65.9K
CodeProject 正在变化。 阅读更多。
Home

关于Node-Modules的注意事项

emptyStarIconemptyStarIconemptyStarIconemptyStarIconemptyStarIcon

0/5 (0投票)

2020年10月23日

CPOL

4分钟阅读

viewsIcon

4450

downloadIcon

48

Node-modules文件夹及其结构。

引言

这是一个关于node_modules文件夹及其结构的说明。

背景

这是一个关于node_modules文件夹及其结构的说明。特别是,当一个NODE项目引用同一包的不同版本时,我想回答以下问题。这些问题很简单,但如果处理不当,可能会导致恼人的版本地狱。

  • 同一包的不同版本是如何放置在node_modules文件夹中的?
  • 应用程序运行时,是否会调用同一包的所有版本,还是只调用该包的一个版本?

为了回答这些问题,我创建了三个NODE包。package-client项目直接和间接地引用了两个版本的package-0

  • 我们将发布两个版本的package-0,版本1.0.0和版本1.0.1
  • package-1引用package-0版本1.0.0
  • package-client引用package-1package-0版本1.0.1。因此,package-client同时引用了package-0的版本1.0.0和版本1.0.1

这个实验是在一个私有的NPM注册表上进行的。如果您不知道如何设置私有的NPM注册表,您可以查看我的另一篇说明。为了简化我的工作,所有包都作用域为"@example"。例如,package-0的全名是@example/package-0。我还为每个包添加了一个.npmrc文件,所以我每次发布或安装包时都不需要指定注册表URL(--registry)。

@example:registry=https://:4873/

如果您希望所有作用域为@example的包都使用注册表https://:4873/,您也可以将该条目放在您home目录下的.npmrc文件中。我们可以通过curl其URL来确认注册表是否正在运行。

curl https://:4873/

"package-0"

@example/package-0package.json如下所示

{
  "name": "@example/package-0",
  "version": "1.0.0",
  "description": "The @example/package-0",
  "main": "index.js",
  "author": "Song Li",
  "license": "ISC"
}

Index.js文件的唯一功能是导出一个表示版本号的string

module.exports = 'This is Version 1.0.0';

我们可以通过以下命令将包发布到注册表

npm publish

然后我们可以将package.jsonindex.js文件更新到版本1.0.1,并发布它。

{
  "name": "@example/package-0",
  "version": "1.0.1",
    ......
}
module.exports = 'This is Version 1.0.1';

我们可以通过以下命令确认这两个版本都已发布到注册表

npm view @example/package-0 versions

"package-1"

@example/package-1引用了@example/package-0

{
  "name": "@example/package-1",
  "version": "1.0.0",
  "description": "The @example/package-1",
  "main": "index.js",
  "author": "Song Li",
  "license": "ISC",
  "dependencies": {
    "@example/package-0": "1.0.0"
  }
}

有三种方法可以引用包版本

  • ~version “大约等于版本” - 它会将您更新到所有未来的补丁版本,而不会增加次要版本。~1.2.3 将使用从 1.2.3 到 <1.3.0 的版本;
  • ^version “与版本兼容” - 它会将您更新到所有未来的次要/补丁版本,而不会增加主要版本。^2.3.4 将使用从 2.3.4 到 <3.0.0 的版本;
  • 绝对版本 - 在此说明中,我使用了绝对版本 "1.0.0"

index.js需要@example/package-0并重新导出其string。由于@example/package-1引用了@example/package-0版本1.0.0,理想情况下它应该导出字符串 "This is Version 1.0.0"。

const msg = require('@example/package-0');
    
module.exports = msg;

然后我们可以发布该包并确认其在注册表中的可用性。

npm publish
npm view @example/package-1 versions

"package-client"

随着@example/package-0@example/package-1都发布到注册表,我们可以看看package-client

{
  "name": "package-client",
  "version": "1.0.0",
  "description": "The package-client ",
  "main": "index.js",
  "private": true,
  "keywords": [],
  "author": "Song Li",
  "license": "ISC",
  "dependencies": {
    "@example/package-1": "1.0.0",
    "@example/package-0": "1.0.1"
  }
}

它引用了@example/package-1@example/package-0index.js打印出这两个包的string

const msg_0 = require('@example/package-0');
const msg_1 = require('@example/package-1');
    
console.log(`Message from package-0: ${msg_0}`);
console.log(`Message from package-1: ${msg_1}`);

然后我们可以安装引用的包并查看node_modules文件夹。

npm install
find . -name "package-0" -type d -prune -print | xargs du -chs

如果我们现在运行index.js,我们将看到以下结果

node index.js

结论

现在我们可以得出结论。

  • 当NODE应用程序引用同一个包的多个版本时,所有版本都将安装在node_modules文件夹中。在这个例子中,1.0.1安装在顶层,1.0.0安装在@example/package-1文件夹下;
  • 当程序中使用同一个包的多个版本时,如果程序实际使用了这些版本,那么所有版本都将被调用。

我们可以进一步查看package-lock.json文件,以更好地理解如何安装包的不同版本。

我们需要与团队共享package-lock.json文件,以便所有人在npm install时都拥有相同的node_modules文件夹。如果我们想从注册表中清理实验包,可以使用以下命令

npm cache clean -f
npm unpublish @example/package-0 -f
npm unpublish @example/package-1 -f

关注点

  • 这是一个关于node_modules文件夹及其结构的说明。
  • 您不太可能遇到包的不同版本的问题。但是,如果您遇到问题,最好知道您可能在同一个程序中同时运行依赖包的不同版本。
  • 希望您喜欢我的帖子,并希望这篇说明能对您有所帮助。

历史

  • 2020年10月16日:第一次修订
© . All rights reserved.