在Vue源码项目的package.json中发现了这么一段配置:
{
scripts: {
"preinstall": "npx only-allow pnpm"
}
}
用yarn install执行后会直接失败:
"preinstall": "npx only-allow pnpm"
这是用来干嘛的呢?我们逐一对它进行拆解:
1.preinstall
它是npm提供的一系列生命周期钩子之一,在包被安装前运行(但要注意preinstall不一定是会在install以前执行,它不同版本的执行顺序有所不同,具体可以查看[BUG] Preinstall script runs after installing dependencies)
2.npx
npx是一个由Node.js官方提供的用于快速执行npm包中的可执行文件的工具。它可以帮助我们在不全局安装某些包的情况下,直接运行该包提供的命令行工具。npx会在执行时,检查本地项目中是否安装了对应的依赖,如果没有安装则会自动下载安装,并执行命令。如果本地已经存在该依赖,则直接执行命令。
注:
(1)npx 不会像 npm 或 yarn 一样将包下载到本地的 node_modules 目录中。相反,它会在执行命令时,在本地缓存中寻找并下载包,然后执行该包中的命令。这样可以避免在开发过程中在全局安装大量的包,同时也可以确保使用的是最新版本的包。
(2)使用npx可以在命令行直接执行本地已安装的依赖包命令,不用在scripts脚本写入命令,也不用麻烦的去找本地脚本。例如:
我们本地安装了一个依赖包:
npm i -D mocha
在本地(当前目录)执行mocha
这个命令是不能执行的:
我们一般会使用几种方式来运行我们想要运行的命令:
①使用package.json的scripts脚本:
//package.json
"scripts": {
"mymocha": "mocha --version",
}
然后在命令行运行:
npm run mymocha
②在命令行中直接找到模块的二进制文件运行
③全局安装模块
而使用npx,我们可以直接在命令行执行我们要运行的命令:
npm i -D mocha
npx mocha --version
(3)它可以用来切换node版本来运行命令
利用 npx 可以下载模块这个特点,可以指定某个版本的 Node 运行脚本。当你想要运行的命令不兼容当前的nodejs版本,可以通过npx来切换版本,指定某个版本的 Node 来运行命令。
$ npx node@0.12.8 -v
v0.12.8
上面命令会使用 0.12.8 版本的 Node 执行脚本。原理是从 npm 下载这个版本的 node,使用后再删掉。
某些场景下,这个方法用来切换 Node 版本,要比 nvm 那样的版本管理器方便一些。
(4)npx的原理
npx的原理,就是在运行它时,执行下列流程:
①首先到node_modules/.bin路径检查npx后的命令是否存在,找到之后执行;
②找不到,就去环境变量$PATH里面,检查npx后的命令是否存在,找到之后执行;
③还是找不到,自动下载一个临时的依赖包最新版本在一个临时目录,然后再运行命令,运行完之后删除,不污染全局环境。
3.only-allow
团队协作开发项目,统一包管理器是有必要的,可以防止产生严重的问题, only-allow就是用来强制在项目中使用特定的包管理器。(后续会对它的源代码进行调试分析,明天我将在下一篇文章《only-allow源码调试与分析》中发表)
4.pnpm
pnpm 是新一代的包管理工具,号称是最先进的包管理器。按照官网说法,可以实现节约磁盘空间并提升安装速度和创建非扁平化的 node_modules 文件夹两大目标,具体原理可以参考 pnpm 官网。