如何使用Node.js解决“找不到模块”错误?

845

从GitHub上拉下一个模块并按照构建说明操作后,我尝试使用以下命令将其拉入现有项目:

> npm install ../faye

这似乎可以解决问题:

> npm list
/home/dave/src/server
└─┬ faye@0.7.1
  ├── cookiejar@1.3.0
  ├── hiredis@0.1.13
  └── redis@0.7.1

但是 Node.js 找不到这个模块:

> node app.js
node.js:201
        throw e; // process.nextTick error, or 'error' event on first tick
              ^
Error: Cannot find module 'faye'
    at Function._resolveFilename (module.js:334:11)
    at Function._load (module.js:279:25)
    at Module.require (module.js:357:17)
    at require (module.js:368:17)
    at Object.<anonymous> (/home/dave/src/server/app.js:2:12)
    at Module._compile (module.js:432:26)
    at Object..js (module.js:450:10)
    at Module.load (module.js:351:31)
    at Function._load (module.js:310:12)
    at Array.0 (module.js:470:10)

我真的很想了解这里到底发生了什么,但我有些不知道接下来该去哪里寻找。有什么建议吗?


11
期望node_modules目录与app.js文件在你的项目根目录下。为什么你在npm安装路径中使用了“..”? - Alex Wayne
3
将"npm install ../faye" 改为 "npm install ../faye/build" 后,它正常工作了。我不知道这种情况有多典型,但是当Faye被构建时,它创建了一个build目录并将package.json的副本放在其中。npm不会抱怨根级别的package.json,但是它引用那个级别不存在的文件。 - Dave Causey
5
我解决了这个问题,但实际上并没有得到我真正问题的答案,即如何解决这个问题。我将尝试提出一些建议,改进npm和/或node,使新手更容易避免这种情况。 - Dave Causey
1
请查看此链接(https://dev59.com/VmUp5IYBdhLWcg3wJlEH#15471995),您可能会了解到在哪里无法查找您的模块。 - Amol M Kulkarni
1
请检查您是否在安装它的同一文件夹中,如果您没有全局安装它。 - Ashwani Panwar
显示剩余3条评论
33个回答

664
使用npm install只会将模块安装到当前目录下(在一个名为node_modules的子目录中)。app.js是否位于home/dave/src/server/下?如果不是,并且您希望从任何目录中使用该模块,您需要使用npm install -g进行全局安装。
我通常会将大多数包本地安装,以便它们与我的项目代码一起被检入。
更新(8/2019):
现在,您可以使用package-lock.json文件,当npm修改您的node_modules目录时,它会自动生成。因此,您可以省略检入包,因为package-lock.json跟踪您当前正在使用的node_modules的确切版本。要从package-lock.json而不是package.json安装包,请使用命令npm ci
更新(3/2016):

我对我的回应受到了很多批评,特别是关于我检查代码依赖的软件包。几天前,有人撤销了他们所有的软件包(https://kodfabrik.com/journal/i-ve-just-liberated-my-modules)(Wayback Machine上的存档),这导致React、Babel和几乎所有其他内容都出现了问题。希望现在清楚了,如果你有生产代码,就不能指望NPM真正为你维护你的依赖关系。


283
通常我会在本地安装大多数软件包,这样它们就可以与我的项目代码一起进行检查。最好创建一个 package.json 文件列出你所依赖的npm模块,并忽略 node_modules 文件夹。然后,当你克隆存储库后,只需运行 npm install 即可设置。 - Alex Wayne
62
除了 package.json 列出所依赖的包之外,我还喜欢保存那些我需要的东西的已知良好副本。硬盘空间很便宜,如果 npm 或包在 npm 上消失了,我仍然可以在我的代码库中拥有完全可用的项目。 - Bill
199
作为一名老开发者,当我读到Node开发人员的"范式"——"磁盘空间很便宜"时,我几乎噎住了。我有正在使用的库。想到可能会有100个副本(或更糟糕,接近副本),我的胃就翻了。磁盘空间虽然便宜,但维护时间很昂贵。也许如果你只是在做一个玩具项目,那么维护成本就很小。但对于实际工作来说,维护成本很高,与磁盘空间的成本无关。 - Lloyd Sargent
86
我真的不理解最后评论的意思。没有人建议拥有任何代码的100个副本,只是建议拥有你的项目所依赖的代码的1个副本。否则,如果NPM或该依赖关系在某一天消失,则项目将无法正常运行。我认为从头开始重写一个依赖项也相当昂贵。顺便说一下,我在微软工作了10年,我们总是将第三方依赖项检入到我们的源代码库中。 - Bill
45
@LloydSargent,拥有“接近副本”并不更糟,它更好,因为每个项目都有一个特定的依赖关系,你已经定义并且其余代码依赖于它。 如果您在多个项目中具有相同版本,则如果您更新任何内容,则必须更新所有内容*。 锁定依赖项允许逐步升级-维护量大大减少。针对实际工作的非玩具项目。 - Dave Newton
显示剩余15条评论

597

我遇到了非常类似的问题。移除整个node_modules文件夹并重新安装解决了我的问题:

rm -rf node_modules
npm install

19
我也会执行npm cache clean,只是为了安全起见 :) - Tony Tai Nguyen
2
当出现“npm install”/“npm update”无法解决的奇怪依赖问题时,这可能是一个不错的第一步故障排除。这解决了一个问题,即当我尝试运行我的Express应用程序时,会随机显示“Error: Cannot find module 'http-errors'”。 - Matt Vukas
10
在运行 npm install 之前,缺少的一步是删除你的 package-lock.json 文件。 - Rick Quantz
这对我没有用,甚至重启了电脑 ;) - Jason G
1
npm ci 会执行相同的操作,但是它是跨平台的。 - jenson-button-event
显示剩余2条评论

106
npm install --save module_name
例如,如果错误是:

{ [Error: Cannot find module '/root/.npm/form-data'] code: 'MODULE_NOT_FOUND' }

那么您可以通过执行命令npm install --save form-data来解决此问题。

1
似乎当我全局安装时,npm/node-modules文件夹是空的,而我尝试使用ng new project-name时显示一些模块丢失...我不得不使用给定的命令逐个安装它们。然后解决了这个问题,但是否有任何单个命令可以一次性安装所有模块? - Vishal Nair

45
rm package-lock.json
rm -r node_modules
npm i

那应该解决问题并安装所有包。


非常感谢,帮了大忙。 - Ahsan Farooq

41

对于 TypeScript 用户,如果您正在导入内置的 Node 模块(例如 httppathurl),并且出现 "Cannot find module "x" 的错误,可以通过运行以下命令来解决:

npm install @types/node --save-dev

该命令将把NodeJS的TypeScript定义导入到您的项目中,使您能够使用Node的内置模块。


23

当第一次npm安装出现故障(npm的SIGINT),延迟时间过长或数据损坏时,就会发生这种情况。再次尝试npm安装无法解决问题。

npm首次检查出现了问题,所以最好的选择是删除文件并重新启动npm安装。


19
这为我确诊了问题。最终我执行了 npm cache clear 命令来清除缓存,并清空了 node_modules 目录,然后跟着执行了 npm install 命令来解决我的问题。 - meklarian

18

我昨天遇到了这个错误。花了一段时间才意识到 package.json 中的 main 入口指向了一个我移动过的文件。一旦我更新了它,错误就消失了,程序包可以正常工作。


5
天哪……我绝望地在谷歌上输入了“Error: Cannot find module”,然后找到了这个问题。你的答案解决了我的问题。我不敢相信如此模糊的搜索词竟然能找到正确的答案。向你和谷歌致敬! Translated: 天哪...我绝望地在谷歌上输入了“Error: Cannot find module”,然后找到了这个问题。你的答案解决了我的问题。我不敢相信如此模糊的搜索词竟然能找到正确的答案。向你和谷歌致敬! - Jamon Holmgren
3
非常感谢。我已经成功将我的子模块的“main”入口指向了一个被排除在其存储库之外的目录,因此当我尝试通过“npm install”将其包含时,它可以工作,但是在需要时找不到任何导出!非常感谢这个明显但有用的答案。 - Dragos
2
谢谢你。我在使用Yarn工作区时遇到了这种情况,所以一直在寻找路径解析算法和各种东西。 :) 我被错误消息中“定位”模块的方式所困扰,而且ESLint也给出了类似的错误消息。然后我看到了你的答案,意识到自己是个笨蛋。谢谢! - Mark Birbeck
package.json文件在哪里?有人能提供更多的上下文吗?我已经使用VS Code一年了,成功地编写了各种编码项目,但我对NodeJS还很新,需要一步一步地解决这个非常令人沮丧的问题。我在这个页面上尝试的其他所有方法都不起作用,或者没有足够的上下文。 - Hotelsinger

17

检查环境变量NODE_PATH是否被正确设置,并指向node_modules路径。Node.js使用该变量来搜索库文件。


我点赞了这个回答,因为它解决了我的问题,并引导我查看了这篇node.js文档。但我认为这并不是一个通用的答案,因为文档指出了定位模块的替代策略。 - Graham Klyne
是的,这应该是解决此类“未找到模块”路径相关问题的正确方法。 - Nam G VU

13

如果您使用nvm,请检查已经绑定到其他库的node_modules是否已经编译为正确的Node.js版本。

我曾遇到同样的错误。原因如下:我们在服务器上运行两个应用程序,其中一个需要Node.js 5.6,因为它使用node-gd(目前不支持Node.js 6),另一个需要Node.js 6。Node.js 6是apt-get安装的。

此外,我们使用pm2工具进行部署。

因此,默认设置是当nvm未生效时,pm2进程启动,因此它使用Node.js(版本6)的apt-get安装。因此,主pm2守护进程使用Node.js 6启动。如果我以fork模式运行应用程序,则它们会在单独的进程中启动,并且nvm设置会生效。当我以集群模式运行应用程序时,它们会继承非nvm环境。

因此,当我尝试切换到集群模式时,应用程序无法启动,因为编译为5.6的绑定将失败并显示此消息。

我通过在nvm设置生效时重新启动pm2来解决了这个问题。还应该修复启动脚本。


11

如果其他所有方法都不起作用,尝试:

npm link package_name

e.g

npm link webpack
npm link autoprefixer

e.t.c


11
感谢您的请求!我会尽力将以下内容翻译成通俗易懂的中文,不改变原意。 - Kathir
2
请解释一下! - carloswm85

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