如何在 Node 中导入全局模块?我得到“错误:找不到模块 <module>”?

Posted

技术标签:

【中文标题】如何在 Node 中导入全局模块?我得到“错误:找不到模块 <module>”?【英文标题】:How do I import global modules in Node? I get "Error: Cannot find module <module>"? 【发布时间】:2011-12-19 17:24:12 【问题描述】:

我正在尝试在 Mac OSX Lion 上设置 Node。一切似乎都正常,但我似乎无法从我的全局模块文件夹中导入任何模块。我得到了错误,

Error: Cannot find module <module>

如果我运行这个:node -e require.paths,我得到的响应是:

[ '/usr/local/lib/node_modules',
  '/Users/Me/.node_modules',
  '/Users/Me/.node_libraries',
  '/usr/local/Cellar/node/0.4.12/lib/node' ]

这是正确的,我的模块确实安装在 /usr/local/lib/node_modules 中。但是,当我尝试运行脚本时,我得到了这个:

Error: Cannot find module 'socket.io'
    at Function._resolveFilename (module.js:326:11)
    at Function._load (module.js:271:25)
    at require (module.js:355:19)
    at Object.<anonymous> (/Users/Me/node/server.js:2:10)
    at Module._compile (module.js:411:26)
    at Object..js (module.js:417:10)
    at Module.load (module.js:343:31)
    at Function._load (module.js:302:12)
    at Array.<anonymous> (module.js:430:10)
    at EventEmitter._tickCallback (node.js:126:26)

我的 .bash_profile 如下所示:

export PATH=/usr/local/mysql/bin:$PATH
export NODE_PATH=/usr/local/lib/node_modules
export DYLD_LIBRARY_PATH="$DYLD_LIBRARY_PATH:/usr/local/mysql/lib/"

非常感谢一些帮助,我不知道为什么我不能导入任何库。

【问题讨论】:

你知道这不是做事的首选方式,对吧? 您能详细说明一下吗?你的意思是我不应该将库安装到我的全局文件夹中吗? @Hanpan:首选方式是在本地通过 require() 安装要使用的模块。 可以在这里找到更好和更新的答案(不依赖于npm link):***.com/a/15646750/2671392 我是老派,习惯于在全球范围内安装库。我从未见过大量使用本地库安装的任何令人信服的理由。到我们完成时,我正在学习的 mongodb 课程最终将包含近一百个小项目,每个项目都包含一组大部分重复的库 - mongodb、express、consolidate 等。向交互式语言的转变留下了存款各地的地方图书馆。我必须在本地 Scala 存储库中有数千个 Scala 库。同上 Meteor,groovy 和 ruby​​。 【参考方案1】:

如果您使用 npm >=1.0,您可以使用 npm link &lt;global-package&gt; 创建一个本地链接,指向已在全球范围内安装的软件包。 (警告:操作系统必须支持符号链接。

然而,这并非没有问题。

npm 链接是一个开发工具。 真棒 用于管理本地开发盒上的包。但是使用 npm link 进行部署基本上是在自找麻烦,因为它使得在不知不觉中更新内容变得超级容易。

作为替代方案,您可以在本地和全局安装包。

有关更多信息,请参阅

https://nodejs.org/en/blog/npm/npm-1-0-link/ https://nodejs.org/en/blog/npm/npm-1-0-global-vs-local-installation/

【讨论】:

我正在读这篇文章,简直不敢相信自己的眼睛。因此,如果我安装 express,然后在 express 之上构建 20 个项目,我需要为每个项目安装 20 次,在每个项目文件夹中,一遍又一遍?我对包管理器没有太多经验,但这有点糟糕...... 说的没错,仔细想想,也有道理。在本地管理您的依赖项可以使所有内容保持独立,并允许您为任何给定项目指定特定版本的依赖项(例如,项目 foo 需要 express 2.x,而项目 bar 可以使用 express 3 beta)。 我也有一段时间难以理解其逻辑,但在看到我的 Ruby 朋友为全局包更新而苦苦挣扎、争论 gemset 并且通常根本不升级之后,我承认在本地安装依赖项绝对是进行包管理的唯一明智的方法 我想将这种情况与静态链接库与动态链接库的情况进行比较,因为它与软件分发有关。考虑到几乎所有在 ios App Store 上分发的应用程序都必须静态链接 iOS SDK 未提供的依赖项。为什么这样做?全局依赖地狱是非常真实的事情。 据我了解,npm 的缓存(位于~/.npm)将使您在不同位置执行重新安装过程变得方便。【参考方案2】:

Node.js 使用环境变量NODE_PATH 允许指定要包含在模块搜索路径中的其他目录。您可以使用npm 本身来告诉您使用npm root -g 命令将全局模块存储在哪里。因此,将这两者放在一起,您可以使用以下命令(在 Linux 上)确保全局模块包含在您的搜索路径中

export NODE_PATH=$(npm root --quiet -g)

【讨论】:

感谢NODE_PATH 环境变量提示。这帮助很大! 这应该是置顶评论 我必须将 NODE_PATH 设置为等效的 posix 路径才能使 npm 在 MSYS2 上工作。谢谢。 也适用于 Windows 和 Git bash。完美的。 :-) 适用于 Mac OSX。我正在使用单个 JS 文件并使用全局模块。处理起来更简单。【参考方案3】:

您可以使用 npm link 在项目文件夹中创建指向全局包的符号链接。

例子:

$ npm install -g express
$ cd [local path]/project
$ npm link express

它所做的只是创建一个本地 node_modules 文件夹,然后创建一个符号链接 express -> [全局目录]/node_modules/express 然后可以通过 require('express') 解析

【讨论】:

这个跨操作系统兼容吗? 较新版本的 Windows 支持它,因为此版本:github.com/npm/npm/commit/… 对于较旧的 Windows 版本,请尝试 npmjs.com/package/npm-junction【参考方案4】:

如下全局安装任何包:

$ npm install -g replace  // replace is one of the node module.

由于这个替换模块是全局安装的,所以如果你看到你的节点模块文件夹,你不会在那里看到替换模块,所以你不能使用 require('replace') 来使用这个包。

因为使用 require 您只能使用节点模块文件夹中存在的本地模块。

现在要使用全局模块,您应该使用以下命令将其与节点模块路径链接。

$ npm link replace

现在返回并查看您的节点模块文件夹,您现在可以在那里看到替换模块,并且可以在您的应用程序中将其与 require('replace') 一起使用,因为它与您的本地节点模块链接。

如果需要进一步澄清,请告诉我。

【讨论】:

【参考方案5】:

您可以将 require 与全局模块目录的路径一起用作参数。

require('/path/to/global/node_modules/the_module');

在我的 Mac 上,我使用这个:

require('/usr/local/lib/node_modules/the_module');

如何找到您的全局模块在哪里? --> Where does npm install packages?

【讨论】:

【参考方案6】:

将环境变量 NODE_PATH 设置为指向您的全局 node_modules 文件夹。

在 Windows 7 或更高版本中,路径类似于 %AppData%\npm\node_modules,而在 UNIX 中可能类似于 /home/sg/.npm_global/lib/node_modules/,但这取决于用户配置。

npm config get prefix 命令可以帮助找出正确的路径。

在 UNIX 系统中,您可以使用以下命令完成它:

export NODE_PATH=`npm config get prefix`/lib/node_modules/

【讨论】:

【参考方案7】:

简单的答案是在 npm 全局根目录中运行 node。

cd $( npm root -g ) && node

【讨论】:

【参考方案8】:

我正在使用 Docker。我正在尝试创建一个安装了所有节点依赖项的 docker 映像,但可以在容器运行时使用我的本地应用程序目录(而不用 node_modules 目录或链接污染它)。这会导致在这种情况下出现问题。我的解决方法是要求模块所在的确切路径,例如require('/usr/local/lib/node_modules/socket.io')

【讨论】:

【参考方案9】:

require.paths 已弃用。

转到您的项目文件夹并输入

npm install socket.io

应该将它安装在本地的 ./node_modules 文件夹中,节点会在其中查找它。

我的东西是这样的:

cd ~/Sites/
mkdir sweetnodeproject
cd sweetnodeproject
npm install socket.io

创建一个 app.js 文件

// app.js
var socket = require('socket.io')

现在运行我的应用程序

node app.js

确保您使用的是npm &gt;= 1.0node &gt;= 4.0

【讨论】:

他在询问是否使用全局安装的 npm 包。 @Jamund。您正在展示如何使用本地安装的软件包,但最初的问题是关于全局的。

以上是关于如何在 Node 中导入全局模块?我得到“错误:找不到模块 <module>”?的主要内容,如果未能解决你的问题,请参考以下文章

在 Node.js 中导入:错误“必须使用导入来加载 ES 模块”[重复]

如何在 Node.js REPL 中导入 ES 模块?

如何在 ember-cli 中导入 amd 模块?

如何在 React 组件中导入 CSS 文件

无法在 node.js 中导入模块 [重复]

如何在打字稿中导入js文件作为模块