gatsby-node.js
não permite javascript ES6.
gatsby-node.js
:
import myOnCreatePage from './gatsby/node/onCreatePage';
export const onCreatePage = myOnCreatePage;
gatsby-node.js
deve ser transpilado e permitir ES6 como gatsby-ssr.js
ou gatsby-browser.js
.
Erro
Error: <root>/gatsby-node.js:1
SyntaxError: Unexpected token import
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
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:
esm
( npm i esm
)gatsby-node.esm.js
em sua pasta raiz (a mesma pasta que contém gatsby-node.js
)gatsby-node.js
para gatsby-node.esm.js
gatsby-node.js
pelo seguinte:javascript
require = require('esm')(module)
module.exports = require('./gatsby-node.esm.js')
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:
- Instale
esm
(npm i esm
)- Crie um arquivo chamado
gatsby-node.esm.js
em sua pasta raiz (a mesma pasta que contémgatsby-node.js
)- Mova todo o seu código de
gatsby-node.js
paragatsby-node.esm.js
- Substitua todo o código em
gatsby-node.js
pelo seguinte:
js require = require('esm')(module) module.exports = require('./gatsby-node.esm.js')
- Use
import
emgatsby-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 ...
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?
Comentários muito úteis
Eu uso ESM para isso e funciona até agora. Aqui está o que eu fiz:
esm
(npm i esm
)gatsby-node.esm.js
em sua pasta raiz (a mesma pasta que contémgatsby-node.js
)gatsby-node.js
paragatsby-node.esm.js
gatsby-node.js
pelo seguinte:javascript require = require('esm')(module) module.exports = require('./gatsby-node.esm.js')
import
emgatsby-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 :)