NPM全局安装“找不到模块”

245

我刚刚编写了一个模块发布到npm上(https://npmjs.org/package/wisp)

在命令行中安装运行良好:

$ npm i -g wisp

但是,当我从命令行运行它时,一直出现一个错误,提示 optimist 未安装:

$ wisp 
Error: Cannot find module 'optimist'
    at Function.Module._resolveFilename (module.js:338:15)
    at Function.Module._load (module.js:280:25)
    at Module.require (module.js:362:17)
    at require (module.js:378:17)
    at Object.<anonymous> (/usr/local/lib/node_modules/wisp/wisp:12:10)
    at Object.<anonymous> (/usr/local/lib/node_modules/wisp/wisp:96:4)
    at Module._compile (module.js:449:26)
    at Object.exports.run (/usr/local/lib/node_modules/coffee-script/lib/coffee-script/coffee-script.js:68:25)
    at compileScript (/usr/local/lib/node_modules/coffee-script/lib/coffee-script/command.js:135:29)
    at fs.stat.notSources.(anonymous function) (/usr/local/lib/node_modules/coffee-script/lib/coffee-script/command.js:110:18)

然而,我已经在package.json文件中将其指定为依赖项:

{
  "name": "wisp",
  "author": "Brendan Scarvell <bscarvell@gmail.com>",
  "version": "0.1.0",
  "description": "Global nodejs file server",
  "dependencies": {
    "optimist": "~0.3.4"
  },
  "repository": "git://github.com/tehlulz/wisp",
  "bin": {
    "wisp" : "./wisp"
  }
}

有没有人知道如何使它运行?我知道和bin相关,需要将可执行文件添加到bin目录中,该目录下的node_modules为空。但是不知道如何解决。


如果您没有使用-g选项安装,会发生什么? - vinayr
它会在当前目录下安装一个node_modules文件夹,其中包含wisp。 - Menztrual
是的。如果我在本地运行 npm i wisp 后尝试运行 wisp,仍然返回相同的错误。 - Menztrual
这对我也很好用。但我想要在一个随机目录中,只需输入$ wisp即可进行全局安装(类似于Express的方式)。 - Menztrual
如果我执行 export PATH=$PATH:~/node_modules/wisp,那么对我来说是有效的。 - vinayr
显示剩余3条评论
19个回答

417

如果其他人遇到了这个问题,那很可能是因为我的npm安装在不包含NODE_PATH的位置。

[root@uberneek ~]# which npm
/opt/bin/npm
[root@uberneek ~]# which node
/opt/bin/node
[root@uberneek ~]# echo $NODE_PATH

我的NODE_PATH为空,运行npm install --global --verbose promised-io命令显示正在安装到/opt/lib/node_modules/promised-io

[root@uberneek ~]# npm install --global --verbose promised-io
npm info it worked if it ends with ok
npm verb cli [ '/opt/bin/node',
npm verb cli   '/opt/bin/npm',
npm verb cli   'install',
npm verb cli   '--global',
npm verb cli   '--verbose',
npm verb cli   'promised-io' ]
npm info using npm@1.1.45
npm info using node@v0.8.4
[cut]
npm info build /opt/lib/node_modules/promised-io
npm verb from cache /opt/lib/node_modules/promised-io/package.json
npm verb linkStuff [ true, '/opt/lib/node_modules', true, '/opt/lib/node_modules' ]
[cut]

我的脚本在执行require('promised-io/promise')时失败:

[neek@uberneek project]$ node buildscripts/stringsmerge.js 

module.js:340
    throw err;
          ^
Error: Cannot find module 'promised-io/promise'
    at Function.Module._resolveFilename (module.js:338:15)

我可能是通过configure --prefix=/opt从源代码安装了node和npm。我不知道为什么这使它们无法找到已安装的模块。目前的解决方法是将NODE_PATH指向正确的目录:

export NODE_PATH=/opt/lib/node_modules

我现在成功地使用了require('promised-io/promise')


14
在哪里设置这个 NODE_PATH? - sandy
10
根据你的操作系统不同,设置 NODE_PATH 环境变量的位置也不同。我使用 Linux 的一种发行版,所以我使用 export NODE_PATH=... 命令在本地 shell 中设置它,并导出到在该 shell 中运行的命令中。若要使更改持久化或对所有 shell 可用,请将其放入 .profile 或类似文件中。总体概念对新手来说有点棘手,可以尝试阅读 https://help.ubuntu.com/community/EnvironmentVariables 。对于 Windows 用户,建议切换到 Linux。好吧,只是开个玩笑。可以参考 http://www.computerhope.com/issues/ch000549.htm 或搜索谷歌。 - Neek
14
对于OSX Lion,以下方法适用于我...将export NODE_PATH=/usr/local/lib/node_modules添加到我的环境变量中。我使用了“locate node_modules”来查找正确的路径。 - k1eran
2
NODE_PATH 对于 WINDOWS 也适用。这是因为 Node 模块可以在本地和全局安装。 - zinking
5
如果您在Mac OS X上使用Homebrew安装了Node.js:在终端中运行open -a TextEdit ~/.bash_profile,然后将export NODE_PATH=/usr/local/lib/node_modules添加到文件末尾。重新启动终端窗口。现在运行echo $NODE_PATH应该会打印出/usr/local/lib/node_modules - Pwdr
显示剩余11条评论

51

在Mac程序的开头添加以下内容:

module.paths.push('/usr/local/lib/node_modules');


该代码会将模块路径添加到节点模块中。

4
有没有一种非操作系统特定的方法来做到这一点? - UpTheCreek
@UpTheCreek 这是一种非特定于操作系统的方式。这是JS代码,你只需要指向一个包含你要查找的模块的node_modules。 - Adelin
1
@Adelin - 这是一个特定于操作系统的解决方案,因为全局 node_modules 的位置是特定于操作系统的。例如,如果您在 Windows 上进行开发,并在生产环境中运行 Linux,则这不是一个很好的解决方案。 - UpTheCreek
这很容易克服。例如,您可以将节点路径保存在环境变量中,并用 os.environ.nodepath 替换硬编码的路径(类似这样的方式)。 - Adelin
macOS Mojave 10.14.6需要在~/bash_profile中添加export NODE_PATH=/usr/local/lib/node_modules/npm/node_modules,这样更加机器独立,因为本地的.js代码不会受到影响。 - vwvan
你可以通过运行 npm root -g 命令来获取全局节点模块路径,然后在你的 JS 文件中使用上述解决方案。 - Olamide226

17

默认情况下,Node 不会查找 /usr/local/lib/node_module 以加载全局模块。 请参考http://nodejs.org/api/modules.html#modules_loading_from_the_global_folders中解释的模块加载方式。

因此,您必须要么: 1)将 /usr/local/lib/node_module 添加到 NODE_PATH,并导出它, 或者 2)将已安装的 Node 模块复制到 /usr/local/lib/node 中。 (如上述链接所述,Node 将在该路径中搜索并工作。)


15
以下通用修复方法适用于任何模块,例如使用 request-promise 的情况。

替换


npm install request-promise --global

随着

npm install request-promise --cli

已经起作用(来源),并且也适用于globalsinherits

另外,请尝试设置环境变量

NODE_PATH=%AppData%\npm\node_modules

npm install 命令中没有 --cli 参数。 - James Gentes

11

对于一些人(比如我),如果其他方法都不起作用,可以尝试这个:

brew cleanup
brew link node
brew uninstall node
brew install node
希望能对某人有所帮助 :)

8

3

如果你在Windows上刚刚进行了干净的安装,而出现了这个问题,那么你需要清除 \AppData\Roaming 中的npm缓存。


3

$ vim /etc/profile.d/nodejs.sh

export NODE_PATH=/usr/lib/nodejs:/usr/lib/node_modules:/usr/share/javascript

这是默认存在的。对于用户来说,它是被加载的,但是在以root身份运行时,它不会被加载,因此需要将其包含在root用户的路径中。 - stamster

2
对于Mac用户,最好使用手动安装方式:

To minimize the chance of permissions errors, you can configure npm to use a different directory. In this example, it will be a hidden directory on your home folder.

  1. Back-up your computer before you start.

  2. Make a directory for global installations:

    mkdir ~/.npm-global

  3. Configure npm to use the new directory path:

    npm config set prefix '~/.npm-global'

  4. Open or create a ~/.profile file and add this line:

    export PATH=~/.npm-global/bin:$PATH

  5. Back on the command line, update your system variables:

    source ~/.profile

  6. Test: Download a package globally without using sudo.

    npm install -g jshint

Instead of steps 2-4, you can use the corresponding ENV variable (e.g. if you don't want to modify ~/.profile):

NPM_CONFIG_PREFIX=~/.npm-global

参考文献: https://docs.npmjs.com/getting-started/fixing-npm-permissions

这篇文章介绍了如何修复npm权限的问题。在安装全局npm包或使用sudo运行npm命令时,您可能会遇到权限错误。本文提供了几种解决方法,包括更改npm默认目录的所有权和更改用户的UID。如果您遇到此类问题,请查看本文以获取帮助。

2

我用简单的方法做到了这一点...

  1. 从控制面板中卸载node [Windows 7]
  2. 重新安装node
  3. 安装protractor npm install --global --verbose protractor
    更新web driver manager。

对我来说运行良好。

希望这可以帮助你...


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