<p>gatsby-node.js não permite importação ES6</p>

Criado em 2 set. 2018  ·  39Comentários  ·  Fonte: gatsbyjs/gatsby

Descrição

gatsby-node.js não permite javascript ES6.

Passos para reproduzir

gatsby-node.js :

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

Resultado esperado

gatsby-node.js deve ser transpilado e permitir ES6 como gatsby-ssr.js ou gatsby-browser.js .

Resultado atual

Erro

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

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

Comentários muito úteis

Eu uso ESM para isso e funciona até agora. Aqui está o que eu fiz:

  1. Instale esm ( npm i esm )
  2. Crie um arquivo chamado gatsby-node.esm.js em sua pasta raiz (a mesma pasta que contém gatsby-node.js )
  3. Mova todo o seu código de gatsby-node.js para gatsby-node.esm.js
  4. Substitua todo o código em gatsby-node.js pelo seguinte:
    javascript require = require('esm')(module) module.exports = require('./gatsby-node.esm.js')
  5. Use import em gatsby-node.esm.js tudo que você quiser 🎉

@KyleAMathews Há algo de perigoso em fazer dessa maneira? Porque se for seguro, posso adicioná-lo aos documentos :)

Todos 39 comentários

Esse arquivo é executado por node.js para que seja compatível com qualquer versão de node que você está usando. O suporte do módulo Es6 no nó ainda é um apagamento https://medium.com/@giltayar/native -es-modules-in-nodejs-status-and-future-direction-part-i-ee5ea3001f71

Eu também estou correndo para isso. Eu preciso usar gatsby-mdx/mdx-renderer , e mesmo se eu require it, o próprio arquivo requerido usa a sintaxe do módulo ES6 e quebra. Existe uma maneira de alterar a configuração para que gatsby-node.js passe pelo babel? Seria legal poder usar JSX dentro dele também, embora menos urgente para mim.

Quais seriam as etapas para ativar o suporte de import / export em gatsby-node.js ? A postagem do Medium com link para menções usando .mjs arquivos, mas eu não acho que funcionará com Gatsby?

Existe uma maneira de usar babel-node vez de node ?

Eu uso ESM para isso e funciona até agora. Aqui está o que eu fiz:

  1. Instale esm ( npm i esm )
  2. Crie um arquivo chamado gatsby-node.esm.js em sua pasta raiz (a mesma pasta que contém gatsby-node.js )
  3. Mova todo o seu código de gatsby-node.js para gatsby-node.esm.js
  4. Substitua todo o código em gatsby-node.js pelo seguinte:
    javascript require = require('esm')(module) module.exports = require('./gatsby-node.esm.js')
  5. Use import em gatsby-node.esm.js tudo que você quiser 🎉

@KyleAMathews Há algo de perigoso em fazer dessa maneira? Porque se for seguro, posso adicioná-lo aos documentos :)

Esse padrão definitivamente funciona @nikoladev! Não tenho certeza para onde iria nos documentos, no entanto. Alguma ideia @ gatsbyjs / docs?

Veja como eu fiz:

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

Parece funcionar bem, mas será que não vai mexer no cache? Acho que o cache deve ser redefinido quando você modifica gatsby-node.js mas estou tendo problemas com isso, embora não saiba se eles estão relacionados.

@KyleAMathews Que tal em Fornecimento de Conteúdo e Dados ? Pelo menos essa é a razão pela qual o usei.

É um debate diferente, mas alguma chance de usar import pode ser suportada fora da caixa? Acho que para projetos maiores de Gatsby, o que acontece em gatsby-node.js é quase tão importante quanto seu front-end real e é uma droga não ser capaz de codificar de uma maneira moderna com import , async/await , etc. sem hacks extras.

@KyleAMathews , há uma maneira de exigir um arquivo ES6 local? Por exemplo, eu tenho um arquivo src/utils/article.js que se parece com o seguinte:

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

e o meu arquivo gatsby-node.js :

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

E recebo o erro:

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

Alguma ideia? Eu uso a função para criar a url para nossos artigos / postagens e gostaria de importá-la como faço em meus componentes React. Obrigado!

Consegui resolver meu problema usando ES5 em meu arquivo src/utils/article.js , assim:

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

e então gatsby-node.js , assim:

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

Também posso importar createArticleUrl normalmente em arquivos ES6, import { createArticleUrl } from '../utils/article' .

Eu uso ESM para isso e funciona até agora. Aqui está o que eu fiz:

  1. Instale esm ( npm i esm )
  2. Crie um arquivo chamado gatsby-node.esm.js em sua pasta raiz (a mesma pasta que contém gatsby-node.js )
  3. Mova todo o seu código de gatsby-node.js para gatsby-node.esm.js
  4. Substitua todo o código em gatsby-node.js pelo seguinte:
    js require = require('esm')(module) module.exports = require('./gatsby-node.esm.js')
  5. Use import em gatsby-node.js tudo que você quiser 🎉

@KyleAMathews Há algo de perigoso em fazer dessa maneira? Porque se for seguro, posso adicioná-lo aos documentos :)

O quinto "Use import em gatsby-node.esm.js tudo o que você deseja"?

@WeZZard Você está totalmente certo! Vou consertar no meu post.

Outra maneira que descobri que isso funcionava foi atualizando seu package.json com o seguinte:

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

Não há necessidade de criar novos arquivos

@reaktivo seus scripts funcionam localmente, mas não consegui fazê-los funcionar com o netlify. Você consegue implantar seu site para netlify com npx ?

@rotexhawk Apenas empurrou um exemplo e funcionou bem:

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

Certifique-se de que você esteja executando npm install --save-dev esm antes e que sua configuração de compilação execute npm run build vez de gatsby build

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

Obrigado, instalei o ESM. o problema é que o netlify não tem acesso a npx , diz que o comando falhou. Especifiquei minha versão do nó, mas isso não ajudou.

@rotexhawk Isso é muito estranho, considerando que o projeto que enviei a você foi implantado no Netlify ... de qualquer maneira, se você precisar evitar npx , o seguinte pode 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\""
  },

@rotexhawk Entrou em contato com a equipe do Netlify, talvez você também precise especificar o NPM_VERSION, consulte https://www.netlify.com/docs/build-settings/#node -npm-and-yarn

@reaktivo serve . Obrigado por toda a ajuda.

Eu consideraria fortemente adicionar essa abordagem esm à documentação, uma vez que Gatsby está indicando que os módulos es6 devem funcionar dentro do arquivo gatsby-node.js. Esta mensagem de erro é impressa, quando você mistura os 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.

Isso indica claramente, você PODE usar módulos es6.

esm não parece funcionar ao usar os espaços de trabalho do yarn. Diz que não consegue encontrar o módulo do espaço de trabalho.

Na verdade, parece que só funciona para a importação de primeiro nível em gatsby-node.ems.js , não para qualquer coisa que o componente importado também importe.

Por exemplo,

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

Lança um erro:

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

Como os módulos Node estão quase lá, eu queria usar o node com --experimental-modules vez de esm .

Mudei scripts.start para "node --experimental-modules ./node_modules/.bin/gatsby develop" , renomeei gatsby-node.js para gatsby-node.mjs , mas entendi

Erro em "~ / website / gatsby-node.mjs": deve usar importar para carregar o Módulo ES: ~ / website / gatsby-node.mjs

Erro: [ERR_REQUIRE_ESM]: Deve-se usar a importação para carregar o Módulo ES: ~ / website / gatsby-node.mjs

Lembre-se de que não oferecemos suporte oficial para isso e que as soluções alternativas mencionadas aqui só vão até certo ponto. Talvez alguns de nossos pacotes ainda não sejam compatíveis com este recurso de nó experimental ou simplesmente não funcione. Podemos revisitar este tópico quando as coisas estiverem estáveis.

Agora que os módulos ES não são mais experimentais , esse problema deve ser reaberto?

Eles ainda são experimentais e não terminados. Apenas a bandeira foi removida

no entanto, a implementação permanece experimental e sujeita a alterações

Eu mergulhei fundo nisso, e ainda não vale a pena a dor. Espere que os carregadores sejam implementados ou use o pacote esm .

Alguém encontrou uma solução usando o babel? Seria ótimo se eu pudesse colocar minha configuração de babel em um projeto gatsby e fazer tudo funcionar.

Usar gatsby, mas depois ter que voltar para module.exports realmente parece um grande passo para trás.

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

npm i esm

e, em seguida, modifique seus comandos para ficarem assim:

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

@wesbos @reaktivo você consegue usar essa correção ainda com o gatsby mais recente (2.22.17 no meu caso)?

Eu o fiz funcionar sem problemas ao usar essa solução, mas atualizei o gatsby hoje e comecei a receber os erros de importação novamente:

`` `

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

ERROR # 10123 CONFIG

Encontramos um erro ao tentar carregar o gatsby-config do seu site. Corrija o erro e tente novamente.

Erro: /project/gatsby-config.js:1
(função (exporta, requer, módulo, __filename, __dirname) {import urlJoin de "url-join";
^^^^^^
SyntaxError: Não é possível usar a instrução de importação fora de um módulo```

Como alternativa, você pode usar o TypeScript para gatsby-* arquivos .

meu truque ESM acima simplesmente parou de funcionar. Até reverti o gatsby e a versão do nó e isso persiste.

Detalhe aqui se alguém tiver o mesmo problema: https://github.com/reaktivo/gatsby-esm/issues/1

@caycecollins você encontrou uma solução?

@wesbos Acabei voltando para es5 require por agora :(

EDIT: Acabei de notar sua última correção aqui https://github.com/gatsbyjs/gatsby/issues/24925 ... Vou tentar!

Apenas para avisar que lutei com isso por uma hora e finalmente descobri que não importa o que eu coloquei no meu package.json para construção, a configuração da IU do Netlify estava tendo precedência. Não foi até eu adicionar um netlify.toml que isso se tornou aparente. Moral da história, edite as configurações de construção da interface do usuário do Netlify ou limpe-as e jogue-as na configuração. Eu prefiro o último. 😄

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

É importante notar que sim, isso funcionou para mim:

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

Uau, eu entendo que a mudança é difícil, mas os Módulos ES são Javascript agora, então é realmente decepcionante ver (por quaisquer motivos totalmente válidos) os mantenedores lutando _contra o suporte ao Javascript_ ... especialmente quando JDalton e seu pacote esm fazem é tão fácil!

PS Alguns detalhes relevantes dos quais você pode não estar ciente ...

  • Esta é uma correção de duas linhas. A menos que Gatsby tenha vários "pontos de entrada", todo o PR para consertar isso terá três linhas: a entrada package.json para o pacote esm e as linhas:
require = require("esm")(module/*, options*/)
module.exports = require("./main.js")
  • Este módulo já é amplamente utilizado nas principais bibliotecas como Knex. Existem literalmente 135 ... _milhares_ bibliotecas dependendo disso!

  • Foi escrito pelo criador do Lodash, então este não é o primeiro projeto NPM de um engenheiro júnior: é uma biblioteca séria escrita por um profissional experiente

  • É totalmente compatível com versões anteriores: a menos que alguém use import ou export em seu código de módulo não ES (e tenho certeza que essas são palavras-chave proibidas de JS desde o início dos tempos), todos existentes o código continuará funcionando da mesma forma

  • se houver qualquer tipo de preocupação com o desempenho, é trivialmente fácil "manter" esse recurso com um argumento de linha de comando ( knex optou por seguir esse caminho, por exemplo)

Portanto, é "obter recursos modernos da linguagem Javascript com três linhas de código" ou ... lutar por isso? beneficiar.

Se houver interesse, ficarei mais do que feliz em enviar um PR :)

Alguém pode fornecer uma solução final e bloquear este tópico?

Odeio fazer essa dança de passar os olhos em todos os comentários em questões realmente importantes, mas aparentemente fechadas, onde a conversa ainda está acontecendo e tentar peneirar todos os comentários para ver qual deles tem mais aprovação e provavelmente é a melhor solução 😔

Como eu disse, a parte difícil não é fazer o módulo esm funcionar: ele foi projetado para tornar as coisas extremamente simples. Eu mesmo enviaria um PR se soubesse alguma coisa sobre a arquitetura de Gatsby (e novamente, para ver outra grande biblioteca usá-la, basta olhar para a Knex ).

A parte difícil é apenas conseguir que um mantenedor com esse conhecimento se importe :(

Você pensaria que mesmo que cada mantenedor odiasse a sintaxe do módulo JS moderno, eles ainda poderiam pelo menos apreciar o desejo de seus usuários por isso ... mas a recusa até mesmo de reabrir este problema, quanto mais corrigi-lo ( novamente, possivelmente com apenas duas linhas de código) sugere o contrário. Considerando o quão bom esta equipe tem sido com outras questões, é honestamente confuso para mim.

Como eu disse, a parte difícil _não_ é fazer o módulo esm funcionar: ele foi projetado para tornar as coisas _extremamente_ simples. Eu mesmo enviaria um PR se soubesse alguma coisa sobre a arquitetura de Gatsby (e novamente, para ver outra grande biblioteca usá-la, basta olhar para a Knex ).

A parte difícil é apenas conseguir que um mantenedor com esse conhecimento se importe :(

Você pensaria que, mesmo se cada mantenedor tivesse uma _desejo_ pessoal pela sintaxe do módulo JS moderno, eles ainda poderiam pelo menos apreciar o desejo de seus usuários por isso ... mas a recusa até mesmo de reabrir este problema, quanto mais corrigi-lo ( novamente, possivelmente com apenas duas linhas de código) sugere o contrário. Considerando o quão bom esta equipe tem sido com outras questões, é honestamente confuso para mim.

Alguma palavra dos mantenedores sobre este assunto, por favor?

Esta página foi útil?
0 / 5 - 0 avaliações

Questões relacionadas

Oppenheimer1 picture Oppenheimer1  ·  3Comentários

timbrandin picture timbrandin  ·  3Comentários

kalinchernev picture kalinchernev  ·  3Comentários

rossPatton picture rossPatton  ·  3Comentários

andykais picture andykais  ·  3Comentários