目录
1. npm install VS npm install -g
2. npm install -g 的本质?映射脚本的作用?
3. 如何测试使用未发布的 npm 包?npm link 原理?
4. link 到项目
4.1 全局 link
4.2 解除 link
4.3 link 到项目有两种情况(项目和模块是否在同一目录)
4.3.1 当项目和模块在 相同 目录下,可以使用相对路径,只需 link 一次
4.3.2 当项目和模块在 不同 目录下,需要做两次 link
5. 通过 npm link,测试本地编写的 node 模块
5.1 创建待测试 node 模块,生成 package.json
5.2 创建真实项目,运行报错找不到待测试 node 模块
5.3 在待测试 node 模块目录下,开启全局 link
5.4 在 project 目录下,连接项目和待测试 node 模块
5.5 运行项目,查看 项目 和 待测试 node 模块 连接效果
5.6 移除项目和模块的 link、移除 待测试 node 模块全局 link
6. 通过 npm link,在项目中使用全局安装的模块
7. 为什么全局安装的模块,不能直接 require,而要通过 npm link 呢?
8. 参考文章
1. npm install VS npm install -g
npm install 可以把发布在 npmjs 平台上的模块包,下载到本地项目中
npm install -g 可以把包下下来的同时,还帮我们配置好全局变量:
- 此时可以直接使用命令运行,比如 nrm use
- 避免了通过 node 执行,比如 node nrm ...
- 也避免了配置 package.json 的 script 脚本来执行,比如 "script": "node nrm ..."
以上内容,仅限于已经发布的包;
2. npm install -g 的本质?映射脚本的作用?
在 mac 中,在终端可以直接使用的命令(比如 nrm),其实是在执行 /usr/local/bin 目录下的脚本(/usr/local/bin 是 全局命令 所在的地方);
在执行 npm install -g 的时候,相关依赖会被安装在 /usr/local/lib/node_modules 目录下;
在 /usr/local/bin 目录下,不仅存储了全局命令,还有一个映射脚本;
映射脚本会把 npm install -g 安装的内容,指向 /usr/local/lib 下的真实文件;(优点:实现了只有一份可执行文件的前提下,给命令取别名)
3. 如何测试使用未发布的 npm 包?npm link 原理?
1 中说了,npm install 和 npm install -g,仅限于已经发布的包
那么如何测试使用未发布的 npm 包呢?难道要把一个未经测试的包发布到 npm,然后 install 下来测试吗?
当然不能这么做,npm 官方提供了 测试本地包 的工具指令:npm link
npm link 可以帮助我们模拟包安装后的状态,它会在系统中做一个快捷方式映射,让本地的包就好像 install 过一样,可以直接使用
npm link 做的事情,和 2 中 npm install -g 做的事 基本一致,区别在于:
- npm link 在 /usr/local/lib 下的 node_modules 里不是存的真实的文件,而是存了一个快捷方式
- 该 快捷方式 指向当前执行 npm link 的目录
- 如果开发的是 node 包,则执行的命令名和真实执行的文件入口,会根据项目 package.json 里 bin 的配置来获取
4. link 到项目
4.1 全局 link
如果编写的 node 模块,是单独的一个项目,不和其他的项目在同一个目录下
为了让其他目录下的项目,使用 node 模块,需要将 node 模块 link 到全局
npm link 前,需要在 node 模块的 package.json 里,配置 bin 字段
"bin" : {
"your-command-name": "./path-to/your-command-entry-file"
}
在 node 模块目录下,执行 npm link(全局 link 不需要添加任何参数哦)
cd your-command-module
npm link
成功后,就可以在 终端 执行全局命令 your-command-name 了
4.2 解除 link
测试完待测试 node 模块后,记得要解除全局 link,不然全局 node_modules 内的快捷方式太乱了
解除模块全局 link —— 进入模块目录,执行 unlink
cd your-command-module
npm unlink your-command-module
解除项目和模块 link —— 进入项目目录,执行 unlink
cd your-project
npm unlink your-ui-lib
4.3 link 到项目有两种情况(项目和模块是否在同一目录)
如果是测试前端包,跑在浏览器环境的,比如 UI 组件库,有两种情况
4.3.1 当项目和模块在 相同 目录下,可以使用相对路径,只需 link 一次
npm link ../xx-module
4.3.2 当项目和模块在 不同 目录下,需要做两次 link
进入待测试组件库目录,将组件库 link 到全局
cd your-ui-lib
npm link
进入要使用该组件库的工程,在工程中 link 组件库
cd your-project
npm link your-ui-lib
现在就可以在 工程 中使用 组件库,就好像 组件库 被 install 到工程中一样
5. 通过 npm link,测试本地编写的 node 模块
创建一个项目 npm-link-test,该项目包含了两部分内容:
- 自己编写的待测试的 node 模块
- 真实项目,该项目将安装并使用上面的 node 模块
项目基本结构:
5.1 创建待测试 node 模块,生成 package.json
module.exports = {
name: "LyrelionNodeModules",
sayHello: function(){
console.log("hello LyrelionNodeModules");
}
}
使用 npm init -y 可以自动生成 package.json 并命名,像这样:
{
"name": "lyrelion-node-modules",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC"
}
5.2 创建真实项目,运行报错找不到待测试 node 模块
执行 node demo.js,不出意外的报错了,找不到 LyrelionNodeModules 模块,这是因为 require 当前的搜寻目录里,没有 LyrelionNodeModules 模块
5.3 在待测试 node 模块目录下,开启全局 link
切换到 LyrelionNodeModules 目录下,执行 npm link,开启全局 link
我们知道,npm link 命令的作用是:
- 在全局环境下,也就是 Node.js 安装目录下的 node_modules 目录下,生成一个符号链接文件(就是创建一个快捷方式文件)
- 该文件的名字就是 LyrelionNodeModules 目录下 package.json 文件中指定的模块名
因为,它是一个快捷方式,所以无论在 LyrelionNodeModules 下修改了什么东西,都会实时更新
5.4 在 project 目录下,连接项目和待测试 node 模块
执行 npm link lyrelion-node-modules,就可以连接 项目 和 待测试 node 模块 了
看,此时项目下面生成了 node_modules!
5.5 运行项目,查看 项目 和 待测试 node 模块 连接效果
执行 node demo.js 还是报错了
因为待测试第三方模块里,没指定 bin,所以默认的名字是 中划线形式,而我最初写的是 大驼峰形式,把大驼峰改成中划线即可,打印效果也对了
5.6 移除项目和模块的 link、移除 待测试 node 模块全局 link
移除项目和模块的 link:进入项目目录下,执行 npm unlink lyrelion-node-modules
此时,node_modules 中的 待测试 node 模块包,被移除了
移除 待测试 node 模块全局 link:进入待测试 node 模块目录下,执行 npm unlink lyrelion-node-modules
6. 通过 npm link,在项目中使用全局安装的模块
5 中,npm link 自己写的模块,但大部分情况下,我们都是要引用别人写好的模块,此时也可以通过 npm link 简化操作
假设现在有 A、B 两个项目,都使用了 Coffee-script 模块:
首先,将 Coffee-script 安装到全局
npm install coffee-script -g # 全局安装 Coffee-script
其次,在每一个要开发的应用中,连接全局安装的 Coffee-script
cd A
npm link coffee-script # 把全局安装的 Coffee-script 模块,链接到 A 的 node_modules 下
cd B
npm link coffee-script # 把全局安装的 Coffee-script 模块,链接到 B 的 node_modules 下
更新全局安装的 Coffee-script,则 A、B 中的依赖也自动更新了
npm update coffee-script -g # 更新全局安装的 Coffee-script,所有 link 的项目同时更新了
7. 为什么全局安装的模块,不能直接 require,而要通过 npm link 呢?
可能会有人疑问:
- 不是说全局安装的包,在每一个项目中都可以用吗?
- 为啥这里全局安装了 Coffee-script,在具体的项目中,却还需要 npm link 进行使用呢?
注意以下几点:
- npm install -g moduleName 是将模块装到 全局目录 下
- 全局安装的模块,是供命令行(command line)使用的,比如 grunt
- 全局安装的模块,不可以用 require 调用包,而项目中需要 require,所以需要 npm link 一下
8. 参考文章
npm link详解 | ChampYin's Blognpm install 可以把发布在 npmjs 平台上的模块包下载到本地,npm install -g 可以把包下下来的同时,还帮我们配置好全局变量,让我们可以直接使用命令而不是通过 node 来执行或者配置 package.json 的 script 脚本来 run。 但这仅限于已经发布的包,那对于未发布的包,要怎么测试使用呢?难道要把一个未经测试的包发布上去然后 install 下来测试?https://champyin.com/2019/08/27/npm-link%E8%AF%A6%E8%A7%A3/ npm link的用法 - zhangzl419 - 博客园npm link的用法 假如我们想自己开发一个依赖包,以便在多个项目中使用。 一种可行的方法,也是npm给我们提供的标准做法,那就是我们独立开发好这个依赖包,然后将它直接发布到npm镜像站上去,等以后https://www.cnblogs.com/zhangzl419/p/15210835.html