<p>gatsby-node.js no permite la importación de ES6</p>

Creado en 2 sept. 2018  ·  39Comentarios  ·  Fuente: gatsbyjs/gatsby

Descripción

gatsby-node.js no permite ES6 javascript.

pasos para reproducir

gatsby-node.js :

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

Resultado Esperado

gatsby-node.js debe transpilarse y permitir ES6 como gatsby-ssr.js o gatsby-browser.js .

Resultado actual

Error

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

Medio ambiente

  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

Comentario más útil

Utilizo esm para esto y funciona hasta ahora. Esto es lo que hice:

  1. Instalar esm ( npm i esm )
  2. Cree un archivo llamado gatsby-node.esm.js en su carpeta raíz (la misma carpeta que contiene gatsby-node.js )
  3. Mueva todo su código de gatsby-node.js a gatsby-node.esm.js
  4. Reemplace todo el código en gatsby-node.js con lo siguiente:
    javascript require = require('esm')(module) module.exports = require('./gatsby-node.esm.js')
  5. Usa import en gatsby-node.esm.js todo lo que quieras 🎉

@KyleAMathews ¿Hay algo peligroso en hacerlo de esta manera? Porque si es seguro, podría agregarlo a los documentos :)

Todos 39 comentarios

Ese archivo lo ejecuta node.js, por lo que es compatible con cualquier versión del nodo que esté utilizando. El soporte del módulo Es6 en el nodo sigue siendo un wip https://medium.com/@giltayar/native -es-modules-in-nodejs-status-and-future-directions-part-i-ee5ea3001f71

También me encuentro con esto. Necesito usar gatsby-mdx/mdx-renderer , e incluso si lo require , el archivo requerido usa la sintaxis del módulo ES6 y se rompe. ¿Hay alguna manera de cambiar la configuración para que gatsby-node.js pasen por babel? Sería genial poder usar JSX dentro de él también, aunque menos urgente para mí.

¿Cuáles serían los pasos para habilitar el soporte de import / export en gatsby-node.js ? La publicación de Medium vinculada a menciones usando archivos .mjs pero no creo que funcione con Gatsby.

¿Hay alguna forma de usar babel-node lugar de node ?

Utilizo esm para esto y funciona hasta ahora. Esto es lo que hice:

  1. Instalar esm ( npm i esm )
  2. Cree un archivo llamado gatsby-node.esm.js en su carpeta raíz (la misma carpeta que contiene gatsby-node.js )
  3. Mueva todo su código de gatsby-node.js a gatsby-node.esm.js
  4. Reemplace todo el código en gatsby-node.js con lo siguiente:
    javascript require = require('esm')(module) module.exports = require('./gatsby-node.esm.js')
  5. Usa import en gatsby-node.esm.js todo lo que quieras 🎉

@KyleAMathews ¿Hay algo peligroso en hacerlo de esta manera? Porque si es seguro, podría agregarlo a los documentos :)

¡Este patrón definitivamente funciona @nikoladev! Sin embargo, no estoy seguro de a dónde iría en los documentos. ¿Alguna idea @ gatsbyjs / docs?

Así es como lo hice:

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

Parece que funciona lo suficientemente bien, pero me pregunto si no afectará al caché. Creo que se supone que el caché se reinicia cuando modificas gatsby-node.js pero he tenido problemas con eso, aunque no sé si están relacionados.

@KyleAMathews ¿Qué tal la contenido y datos ? Al menos esa es la razón por la que lo usé.

Es un debate diferente, pero ¿alguna posibilidad de usar import podría ser compatible de forma inmediata? Siento que para proyectos más grandes de Gatsby, lo que sucede en gatsby-node.js es casi tan importante como su interfaz real y apesta no poder codificar de una manera moderna con import , async/await , etc. sin hacks adicionales.

@KyleAMathews , ¿hay alguna manera de requerir un archivo ES6 local? Por ejemplo, tengo un archivo src/utils/article.js que se parece a lo siguiente:

// 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}`
)

y mi archivo gatsby-node.js :

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

Y me sale el error:

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

¿Algunas ideas? Utilizo la función para crear la URL de nuestros artículos / publicaciones y me gustaría importarla como lo hago en mis componentes de React. ¡Gracias!

Pude resolver mi problema usando ES5 en mi archivo src/utils/article.js , así:

// 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

y luego gatsby-node.js , así:

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

También puedo importar createArticleUrl como es normal en archivos ES6, import { createArticleUrl } from '../utils/article' .

Utilizo esm para esto y funciona hasta ahora. Esto es lo que hice:

  1. Instalar esm ( npm i esm )
  2. Cree un archivo llamado gatsby-node.esm.js en su carpeta raíz (la misma carpeta que contiene gatsby-node.js )
  3. Mueva todo su código de gatsby-node.js a gatsby-node.esm.js
  4. Reemplace todo el código en gatsby-node.js con lo siguiente:
    js require = require('esm')(module) module.exports = require('./gatsby-node.esm.js')
  5. Usa import en gatsby-node.js todo lo que quieras 🎉

@KyleAMathews ¿Hay algo peligroso en hacerlo de esta manera? Porque si es seguro, podría agregarlo a los documentos :)

¿Es el quinto "Use import en gatsby-node.esm.js todo lo que quiera"?

@WeZZard ¡ Tienes toda la razón! Lo arreglaré en mi publicación.

Otra forma en que encontré que esto funcionaba fue actualizando su package.json con lo siguiente:

  "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\""
  },

No es necesario crear nuevos archivos

@reaktivo, sus scripts funcionan localmente, pero no pude hacer que funcionara con netlify. ¿Puede implementar su sitio para netlify con npx ?

@rotexhawk Solo presionó un ejemplo y funcionó bien:

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

Asegúrese de que está ejecutando npm install --save-dev esm antes y que su configuración de compilación ejecute npm run build lugar de gatsby build

Mira este compromiso: https://github.com/reaktivo/gatsby-esm/commit/cf620259ac8b118dea38b99409963cb26bf1b240

Gracias, he instalado esm. el problema es que netlify no tiene acceso a npx , dice que el comando falló. Especifiqué la versión de mi nodo, pero eso no ayudó.

@rotexhawk Eso es realmente extraño, considerando que el proyecto que te envié fue implementado en Netlify ... de todos modos, si necesitas evitar npx , lo siguiente podría funcionar:

  "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\""
  },

@reaktivo servirá. Gracias por toda la ayuda.

Consideraría seriamente agregar ese enfoque esm a la documentación, ya que Gatsby indica que los módulos es6 deberían funcionar dentro del archivo gatsby-node.js. Este mensaje de error se imprime cuando se mezclan módulos:

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.

Indica claramente que PUEDE usar módulos es6.

esm no parece funcionar cuando se utilizan espacios de trabajo de hilo. Dice que no puede encontrar el módulo del espacio de trabajo.

En realidad, parece que solo funciona para la importación de primer nivel en gatsby-node.ems.js , no para nada que el componente importado también importe.

Por ejemplo,

./gatsby-node.ems.js

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

./foo

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

Lanza un error:

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

Dado que los módulos de nodo casi están allí, quería usar el nodo con --experimental-modules lugar de esm .

Cambié scripts.start a "node --experimental-modules ./node_modules/.bin/gatsby develop" , renombré gatsby-node.js a gatsby-node.mjs , pero obtengo

Error en "~ / website / gatsby-node.mjs": debe usar la importación para cargar el módulo ES: ~ / website / gatsby-node.mjs

Error: [ERR_REQUIRE_ESM]: debe usar la importación para cargar el módulo ES: ~ / website / gatsby-node.mjs

Tenga en cuenta que no lo admitimos oficialmente y que las soluciones alternativas mencionadas aquí solo pueden llegar hasta cierto punto. Quizás algunos de nuestros paquetes aún no sean compatibles con esta función de nodo experimental o simplemente no funcionará. Podemos volver a visitar este tema cuando las cosas estén estables.

Ahora que los módulos ES ya no son experimentales , ¿debería reabrirse este problema?

Todavía son experimentales y no están terminados. Solo se ha quitado la bandera

Sin embargo, la implementación sigue siendo experimental y está sujeta a cambios.

Me sumergí profundamente en esto y, en mi opinión, todavía no vale la pena el dolor. Espere a que se implementen los cargadores o use el paquete esm .

¿Alguien ha encontrado una solución usando babel? Sería genial si pudiera colocar mi configuración de babel en un proyecto de gatsby y hacer que todo funcione.

Usar gatsby, pero luego tener que volver a module.exports realmente se siente como un enorme paso atrás.

Modern web tech without the headache -> no tanto :(

npm i esm

y luego modifique sus comandos para que se vean así:

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

@wesbos @reaktivo, ¿puedes usar esa solución todavía con el último gatsby (2.22.17 en mi caso)?

Lo tuve funcionando sin ningún problema al usar esa solución, pero actualicé gatsby hoy y comencé a recibir los errores de importación nuevamente:

''

npx --node-arg '-r esm' desarrollo de gatsby

ERROR # 10123 CONFIG

Encontramos un error al intentar cargar el archivo gatsby-config de su sitio. Corrija el error y vuelva a intentarlo.

Error: /project/gatsby-config.js:1
(función (exporta, requiere, módulo, __filename, __dirname) {import urlJoin from "url-join";
^^^^^^
SyntaxError: No se puede usar la declaración de importación fuera de un módulo

Como alternativa, es posible que desee utilizar TypeScript para archivos gatsby-* .

mi truco de esm anterior simplemente dejó de funcionar. Incluso revirtí gatsby y la versión de nodo y persiste.

Detalla aquí si alguien tiene el mismo problema: https://github.com/reaktivo/gatsby-esm/issues/1

@caycecollins , ¿encontraste una solución?

@wesbos Terminé volviendo a es5 require por ahora :(

EDITAR: Acabo de notar su última solución aquí https://github.com/gatsbyjs/gatsby/issues/24925 ... ¡Lo intentaré!

Solo un aviso de que luché con esto durante una hora y finalmente descubrí que no importaba lo que pusiera en mi package.json para compilar, la configuración de la interfaz de usuario de Netlify estaba teniendo prioridad. No fue hasta que agregué un netlify.toml que esto se hizo evidente. Moraleja de la historia, edite la configuración de compilación de la interfaz de usuario de Netlify, o bórrelos y tírelos a la configuración. Prefiero lo último. 😄

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

Vale la pena señalar que sí, esto funcionó para mí:

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

Vaya, entiendo que el cambio es difícil, pero los módulos ES son Javascript ahora, por lo que es realmente decepcionante ver (por cualquier razón totalmente válida) que los mantenedores luchen contra el soporte de Javascript ... especialmente cuando JDalton y su paquete esm hacen ¡es tan fácil!

PD: Algunos detalles relevantes que quizás no conozcas ...

  • Esta es una solución de dos líneas. A menos que Gatsby tenga múltiples "puntos de entrada", todo el RP para arreglar esto será de tres líneas: la entrada package.json para el paquete esm , y las líneas:
require = require("esm")(module/*, options*/)
module.exports = require("./main.js")
  • Este módulo ya se usa

  • Fue escrito por el creador de Lodash, por lo que este no es el primer proyecto de NPM de un ingeniero junior: es una biblioteca seria escrita por un profesional experimentado.

  • Es completamente compatible con versiones anteriores: a menos que alguien use import o export en su código de módulo que no es de ES (y estoy bastante seguro de que esas han sido palabras clave prohibidas por JS desde el principio de los tiempos) todas las existentes el código seguirá funcionando igual

  • si hubo algún tipo de problema de rendimiento, es trivialmente fácil "guardar" esta función con un argumento de línea de comando ( knex optó por seguir esta ruta, por ejemplo)

Entonces, es "obtener características modernas del lenguaje Javascript con tres líneas de código" o ... ¿luchar por eso? beneficio.

Si hay interés, estaría más que feliz de enviar un PR :)

¿Alguien puede proporcionar una solución final y bloquear este hilo?

Odio hacer este baile de hojear todos los comentarios en temas realmente importantes pero aparentemente cerrados donde la conversación todavía está ocurriendo y tratar de examinar todos los comentarios para ver cuál tiene más aprobación y es probable que sea la mejor solución 😔

Como he dicho, la parte difícil no es hacer el esm trabajo del módulo: está diseñado para hacer que las cosas extremadamente simple. Yo mismo enviaría un PR si supiera algo sobre la arquitectura de Gatsby (y nuevamente, para ver otra biblioteca importante usarlo, solo mire Knex ).

La parte difícil es simplemente conseguir que un mantenedor con ese conocimiento se preocupe :(

Uno pensaría que incluso si cada mantenedor tuviera un odio personal por la sintaxis del módulo JS moderno, al menos podrían apreciar el deseo de sus usuarios por él ... pero la negativa a reabrir este problema, y ​​mucho menos a solucionarlo ( nuevamente, posiblemente con solo dos líneas de código) sugiere lo contrario. Dado lo bueno que ha sido este equipo con otros problemas, honestamente me confunde.

Como dije, la parte difícil es _no_ hacer que el módulo esm funcione: está diseñado para hacer las cosas _extremadamente_ simples. Yo mismo enviaría un PR si supiera algo sobre la arquitectura de Gatsby (y nuevamente, para ver otra biblioteca importante usarlo, solo mire Knex ).

La parte difícil es simplemente conseguir que un mantenedor con ese conocimiento se preocupe :(

Uno pensaría que incluso si cada mantenedor tuviera un _ odiado_ personal por la sintaxis del módulo JS moderno, al menos podrían apreciar el deseo de sus usuarios por él ... pero la negativa a reabrir este problema, y ​​mucho menos a solucionarlo ( nuevamente, posiblemente con solo dos líneas de código) sugiere lo contrario. Dado lo bueno que ha sido este equipo con otros problemas, honestamente me confunde.

¿Alguna palabra de los mantenedores sobre este tema, por favor?

¿Fue útil esta página
0 / 5 - 0 calificaciones

Temas relacionados

timbrandin picture timbrandin  ·  3Comentarios

benstr picture benstr  ·  3Comentarios

kalinchernev picture kalinchernev  ·  3Comentarios

Oppenheimer1 picture Oppenheimer1  ·  3Comentarios

brandonmp picture brandonmp  ·  3Comentarios