<p>gatsby-node.js 不允许 ES6 导入</p>

创建于 2018-09-02  ·  39评论  ·  资料来源: gatsbyjs/gatsby

描述

gatsby-node.js不允许 ES6 javascript。

重现步骤

gatsby-node.js

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

预期结果

gatsby-node.js应该被转译并允许 ES6 像gatsby-ssr.jsgatsby-browser.js

实际结果

错误

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

最有用的评论

我为此使用了esm ,到目前为止它有效。 这是我所做的:

  1. 安装esm ( npm i esm )
  2. 在您的根文件夹(包含gatsby-node.js的同一文件夹)中创建一个名为gatsby-node.esm.js文件
  3. 将所有代码从gatsby-node.jsgatsby-node.esm.js
  4. gatsby-node.js所有代码替换为以下内容:
    javascript require = require('esm')(module) module.exports = require('./gatsby-node.esm.js')
  5. gatsby-node.esm.js随意使用import 🎉

@KyleAMathews这样做有什么危险吗? 因为如果安全的话,我可以将它添加到文档中 :)

所有39条评论

该文件由 node.js 运行,因此它支持您使用的 node 版本支持。 节点中的 Es6 模块支持仍然是一个未知数https://medium.com/@giltayar/native -es-modules-in-nodejs-status-and-future-directions-part-i-ee5ea3001f71

我也遇到了这个。 我需要使用gatsby-mdx/mdx-renderer ,即使我使用require它,所需的文件本身也使用 ES6 模块语法并中断。 有没有办法改变配置让gatsby-node.js通过 babel? 能够在其中使用 JSX 也很酷,尽管对我来说不那么紧迫。

gatsby-node.js启用import / export支持的步骤是什么? 使用.mjs文件链接到提及的媒体帖子,但我认为这不适用于 Gatsby?

有没有办法使用babel-node而不是node

我为此使用了esm ,到目前为止它有效。 这是我所做的:

  1. 安装esm ( npm i esm )
  2. 在您的根文件夹(包含gatsby-node.js的同一文件夹)中创建一个名为gatsby-node.esm.js文件
  3. 将所有代码从gatsby-node.jsgatsby-node.esm.js
  4. gatsby-node.js所有代码替换为以下内容:
    javascript require = require('esm')(module) module.exports = require('./gatsby-node.esm.js')
  5. gatsby-node.esm.js随意使用import 🎉

@KyleAMathews这样做有什么危险吗? 因为如果安全的话,我可以将它添加到文档中 :)

这种模式绝对有效@nikoladev! 不确定它会在文档中的位置。 任何想法@gatsbyjs/docs?

这是我如何做到的:

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

它似乎工作得很好,但我想知道它是否会干扰缓存? 我认为缓存应该在您修改gatsby-node.js时重置,但我一直遇到问题,尽管我不知道它们是否相关。

@KyleAMathews采购内容和数据如何? 至少这就是我使用它的原因。

这是一种不同的辩论,但任何使用import都可以开箱即用吗? 我觉得对于更大的 Gatsby 项目,在gatsby-node.js发生的事情几乎与您的实际前端一样重要,并且无法使用importasync/await以现代方式进行编码很糟糕

@KyleAMathews ,有没有办法需要本地 ES6 文件? 例如,我有一个src/utils/article.js文件,如下所示:

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

和我的gatsby-node.js文件:

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

我得到错误:

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

有任何想法吗? 我使用该函数为我们的文章/帖子创建 url,并希望像在我的 React 组件中一样导入它。 谢谢!

我能够通过在src/utils/article.js文件中使用 ES5 来解决我的问题,如下所示:

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

然后gatsby-node.js ,像这样:

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

我也可以像在 ES6 文件中一样导入createArticleUrlimport { createArticleUrl } from '../utils/article'

我为此使用了esm ,到目前为止它有效。 这是我所做的:

  1. 安装esm ( npm i esm )
  2. 在您的根文件夹(包含gatsby-node.js的同一文件夹)中创建一个名为gatsby-node.esm.js文件
  3. 将所有代码从gatsby-node.jsgatsby-node.esm.js
  4. gatsby-node.js所有代码替换为以下内容:
    js require = require('esm')(module) module.exports = require('./gatsby-node.esm.js')
  5. gatsby-node.js随意使用import 🎉

@KyleAMathews这样做有什么危险吗? 因为如果安全的话,我可以将它添加到文档中 :)

第 5 个“在gatsby-node.esm.js使用import是你想要的吗”?

@WeZZard你说得对! 我会在我的帖子中修复它。

我发现此方法可行的另一种方法是使用以下内容更新您的 package.json:

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

无需创建新文件

@reaktivo你的脚本在本地工作,但我无法让它与 netlify 一起工作。 你能用npx部署你的网站到 netlify 吗?

@rotexhawk刚刚推出了一个例子,它运行良好:

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

确保您之前运行npm install --save-dev esm并且您的构建配置运行npm run build而不是gatsby build

查看此提交: https :

谢谢,我已经安装了esm。 问题是 netlify 无法访问npx ,说命令失败。 我指定了我的节点版本,但这没有帮助。

@rotexhawk这真的很奇怪,考虑到我发送给您的项目已部署到 Netlify ......无论如何,如果您需要避免npx ,以下可能有效:

  "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与 Netlify 团队取得联系,您可能还需要指定 NPM_VERSION,请参阅https://www.netlify.com/docs/build-settings/#node -npm-and-yarn

@reaktivo会做。 感谢所有的帮助。

我强烈考虑将 esm 方法添加到文档中,因为 Gatsby 表明 es6 模块应该在 gatsby-node.js 文件中工作。 混合模块时会打印此错误消息:

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.

它清楚地表明,您可以使用 es6 模块。

esm在使用 yarn 工作区时似乎不起作用。 它说它找不到工作区模块。

实际上,它似乎只适用于gatsby-node.ems.js的第一级导入,不适用于导入组件也导入的任何内容。

例如,

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

抛出错误:

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

由于节点模块几乎就在那里,我想使用带有--experimental-modules而不是esm节点。

我将 scripts.start 更改为"node --experimental-modules ./node_modules/.bin/gatsby develop" ,将gatsby-node.js重命名gatsby-node.mjs ,但我得到了

“~/website/gatsby-node.mjs”中的错误:必须使用导入来加载 ES 模块:~/website/gatsby-node.mjs

错误:[ERR_REQUIRE_ESM]:必须使用导入来加载 ES 模块:~/website/gatsby-node.mjs

请记住,我们不正式支持它,这里提到的解决方法只能到此为止。 也许我们的一些软件包尚不与此实验性节点功能兼容,或者它无法正常工作。 当事情稳定时,我们可以重新讨论这个话题。

现在ES 模块不再是实验性的,这个问题应该重新打开吗?

它们仍处于试验阶段,还没有完全完成。 只是旗帜已被移除

然而,实施仍然是实验性的,可能会发生变化

我深入研究了这一点,我认为这不值得痛苦。 等待加载器实现或使用esm包。

有没有人找到使用 babel 的解决方案? 如果我能在 gatsby 项目中删除我的 babel 配置,并让它一切正常,那就太好了。

使用 gatsby,但又不得不回到module.exports真的感觉像是一个巨大的退步。

Modern web tech without the headache -> 没那么多:(

npm i esm

然后将您的命令修改为如下所示:

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

@wesbos @reaktivo你能在最新的 gatsby(在我的例子中为 2.22.17)使用该修复程序吗?

我已经使用该解决方案在没有任何问题的情况下工作,但今天更新了 gatsby 并再次开始出现导入错误:

``

npx --node-arg '-r esm' gatsby 开发

错误 #10123 配置

我们在尝试加载您网站的 gatsby-config 时遇到错误。 请修复错误并重试。

错误:/project/gatsby-config.js:1
(function (exports, require, module, __filename, __dirname) { import urlJoin from "url-join";
^^^^^^
语法错误:不能在模块外使用 import 语句```

作为替代方案,您可能希望将TypeScript 用于gatsby-*文件

我上面的 esm 技巧刚刚停止工作。 我什至回滚了 gatsby 和 node 版本,它仍然存在。

如果有人有同样的问题,请在此处详细说明: https :

@caycecollins你找到解决办法了吗?

@wesbos我现在最终恢复到 es5 require :(

编辑:我刚刚注意到你在这里的最新修复https://github.com/gatsbyjs/gatsby/issues/24925 ......我会尝试一下!

提醒一下,我为此苦苦挣扎了一个小时,最终发现无论我在 package.json 中放入什么来构建,Netlify UI 配置都处于优先地位。 直到我添加了 netlify.toml,这才变得明显。 故事的寓意,编辑您的 Netlify UI 构建设置,或清除它们并将其扔到配置中。 我更喜欢后者。 😄

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

值得注意的是,是的,这对我有用:

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

哇,我知道改变很难,但是 ES 模块现在是 Javascript,所以看到(无论出于什么完全正当的理由)维护者与 _against 支持 Javascript_ 作斗争真的很令人失望……尤其是当 JDalton 和他的esm包使太容易了!

PS 一些你可能不知道的相关细节......

  • 这是一个两行修复。 除非 Gatsby 有多个“入口点”,否则解决这个问题的整个 PR 将是三行: esm包的package.json条目,以及以下几行:
require = require("esm")(module/*, options*/)
module.exports = require("./main.js")
  • 该模块已广泛用于 Knex 等主要库中。 字面上有 135 ... _数千个库依赖于它!

  • 它是由 Lodash 的创建者编写的,所以这不是某个初级工程师的第一个 NPM 项目:它是一个由经验丰富的专业人士编写的严肃的库

  • 它是完全向后兼容的:除非有人在他们的非 ES 模块代码中使用importexport (而且我很确定这些从一开始就是 JS 禁止的关键字)所有现有的代码将继续以相同的方式工作

  • 如果有任何类型的性能问题,使用命令行参数“保持”此功能非常容易(例如, knex选择走这条路线)

所以它是“用三行代码获得现代 Javascript 语言功能”还是......为它而战? 益处。

如果有兴趣,我很乐意提交 PR :)

有人可以提供最终解决方案并锁定此线程吗?

讨厌在讨论仍在进行的真正重要但看似封闭的问题中浏览所有评论并试图筛选所有评论以查看哪个评论最多并且可能是最佳解决方案的舞蹈 😔

就像我说的,困难的部分不是esm模块工作:它旨在让事情变得非常简单。 如果我对 Gatsby 架构有所了解,我会自己提交 PR(再次,要查看另一个主要库使用它,只需查看 Knex )。

困难的部分只是让拥有这些知识的维护者关心:(

你会认为即使每个维护者都对现代 JS 模块语法有个人仇恨,他们至少仍然可以理解他们的用户对它的渴望......但是拒绝甚至重新打开这个问题,更不用说修复它了(再次,可能只有两行代码)建议否则。 鉴于这个团队在其他问题上的表现如此出色,老实说这让我感到困惑。

就像我说的,困难的部分是_不_使esm模块工作:它旨在使事情_极端_简单。 如果我对 Gatsby 架构有所了解,我会自己提交 PR(再次,要查看另一个主要库使用它,只需查看 Knex )。

困难的部分只是让拥有这些知识的维护者关心:(

你会认为即使每个维护者都对现代 JS 模块语法有个人的_讨厌_,他们至少仍然可以欣赏他们的用户对它的渴望......但是拒绝甚至重新打开这个问题,更不用说修复它了(再次,可能只有两行代码)另有建议。 鉴于这个团队在其他问题上的表现如此出色,老实说这让我感到困惑。

请问维护者有没有关于这个主题的信息?

此页面是否有帮助?
0 / 5 - 0 等级

相关问题

timbrandin picture timbrandin  ·  3评论

dustinhorton picture dustinhorton  ·  3评论

hobochild picture hobochild  ·  3评论

theduke picture theduke  ·  3评论

ghost picture ghost  ·  3评论