<p>gatsby-node.js n'autorise pas l'importation ES6</p>

Créé le 2 sept. 2018  ·  39Commentaires  ·  Source: gatsbyjs/gatsby

La description

gatsby-node.js n'autorise pas le javascript ES6.

Étapes à reproduire

gatsby-node.js :

import myOnCreatePage from './gatsby/node/onCreatePage';
export const onCreatePage = myOnCreatePage;

Résultat attendu

gatsby-node.js doit être transpilé et autoriser ES6 comme gatsby-ssr.js ou gatsby-browser.js .

Résultat actuel

Erreur

Error: <root>/gatsby-node.js:1
SyntaxError: Unexpected token import

Environnement

  System:
    OS: macOS High Sierra 10.13.6
    CPU: x64 Intel(R) Core(TM) i7-6567U CPU @ 3.30GHz
    Shell: 3.2.57 - /bin/bash
  Binaries:
    Node: 8.10.0 - ~/.nvm/versions/node/v8.10.0/bin/node
    Yarn: 1.9.4 - /usr/local/bin/yarn
    npm: 6.4.1 - ~/.nvm/versions/node/v8.10.0/bin/npm
  Browsers:
    Chrome: 68.0.3440.106
    Firefox: 61.0.2
    Safari: 11.1.2
  npmPackages:
    gatsby: next => 2.0.0-rc.5 
    gatsby-source-filesystem: next => 2.0.1-rc.1 
  npmGlobalPackages:
    gatsby-cli: 1.1.58

Commentaire le plus utile

J'utilise esm pour cela et cela fonctionne jusqu'à présent. Voici ce que j'ai fait :

  1. Installer esm ( npm i esm )
  2. Créez un fichier appelé gatsby-node.esm.js dans votre dossier racine (le même dossier qui contient gatsby-node.js )
  3. Déplacez tout votre code de gatsby-node.js à gatsby-node.esm.js
  4. Remplacez tout le code de gatsby-node.js par ce qui suit :
    javascript require = require('esm')(module) module.exports = require('./gatsby-node.esm.js')
  5. Utilisez import dans gatsby-node.esm.js tout ce que vous voulez 🎉

@KyleAMathews Y a-t-il quelque chose de dangereux à procéder ainsi ? Parce que si c'est sûr, je pourrais l'ajouter à la doc :)

Tous les 39 commentaires

Ce fichier est exécuté par node.js, il prend donc en charge quelle que soit la version du nœud que vous utilisez. La prise en charge du module Es6 dans le nœud est toujours un wip https://medium.com/@giltayar/native -es-modules-in-nodejs-status-and-future-directions-part-i-ee5ea3001f71

Je suis aussi en train de tomber dessus. J'ai besoin d'utiliser gatsby-mdx/mdx-renderer , et même si je le require , le fichier requis lui-même utilise la syntaxe et les pauses du module ES6. Existe-t-il un moyen de modifier la configuration pour que gatsby-node.js passent par babel ? Ce serait cool de pouvoir également utiliser JSX à l'intérieur, bien que moins urgent pour moi.

Quelles seraient les étapes pour activer le support import / export dans gatsby-node.js ? Le message Medium lié aux mentions utilisant des fichiers .mjs mais je ne pense pas que cela fonctionnera avec Gatsby ?

Existe-t-il un moyen d'utiliser babel-node au lieu de node ?

J'utilise esm pour cela et cela fonctionne jusqu'à présent. Voici ce que j'ai fait :

  1. Installer esm ( npm i esm )
  2. Créez un fichier appelé gatsby-node.esm.js dans votre dossier racine (le même dossier qui contient gatsby-node.js )
  3. Déplacez tout votre code de gatsby-node.js à gatsby-node.esm.js
  4. Remplacez tout le code de gatsby-node.js par ce qui suit :
    javascript require = require('esm')(module) module.exports = require('./gatsby-node.esm.js')
  5. Utilisez import dans gatsby-node.esm.js tout ce que vous voulez 🎉

@KyleAMathews Y a-t-il quelque chose de dangereux à procéder ainsi ? Parce que si c'est sûr, je pourrais l'ajouter à la doc :)

Ce modèle fonctionne définitivement @nikoladev ! Je ne sais pas où cela irait dans la doc. Des idées @gatsbyjs/docs ?

Voici comment j'ai procédé :

require('babel-register')({
  presets: [ 'env' ]
})
require('babel-polyfill')
module.exports = require(`./gatsby-node.mjs`)

Cela semble fonctionner assez bien mais je me demande si cela ne risque pas de gâcher le cache? Je pense que le cache est censé se réinitialiser lorsque vous modifiez gatsby-node.js mais j'ai rencontré des problèmes avec cela, bien que je ne sache pas s'ils sont liés.

@KyleAMathews Que diriez-vous de sous Sourcing Content and Data ? C'est du moins la raison pour laquelle je l'ai utilisé.

C'est un peu un débat différent, mais toute chance d'utiliser import pourrait-elle être prise en charge par défaut ? J'ai l'impression que pour les grands projets Gatsby, ce qui se passe dans gatsby-node.js est presque aussi important que votre front-end actuel et c'est nul de ne pas pouvoir coder de manière moderne avec import , async/await , etc. sans hacks supplémentaires.

@KyleAMathews , existe-t-il un moyen d'exiger un fichier ES6 local? Par exemple, j'ai un fichier src/utils/article.js qui ressemble à ce qui suit :

// src/utils/article.js
import { format } from 'date-fns'

export const createArticleUrl = (a) => (
  `/${format(a.publishDate, 'YYYY')}` +
  `/${format(a.publishDate, 'MM')}` +
  `/${format(a.publishDate, 'DD')}` +
  `/${a.category.urlSlug}` +
  `/${a.urlSlug}`
)

et le fichier my gatsby-node.js :

// gatsby-node.js
...
const { createArticleUrl } = require(`./src/utils/article`)
...

Et j'obtiens l'erreur :

  Error: .../src/utils/article.js:1
  (function (exports, require, module, __filename, __dirname) { import { format } from 'date-fns'
                                                                ^^^^^^
  SyntaxError: Unexpected token import

Des idées? J'utilise la fonction pour créer l'url de nos articles/posts et j'aimerais l'importer comme je le fais dans mes composants React. Merci!

J'ai pu résoudre mon problème en utilisant ES5 dans mon fichier src/utils/article.js , comme ceci :

// src/utils/article.js
const { format } = require('date-fns')

var createArticleUrl = function (a) {
  return (
    `/${format(a.publishDate, 'YYYY')}` +
    `/${format(a.publishDate, 'MM')}` +
    `/${format(a.publishDate, 'DD')}` +
    `/${a.category.urlSlug}` +
    `/${a.urlSlug}`
  )
}

module.exports.createArticleUrl = createArticleUrl

puis gatsby-node.js , comme ceci :

// gatsby-node.js
...
const { createArticleUrl } = require(`./src/utils/article`)
...

Je peux aussi importer createArticleUrl comme d'habitude dans les fichiers ES6, import { createArticleUrl } from '../utils/article' .

J'utilise esm pour cela et cela fonctionne jusqu'à présent. Voici ce que j'ai fait :

  1. Installer esm ( npm i esm )
  2. Créez un fichier appelé gatsby-node.esm.js dans votre dossier racine (le même dossier qui contient gatsby-node.js )
  3. Déplacez tout votre code de gatsby-node.js à gatsby-node.esm.js
  4. Remplacez tout le code de gatsby-node.js par ce qui suit :
    js require = require('esm')(module) module.exports = require('./gatsby-node.esm.js')
  5. Utilisez import dans gatsby-node.js tout ce que vous voulez 🎉

@KyleAMathews Y a-t-il quelque chose de dangereux à procéder ainsi ? Parce que si c'est sûr, je pourrais l'ajouter à la doc :)

Le 5ème "Utilisez import dans gatsby-node.esm.js tout ce que vous voulez" ?

@WeZZard Vous avez tout à fait raison ! Je vais le corriger dans mon message.

Une autre façon dont j'ai trouvé que cela fonctionnait était de mettre à jour votre package.json avec ce qui suit :

  "scripts": {
    "build": "npx --node-arg '-r esm' gatsby build",
    "develop": "npx --node-arg '-r esm' gatsby develop",
    "start": "npx --node-arg '-r esm' npm run develop",
    "serve": "npx --node-arg '-r esm' gatsby serve",
    "test": "echo \"Write tests! -> https://gatsby.app/unit-testing\""
  },

Pas besoin de créer de nouveaux fichiers

@reaktivo vos scripts fonctionnent localement mais je n'ai pas pu le faire fonctionner avec netlify. Êtes-vous capable de déployer votre site pour netlify avec npx ?

@rotexhawk Je

https://github.com/reaktivo/gatsby-esm/
https://gatsby-esm-example.netlify.com/

Assurez-vous que vous exécutez npm install --save-dev esm auparavant et que votre configuration de build exécute npm run build au lieu de gatsby build

Découvrez ce commit : https://github.com/reaktivo/gatsby-esm/commit/cf620259ac8b118dea38b99409963cb26bf1b240

Merci, j'ai installé esm. le problème est que netlify n'a pas accès à npx , dit la commande a échoué. J'ai spécifié ma version de nœud mais cela n'a pas aidé.

@rotexhawk C'est vraiment bizarre, étant donné que le projet que je vous ai envoyé a été déployé sur Netlify... de toute façon, si vous devez éviter npx , ce qui suit pourrait fonctionner :

  "scripts": {
    "build": "node -r esm ./node_modules/bin/gatsby build",
    "develop": "node -r esm ./node_modules/bin/gatsby develop",
    "start": "npm run develop",
    "serve": "node -r esm ./node_modules/bin/gatsby serve",
    "test": "echo \"Write tests! -> https://gatsby.app/unit-testing\""
  },

@rotexhawk Vous avez contacté l'équipe Netlify, vous devrez peut-être également spécifier la NPM_VERSION, voir https://www.netlify.com/docs/build-settings/#node -npm-and-yarn

@reaktivo fera l'affaire. Merci pour votre aide.

J'envisagerais fortement d'ajouter cette approche esm à la documentation, car Gatsby indique que les modules es6 devraient fonctionner dans le fichier gatsby-node.js. Ce message d'erreur s'affiche, lorsque vous mixez des modules :

error This plugin file is using both CommonJS and ES6 module systems together which we don't support. You'll need to edit the file to use just one or the other.

Cela indique clairement que vous POUVEZ utiliser les modules es6.

esm ne semble pas fonctionner lors de l'utilisation d'espaces de travail de fil. Il dit qu'il ne peut pas trouver le module d'espace de travail.

En fait, il semble que cela ne fonctionne que pour l'importation de premier niveau dans gatsby-node.ems.js , pas pour tout ce que le composant importé importe également.

Par exemple,

./gatsby-node.ems.js

import foo from "./foo";
const fooText = foo + " more text";

./toto

import bar from "bar";
const foo = bar("whatever");
export default foo;

Lève une erreur :

Error in "C:\...\gatsby-node.js": Cannot find module 'bar'

Comme les modules Node sont presque là, je voulais utiliser node avec --experimental-modules au lieu de esm .

J'ai changé scripts.start en "node --experimental-modules ./node_modules/.bin/gatsby develop" , renommé gatsby-node.js en gatsby-node.mjs , mais j'obtiens

Erreur dans "~/website/gatsby-node.mjs" : Doit utiliser l'importation pour charger le module ES : ~/website/gatsby-node.mjs

Erreur : [ERR_REQUIRE_ESM] : Doit utiliser l'importation pour charger le module ES : ~/website/gatsby-node.mjs

Veuillez garder à l'esprit que nous ne le soutenons pas officiellement et que les solutions de contournement mentionnées ici ne peuvent aller que jusqu'à présent. Peut-être que certains de nos packages ne sont pas encore compatibles avec cette fonctionnalité de nœud expérimental ou que cela ne fonctionnera tout simplement pas. Nous pourrons revenir sur ce sujet lorsque les choses seront stables.

Maintenant que les modules ES ne sont plus expérimentaux , ce problème doit-il être rouvert ?

Ils sont encore expérimentaux et pas tout à fait terminés. Juste le drapeau a été enlevé

cependant la mise en œuvre reste expérimentale et sujette à changement

J'ai plongé profondément dans cela, et imo, ça n'en vaut pas encore la peine. Attendez que les chargeurs soient implémentés ou utilisez le package esm .

Quelqu'un a-t-il trouvé une solution avec babel ? Ce serait génial si je pouvais laisser tomber ma configuration babel dans un projet gatsby et que tout fonctionne.

Utiliser gatsby, mais ensuite devoir revenir à module.exports ressemble vraiment à un énorme pas en arrière.

Modern web tech without the headache -> pas tellement :(

npm i esm

puis modifiez vos commandes pour qu'elles ressemblent à ceci :

https://github.com/wesbos/awesome-uses/blob/master/package.json#L39 -L42

@wesbos @reaktivo pouvez-vous toujours utiliser ce correctif avec le dernier gatsby (2.22.17 dans mon cas) ?

Je l'ai fait fonctionner sans aucun problème avec cette solution, mais j'ai mis à jour gatsby aujourd'hui et j'ai recommencé à recevoir les erreurs d'importation :

```

npx --node-arg '-r esm' gatsby develop

ERREUR #10123 CONFIGURATION

Nous avons rencontré une erreur lors de la tentative de chargement de la configuration gatsby de votre site. Veuillez corriger l'erreur et réessayer.

Erreur : /project/gatsby-config.js:1
(fonction (exports, require, module, __filename, __dirname) { import urlJoin depuis "url-join" ;
^^^^^^
SyntaxError : impossible d'utiliser l'instruction import en dehors d'un module```

Comme alternative, vous pouvez utiliser TypeScript pour les fichiers gatsby-* .

mon astuce esm ci-dessus vient de cesser de fonctionner. J'ai même annulé la version gatsby et node et cela persiste.

Détaillé ici si quelqu'un a le même problème : https://github.com/reaktivo/gatsby-esm/issues/1

@caycecollins avez-vous trouvé une solution ?

@wesbos, j'ai fini par revenir à es5 requis pour le moment :(

EDIT : je viens de remarquer votre dernier correctif ici https://github.com/gatsbyjs/gatsby/issues/24925 ... Je vais essayer ça !

Juste un avertissement que j'ai lutté avec cela pendant une heure et j'ai finalement compris que peu importe ce que je mettais dans mon package.json pour la construction, la configuration de l'interface utilisateur Netlify avait la priorité. Ce n'est que lorsque j'ai ajouté un netlify.toml que cela est devenu évident. Morale de l'histoire, modifiez les paramètres de construction de votre interface utilisateur Netlify ou effacez-les et ajoutez-les à la configuration. Je préfère ce dernier. ??

[build]
  command = "npm run build"
  publish = "public"

Il convient de noter que oui, cela a fonctionné pour moi:

"build": "NODE_OPTIONS='-r esm' gatsby build",

Wow, je comprends que le changement est difficile, mais les modules ES sont maintenant Javascript, donc c'est vraiment décevant de voir (pour quelque raison que ce soit) les responsables se battre _contre le support de Javascript_ ... surtout quand JDalton et son paquet esm font c'est si facile !

PS Quelques détails pertinents que vous ignorez peut-être...

  • Il s'agit d'un correctif en deux lignes. À moins que Gatsby n'ait plusieurs "points d'entrée", le PR entier pour résoudre ce problème sera sur trois lignes : l'entrée package.json pour le package esm et les lignes :
require = require("esm")(module/*, options*/)
module.exports = require("./main.js")
  • Ce module est déjà largement utilisé dans les grandes bibliothèques comme Knex. Il y a littéralement 135... _mille_ bibliothèques qui en dépendent déjà !

  • Il a été écrit par le créateur de Lodash, ce n'est donc pas le premier projet NPM d'un ingénieur junior : c'est une bibliothèque sérieuse écrite par un professionnel chevronné

  • C'est complètement rétrocompatible : à moins que quelqu'un n'utilise import ou export dans son code de module non-ES (et je suis presque sûr que ce sont des mots-clés interdits par JS depuis la nuit des temps) tous existants le code continuera à fonctionner de la même manière

  • s'il y avait un quelconque problème de performances, il est trivialement facile de "garder" cette fonctionnalité avec un argument de ligne de commande ( knex choisi d'emprunter cette voie, par exemple)

C'est donc "gagner des fonctionnalités du langage Javascript moderne avec trois lignes de code" ou ... se battre pour ? bénéficier à.

S'il y a un intérêt, je serais plus qu'heureux de soumettre un PR :)

Quelqu'un peut-il fournir une solution finale et verrouiller ce fil?

Je déteste faire cette danse d'écrémer tous les commentaires dans des problèmes vraiment importants mais apparemment fermés où la conversation est toujours en cours et essayer de passer au crible tous les commentaires pour voir lequel a le plus d'approbations et est probablement la meilleure solution 😔

Comme je l'ai dit, le plus dur n'est pas de faire fonctionner le module esm : il est conçu pour rendre les choses extrêmement simples. Je soumettrais moi-même un PR si je savais quelque chose sur l'architecture de Gatsby (et encore une fois, pour voir une autre bibliothèque majeure l'utiliser, il suffit de regarder Knex ).

La partie difficile est juste d'avoir un mainteneur avec cette connaissance pour s'en soucier :(

On pourrait penser que même si chaque mainteneur avait une détestation personnelle pour la syntaxe du module JS moderne, ils pourraient toujours au moins apprécier le désir de leurs utilisateurs pour cela ... mais le refus de même rouvrir ce problème, sans parler de le résoudre ( encore une fois, peut-être avec seulement deux lignes de code) suggère le contraire. Étant donné à quel point cette équipe a été formidable avec d'autres problèmes, c'est honnêtement déroutant pour moi.

Comme je l'ai dit, le plus dur n'est _pas_ de faire fonctionner le module esm : il est conçu pour rendre les choses _extrêmement_ simples. Je soumettrais moi-même un PR si je savais quelque chose sur l'architecture de Gatsby (et encore une fois, pour voir une autre bibliothèque majeure l'utiliser, il suffit de regarder Knex ).

La partie difficile est juste d'avoir un mainteneur avec cette connaissance pour s'en soucier :(

On pourrait penser que même si chaque responsable avait une syntaxe personnelle _détestée_ pour le module JS moderne, ils pourraient toujours au moins apprécier le désir de leurs utilisateurs pour cela ... mais le refus de même rouvrir ce problème, sans parler de le résoudre ( encore une fois, peut-être avec seulement deux lignes de code) suggère le contraire. Étant donné à quel point cette équipe a été formidable avec d'autres problèmes, c'est honnêtement déroutant pour moi.

Un mot des mainteneurs à ce sujet, s'il vous plaît ?

Cette page vous a été utile?
0 / 5 - 0 notes

Questions connexes

rossPatton picture rossPatton  ·  3Commentaires

3CordGuy picture 3CordGuy  ·  3Commentaires

signalwerk picture signalwerk  ·  3Commentaires

totsteps picture totsteps  ·  3Commentaires

ghost picture ghost  ·  3Commentaires