npm link是个什么东东?

475 阅读4分钟

大家好,我是程序员_随心,希望能够通过自己的学习输出给你带来帮助。

背景

我之前在本地做的一个cli工具叫hcli,当时用了npm link命令,然后就可以在全局使用hcli命令了。当时没细研究是为什么,现在来研究一下。

官方介绍

This is handy for installing your own stuff, so that you can work on it and test iteratively without having to continually rebuild.

Package linking is a two-step process.

First, npm link in a package folder will create a symlink in the global folder {prefix}/lib/node_modules/<package> that links to the package where the npm link command was executed. It will also link any bins in the package to {prefix}/bin/{name}. Note that npm link uses the global prefix (see npm prefix -g for its value).

Next, in some other location, npm link package-name will create a symbolic link from globally-installed package-name to node_modules/ of the current folder.

简单翻译下:

这对于安装您自己的东西很方便,这样您就可以在上面工作并迭代测试,而不必不断地重新构建。

包链接是一个两个步骤的过程。

首先,包文件夹中的npm link会在全局文件夹{prefix}/lib/node_modules/中创建一个符号链接,链接到执行npm link命令的包。它还会将包中的所有bin链接到{prefix}/bin/{name}。注意,npm link使用全局前缀(参见 npm prefix -g的值)。

接下来,在其他地方,npm link <package-name>会创建一个符号链接,从全局安装的package-name链接到当前文件夹的node_modules/

实践一下

以下为以hsm-vue2-cli项目为例,我们来验证下。

看下项目的pakage.json文件:

{
  "name": "hcli",
  "version": "1.0.0",
  "description": "my vue cli",
  "main": "index.js",
  "bin": "index.js",
  "scripts": {
    "dev": "node index.js"
  },
  "keywords": [],
  "author": "Shimang He",
  "license": "ISC",
  "dependencies": {
    "ejs": "^3.1.6",
    "inquirer": "^8.2.0"
  }
}

1. 我们首先验证在项目目录下使用npm link命令将包链接到全局作用域下

我们使用npm link命令

➜  hsm-vue2-cli npm link

added 1 package, and audited 3 packages in 2s

found 0 vulnerabilities


➜  hsm-vue2-cli npm ls -g
/Users/hsm/.nvm/versions/node/v16.13.1/lib
├── corepack@0.10.0
├── hcli@1.0.0 -> ./../../../../../code/hsm-vue2-cli
├── npm@8.1.2
├── pnpm@6.32.3
└── yarn@1.22.18

可以看到已经挂到了全局。

官网说npm link会在全局文件夹{prefix}/lib/node_modules/中创建一个符号链接,链接到执行npm link命令的包。它还会将包中的所有bin链接到{prefix}/bin/{name}。我们验证下:

➜  ~ npm prefix -g
/Users/hsm/.nvm/versions/node/v16.13.1

➜  ~ cd /Users/hsm/.nvm/versions/node/v16.13.1/lib/node_modules

➜  node_modules git:(5b3d188) ls
@vue     corepack hcli     npm      pnpm     yarn

➜  node_modules git:(5b3d188) cd /Users/hsm/.nvm/versions/node/v16.13.1/bin

➜  bin git:(5b3d188) ls
corepack hcli     node     npm      npx      pnpm     pnpx     yarn     yarnpkg

注意,我们可以看到其实npm link命令是将hsm-vue2-cli这个项目的package.json中的name属性挂到了全局。那么我们试着使用下它:

➜  ~ hcli
my cli is working~
? Your name (my-node-cli)

ok,已经成功了~

2. 我们来验证npm link 是不是从全局安装的package-name链接到当前文件夹的node_modules/

首先我们切换到另外一个项目npmlinktest

image-20220331133036789.png

我们可以看到node_modules文件夹下引入了hcli这个包,并且这个文件夹后边有一个符号,便是为Symbolic link。ok,我们也验证完了这个,非常棒👍🏻!

那我们该如何解除npm链接的全局包呢?

方法一:

通过npm uninstall -g hcli

➜  ~ npm ls -g --depth=0
/Users/hsm/.nvm/versions/node/v16.13.1/lib
├── corepack@0.10.0
├── hcli@1.0.0 -> ./../../../../../code/hsm-vue2-cli
├── npm@8.1.2
├── pnpm@6.32.3
└── yarn@1.22.18

➜  ~ npm uninstall -g hcli

removed 1 package, and audited 1 package in 157ms

found 0 vulnerabilities

➜  ~ npm ls -g --depth=0
/Users/hsm/.nvm/versions/node/v16.13.1/lib
├── corepack@0.10.0
├── npm@8.1.2
├── pnpm@6.32.3
└── yarn@1.22.18

方法二:

删除{prefix}/lib/node_modules/<package>{prefix}/bin/{name}这两处的文件及文件夹

➜  ~ rm /Users/hsm/.nvm/versions/node/v16.13.1/bin/hcli

➜  ~ npm ls -g
/Users/hsm/.nvm/versions/node/v16.13.1/lib
├── corepack@0.10.0
├── hcli@1.0.0 -> ./../../../../../code/hsm-vue2-cli
├── npm@8.1.2
├── pnpm@6.32.3
└── yarn@1.22.18

➜  ~ hcli
zsh: command not found: hcli
rm -rf /Users/hsm/.nvm/versions/node/v16.13.1/lib/node_modules/hcli

➜  ~ npm ls -g
/Users/hsm/.nvm/versions/node/v16.13.1/lib
├── corepack@0.10.0
├── npm@8.1.2
├── pnpm@6.32.3
└── yarn@1.22.18

此删除方式需注意要删除{prefix}/lib/node_modules/<package>{prefix}/bin/{name}这两处的文件及文件夹

参考

docs.npmjs.com/cli/v8/comm…

最后

您的每一个点赞及评论都是对我坚持写作最大的支持! 另外希望各位朋友和我交流讨论,如有不对的地方,更希望批评指正!

我是程序员_随心,希望能够通过自己的学习输出给你带来帮助。