如何阻止npm从私有GitHub仓库安装时因prepare脚本安装devDependencies?
你当前的问题是:通过npm install --omit=dev github:name/personnal-project#feat/test安装私有GitHub仓库时,尽管指定了忽略dev依赖,但因为仓库的package.json里有prepare脚本(执行npm run build),npm会自动安装devDependencies来完成脚本执行,而这些依赖对生产环境没用。同时你无法发布包到npm/GitHub注册表,也没法通过GitHub Release安装二进制文件,以下是几个可行的解决办法:
方案一:让prepare脚本仅在本地开发时执行
prepare脚本会在npm安装(包括安装依赖包的场景)、npm publish等场景触发,导致npm必须安装dev依赖来执行build。我们可以修改脚本,只在本地git仓库环境下才执行build:
修改私有仓库的package.json中scripts字段:
"scripts": { "prepare": "if [ -d .git ]; then npm run build; fi", "build": "rollup -c", "dev": "rollup -c -w", "start": "sirv public --dev", "prettify": "prettier --write --list-different .", "lint": "eslint --fix ." },
如果需要兼容Windows环境,可以用Node.js脚本判断:
"scripts": { "prepare": "node -e \"const fs = require('fs'); process.exit(fs.existsSync('.git') ? 0 : 1)\" || npm run build", // 其他脚本不变 }
原理:npm从git仓库拉取代码并安装时,不会保留.git目录,因此prepare脚本不会执行build,也就不需要安装dev依赖。而本地开发时,因为存在.git目录,prepare会自动执行build,不影响开发流程。
方案二:提前预编译并跳过脚本执行
- 在私有仓库的
feat/test分支上,手动执行npm run build生成编译文件,然后把public/build/目录的文件提交到分支上; - 安装时加上
--ignore-scripts参数,阻止npm执行prepare脚本:
npm install --omit=dev --ignore-scripts github:name/personnal-project#feat/test
这个方法的核心是提前把编译产物提交到仓库,让npm直接安装已有的编译文件,不需要在安装过程中执行build,自然也就不需要安装dev依赖。
方案三:拆分脚本,避免安装时触发build
把原来的prepare脚本替换为仅本地开发时触发的脚本,比如postinstall,并添加条件判断:
修改私有仓库的package.json:
"scripts": { // 移除原来的prepare脚本,添加带条件的postinstall "postinstall": "if [ \"$npm_config_omit\" != \"dev\" ]; then npm run build; fi", "build": "rollup -c", // 其他脚本不变 },
这样,当你在本地执行npm install(不带--omit=dev)时,会自动执行build;而安装依赖时用--omit=dev,postinstall脚本会跳过build,npm也就不会安装dev依赖。
内容的提问来源于stack exchange,提问作者Lo Bellin

