如何在Node.js中解决“ReferenceError: primordials is not defined”错误

888

我通过 'npm install' 安装了Node.js模块,然后在命令提示符中尝试执行gulp sass-watch。之后,我收到了以下反馈。

[18:18:32] Requiring external module babel-register
fs.js:27
const { Math, Object, Reflect } = primordials;
                                  ^

ReferenceError: primordials is not defined

我以前尝试过这个gulp sass-watch命令:

npm -g install gulp-cli

如果在通过 Visual Studio 任务运行程序自动执行 gulp 任务时遇到此问题(特别是在更新 VS 后),请参见此处 - https://dev59.com/DLvpa4cB1Zd3GeqPCPoZ#72709758 - Chris Halcrow
44个回答

927

当我们将依赖于gulp@3.9.1的旧项目更新到Node.js 12+时,我们遇到了相同的问题。

这些修复程序使您能够通过覆盖graceful-fs版本为^4.2.11来使用Node.js 12+与gulp@3.9.1

如果您正在使用pnpm

pnpm支持覆盖某些依赖项版本。要执行此操作,您应在package.json文件中添加一个pnpm部分:

{
  "pnpm": {
    "overrides": {
      "graceful-fs": "^4.2.11"
    }
  }
}

如果您正在使用yarn v1

yarn v1 支持将软件包解析为定义的版本。 您需要向package.json添加一个resolutions部分:

{
  "resolutions": {
    "graceful-fs": "^4.2.11"
  }
}

感谢@jazd提供的解决问题的方法。

如果您正在使用npm

运行此命令以了解您正在使用哪个版本的Node.js:

node -v

它将返回一个版本号 <major>.<minor>.<patch>,例如 18.11.0
如果你的版本是 v16.14.0 或以上,则可以通过在 package.json 文件中添加 一个overrides部分 来覆盖 graceful-fs 版本:
{
  "overrides": {
    "graceful-fs": "^4.2.11"
  }
}

否则,您需要使用 npm-force-resolutions 作为预安装脚本,以能够通过更改您的 package.json 文件来覆盖 graceful-fs 的版本,如下所示:
{
  "scripts": {
    "preinstall": "npx npm-force-resolutions"
  },
  "resolutions": {
    "graceful-fs": "^4.2.11"
  }
}

npm-force-resolutions 会在 install 完成之前更改 package-lock.json 文件以将 graceful-fs 设置为所需版本。

如果您在项目中使用自定义的 .npmrc 文件,并且它包含代理或自定义注册表,则可能需要将 npx npm-force-resolutions 更改为 npx --userconfig .npmrc npm-force-resolutions,因为某些版本的 npx 默认不使用当前文件夹的 .npmrc 文件。

问题起源

这个问题源于 gulp@3.9.1 依赖 graceful-fs@^3.0.0,后者对 Node.js 的 fs 模块进行了 monkeypatch。

这在 Node.js 版本 11.15 之前是可行的(这是一个来自开发分支的版本,不应该用于生产环境)。

graceful-fs@^4.0.0 不再对 Node.js fs 模块进行 monkeypatch,这使它与 Node.js > 11.15 兼容(已测试并适用于版本 12、14、16、18 和 20)。

请注意,这不是永久性的解决方案,但在您没有时间更新到 gulp@^4.0.0 时,它会有所帮助。


2
@Valentin 这对我有用,但它是如何工作的?根据我的阅读,除了可发布之外,npm-shrinkwrap.json 应该与 package-lock.json 表现相同。为什么它们在这里的表现不同呢?为什么需要 npm-shrinkwrap.json 来解决这个问题? - JordRoss
它的作用是覆盖graceful-fs版本到一个新版本(v4+),该版本不再对nodejs fs模块进行猴子补丁(请参阅graceful-fs README)。值得庆幸的是,这已足以使一切正常运行。 - Valentin
npx npm-force-resolutions 现在需要一个有效的 package-lock.json 才能正常工作。为了解决这个问题,可以使用 "preinstall": "npm install --package-lock-only --ignore-scripts && npx npm-force-resolutions"来源)。 - rustyx
3
我无法感谢你们的足够!使用 npm > 8.3.0,将“overrides”键添加到 package.json 中,完美地解决了问题! - tirmey
注意:如果您尝试此操作但无法正常工作,请尝试删除 npm-shrinkwrap.json 文件,然后再次运行 npm install(当然,在删除 node_modules 之后)。 - rinogo
显示剩余3条评论

913

116
我正在使用 Node v12.1.0 和 Gulp gulp@4.0.2,但它无法正常工作。 - Most Wanted
31
我建议使用 Valentin 发布的 npm-shrinkwrap.json 解决方案:https://dev59.com/aVMI5IYBdhLWcg3wj8OF#58394828,即使这是被接受的解决方案。 - Erik Hansen
7
我使用 Node.js v14 和 Gulp v4。但我仍然遇到了这个问题 :( - nZeus
升级Gulp到4版本后,我不得不在gulpfile.js中修复了一些Task问题,但这样做解决了问题。 - iGanja
使用Node包管理器https://www.npmjs.com/package/n,可以轻松切换到所需的任何Node版本。 - Akhil S
显示剩余4条评论

508

一分钟解决方法:

只需按照这些步骤操作即可。我使用的是Windows 10,方法完美解决了问题!

  1. 在与package.json相同的目录中创建一个npm-shrinkwrap.json文件,并将以下内容复制到文件中:

        {
          "dependencies": {
            "graceful-fs": {
                "version": "4.2.2"
             }
          }
        }
    
  2. 运行npm install,不要担心,它会更新npm-shrinkwrap.json 并添加大量的内容。

  3. 运行gulp来启动项目。


7
请注意:这只是一个临时的解决方案,如果您再次运行 npm i,它会再次出现问题。 - Anuga
9
如果你想再次运行npm install,因为shrinkwrap.json文件在修改过后,你需要将其删除。解决方法是在package.jsonscripts节点中添加一行代码:"preinstall": "cp npm-shrinkwrap.gulp.json npm-shrinkwrap.json"。其中,npm-shrinkwrap.gulp.json是所需的文件,会在执行npm install前被复制到npm-shrinkwrap.json中。(在Windows上将cp替换为copy - Adam Wallner
我已经解决了它,我使用的是 npm@14 版本。 - Muxiddin Jumaniyazov

147

使用以下命令并安装Node.js v11.15.0

npm install -g n

sudo n 11.15.0

将解决

ReferenceError: primordials is not defined in node

参考自@Terje Norderhaug @Tom Corelis的答案。


如果仍然无法正常工作,请尝试执行以下命令(在上述命令之后):npm rebuild node-sass。 - kevinius
9
在我的Windows 64机器上运行“npm install -g n”命令时出现错误: npm ERR!notsup n@6.1.3的平台不受支持:想要{"os":"!win32","arch":"any"}(当前为{"os":"win32","arch":"x64"}) - Daryl McCullough
1
我之前使用的是Node 12,降级后解决了问题。 - mahendraraut

55

使用以下命令安装Node.js v11.15.0和Gulp.js v3.9.1:

npm install -g n

sudo n 11.15.0

npm install gulp@^3.9.1
npm install
npm rebuild node-sass

它将解决这个问题:

在Node中引用错误:primordials未定义


9
请勿使用短期支持的NodeJS分支(所有奇数版本号如9和11),请使用NodeJS 10。 - user753676
1
sudo n 11.15.0 中的 n 应该在第一步中安装,即 npm install -g n。那是什么?它还有效吗? - Peter Mortensen
如果您在运行 npm install gulp@^3.9.1 时遇到权限问题,请按照此指南 https://docs.npmjs.com/resolving-eacces-permissions-errors-when-installing-packages-globally 中的步骤进行操作。 - Crisoforo Gaspar

48

对我来说,Diego Fortes的回答有效,只需要进行一些小改动。

如果出现此错误,以下是我的工作流程:

  1. npm install

  2. npm install gulp

  3. 创建文件npm-shrinkwrap.json,其中包含:

    {
      "dependencies": {
        "graceful-fs": {
            "version": "4.2.2"
         }
      }
    }
    
  4. npm install(再次执行)(不要再次执行npm install gulp!非常重要 - 否则错误会回来)

  5. gulp(现在正在工作)


3
这只是一个临时的解决方案,如果再次运行 npm i,它会再次出现问题。 - Anuga

32

使用NVM来管理你正在使用的Node.js版本,对我有用的命令如下:

cd /to/your/project/
nvm install lts/dubnium
nvm use lts/dubnium
yarn upgrade # or `npm install`

7
请勿使用短寿的NodeJS分支(所有奇数版本号如9和11),请使用NodeJS 10。并且使用“10”代替代码名称。 - user753676
1
对于 Windows 用户,请使用 nvm-windows - Lupa
Dubnium = Node.js 10.24.1 - sigmapi13

28

Gulp 3.9.1不适用于Node v12.x.x,如果您想升级到Gulp 4.0.2,则必须使用新的语法(series & parallels)完全更改gulpfile.js文件。因此,最好的选择是降级到Node.js v11.x.x(11.15.0版本对我来说工作良好),只需在终端中使用以下代码:

nvm install 11.15.0
nvm use 11.15.0 # Just in case it didn't automatically select the 11.15.0 as the main node.
nvm uninstall 13.1.0
npm rebuild node-sass

28

简述

Gulp 3.* 不支持 Node.js 12.* 或以上版本。您必须降级 Node.js 或升级 Gulp。

如果时间紧迫,请将Node.js降级到v11.*或更低版本;如果需要新功能,并且有时间修复许多损坏的依赖项,请升级Gulp至4.*或更高版本!

正如其他人已经提到的那样,Gulp 3.* 在 Node.js 12 或更高版本上不受支持,因此您必须将Node版本降级至11.*或以下,或者将Gulp升级到4.0。

最佳选择取决于您有多少时间,升级Gulp可带来更干净的gulpfiles和内置的控制方式,使任务在串联或并联中运行,但也依赖于您将gulpfile重写为新语法,并且可能(看本评论结尾)会与某些依赖项发生冲突。


降级Node.js

这是最简单和最快速的选项。特别是如果您使用nnvm,因为它们允许您快速安装和切换Node.js版本。

N中的安装Node.js版本

n 10.16.0

在 NVM 上安装 Node.js 版本

nvm install 10.16.0

完成此操作后,您可能需要重建您的npm依赖关系,或者删除您的node_modules文件夹package-lock.json文件,然后重新安装您的依赖项。但是,如果您仅还原到现有的Node.js版本,则应该没有问题。


升级Gulp

如上所述,这是一个更耗时的任务,但从长远来看可能会带来好处。例如,Node.js 12现在已经引入了ES模块的本地支持(在实验性标志后面),并且在Node.js 13中提供了全面的支持。

您可能需要升级Node.js才能使用它,从而强制您升级Gulp。或者,您可能仅仅想要使用Gulp 4的好处,因为它可以更好更有效地控制编写任务。

已有许多关于此的文章,因此我不会进一步阐述详情,但要重申这不是一个快速的工作。根据您的项目大小,可能需要进行一些重写,并且您可能有一些破坏的依赖项。如果时间不充足,您应该选择简单降级Node.js,至少是暂时的。


但我已经有Gulp 4,它仍然不起作用!

如果像我一样,您已经使用Gulp 4+(我最初在Node.js 10上使用Gulp 4.0.2),并且最近升级了(我升级到了Node.js 13.8.0),但仍然遇到了问题,则可能是由于某个依赖项依赖于较旧版本的Gulp,并被捕获在流程中。

在我的情况下,gulp-combine-mq是一个使用Gulp 3.9.*的依赖项。在我的gulpfile中禁用此任务后,Gulp又可以运行了。

如果发生这种情况,您有几个选项:

  1. 如果插件并非绝对必要,则可以不使用该插件
  2. 寻找替代品,
  3. 修复插件

不用说,如果您有多个插件依赖于较旧版本的Gulp - 尤其是这些插件对于您的应用程序非常重要 - 那么在升级Gulp方面可能需要花费大量额外的时间(因此上面的警告)。

如果发生这种情况,最好只是降级Node.js,至少在可以发布补丁之前。


2
对我来说,这也是我的情况。我正在使用Gulp 4,但一个旧的gulp插件在内部依赖于旧版本的graceful-fs。可以使用“npm ls graceful-fs”找到罪魁祸首 - 使用低于4的版本的graceful-fs的软件包将导致此问题。从gulpfile中删除它,使用替代方案或升级它以解决问题。 - Ondra Koupil

28

简单而优雅的解决方案

只需按照以下步骤操作。它在运行多次 npm install 或安装任何其他模块甚至发布项目到 artifactory 时都能完美运行。

在 package.json 文件所在的同一目录中创建一个名为 npm-shrinkwrap.json 的文件,并包含以下内容:

{
  "dependencies": {
    "graceful-fs": {
        "version": "4.2.2"
     }
  }
}

运行npm install,别担心,它将用大量内容更新npm-shrinkwrap.json。通过更新package.json脚本选项来摆脱这些更新。

"scripts": {
    "preshrinkwrap": "git checkout -- npm-shrinkwrap.json",
    "postshrinkwrap": "git checkout -- npm-shrinkwrap.json"
}

现在您可以运行npm install,您的npm-shrinkwrap.json文件将保持完好无损,并且永远有效。


3
谢谢!你帮我省去了手动保存npm-shrinkwrap.json的麻烦。 - dblazeski
1
很高兴看到我在Stack Overflow上的第一篇帖子能够帮助你成为@dblazeski的第一个人 :) - saumilsdk
@saumilsdk 当我安装其他模块时,例如 npm i bla,它只安装了 graceful-fs 和新的模块,但所有其他模块都不见了,你也是这样吗? - NthDegree
@NthDegree 没有,我没有看到那种情况发生。你应该在你的 package.config 文件中看到一些变化。 - saumilsdk
不错,但是在npm v7中,这些指令已经消失了。根据https://github.com/npm/cli/issues/2520的说法,它们永远不会被执行。 - gaitat

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接