preinstall钩子
Vue3 源码用了 npm 的 preinstall 钩子 约束,只能使用 pnpm 安装依赖。
npm钩子文档
// vue-next/package.json{"private": true,"version": "3.2.22","scripts": {"preinstall": "node ./scripts/preinstall.js",}}
npm run preinstall后先运行preinstall.js,然后运行了install.js,最后是postinstall.js
preinstall.js
// vue-next/scripts/preinstall.jsif (!/pnpm/.test(process.env.npm_execpath || '')) {console.warn(`\u001b[33mThis repository requires using pnpm as the package manager ` +` for scripts to work properly.\u001b[39m\n`)process.exit(1)}
process.argv 属性返回一个数组,由命令行执行脚本时的各个参数组成。它的第一个成员总是 node,第二个成员是脚本文件名,其余成员是脚本文件的参数。
console.log(process.argv)/*['C:\\nodejs\\node.exe','D:\\CS\\Repositories-self\\源码共读\\only-allow-analysis\\1.js']*/console.log(process.env)// 返回一个对象 包含本机环境的一些熟悉,全大写常量
可以在本地新建一个环境变量NODE_ENV,用它确定当前所处的开发阶段,生产阶段设为production,开发阶段设为develop或staging,然后在脚本中读取process.env.NODE_ENV即可。
NODE_ENV=production node app.js
要过一会才生效console.log(process.env.NODE_ENV)
process对象
Only allow pnpm
只需要在package.json添加,就可以避免使用其他包管理器,使用了就报错。
{"scripts": {"preinstall": "npx only-allow pnpm"}}

写一个自己的only-allow
require只能导入CJS的包,注意一些包旧版本用CJS,新版本用ESM
import whichPMRuns from 'which-pm-runs'import boxen from 'boxen'const argv = process.argv.slice(2) // ['node' 'my-only-allow' 'pnpm']if (!argv.length) {console.log('please specitfy the package manager you want to use: pnpm | yarn | npm')process.exit(1)}// 想要约束的包管理器 'pnpm'const wantedPM = argv[0]if (wantedPM !== 'pnpm' && wantedPM !== 'yarn' && wantedPM !== 'npm') {console.log('Then packge manager specified is invalid , only allow pnpm | yarn | npm')process.exit(1)}// { name: 'yarn', version: '1.22.18' }const usedPM = whichPMRuns()// 输出警告if (usedPM && usedPM.name !== wantedPM) {const boxOptions = { borderColor: 'red', borderStyle: 'double', padding: 1 }switch (wantedPM) {case 'pnpm':console.log(boxen(`please use pnpm`, boxOptions))breakcase 'yarn':console.log(boxen(`please use yarn`, boxOptions));breakcase 'npm':console.log(boxen(`please use npm`, boxOptions));break}process.exit(1)}
npx
npx运行的时候,自动去node_modules/.bin路径和环境变量中里面检查命令是否存在。

