从Git仓库安装私有npm组件库时,如何跳过非构建必需的依赖?
首先得理清核心原因:你遇到的devDependencies被全部安装的情况,是因为从Git仓库安装包时,npm默认会执行包的prepare脚本(如果你的组件库package.json里有这个脚本的话)。而prepare通常用来构建包(比如你的tsc -d),npm为了能运行这个脚本,会先安装所有devDependencies——哪怕其中大部分和构建无关。
下面给你几个实用的解决方案,按推荐程度排序:
1. 预构建组件库并提交构建产物(最优解)
既然你的组件库构建只需要typescript和类型声明,那最简单的办法就是提前把构建好的产物提交到Git仓库,这样npm安装时就不需要在本地构建,自然也不会安装那些多余的devDependencies了。具体步骤:
- 在组件库本地运行
tsc -d,生成构建产物(比如dist目录) - 修改
.gitignore,把dist目录从忽略列表中移除,然后提交dist到Git仓库 - 更新组件库的
package.json,把入口指向构建后的文件:{ "main": "./dist/index.js", "types": "./dist/index.d.ts" } - 移除
package.json里的prepare脚本(如果有的话)——因为现在已经预构建好了,不需要在安装时再执行构建 - 提交所有更改到Git,然后在你的两个React项目里更新组件库的commit ref,重新安装试试。这时候npm会直接拉取预构建好的文件,不会再安装那些jest、storybook之类的冗余依赖了。
2. 拆分devDependencies为构建必需和开发工具两类
如果不想预构建,你可以把组件库的devDependencies拆成两部分:
- 把构建必需的依赖(比如
typescript)留在devDependencies里,保证npm安装时能执行prepare脚本 - 把jest、storybook这些仅用于组件库开发的工具,放到一个自定义的字段里,比如
devDependencies-dev
示例组件库package.json:
{ "devDependencies": { "typescript": "^5.2.2" }, "devDependencies-dev": { "jest": "^29.7.0", "@testing-library/react": "^14.0.0", "storybook": "^7.4.6" }, "scripts": { "install-dev": "npm install && npm install --save-dev ${npm_package_devDependencies_dev[@]}" } }
这样,当你开发组件库时,只需要运行npm run install-dev就能安装所有开发工具;而你的React项目安装这个组件库时,只会安装devDependencies里的typescript,其他冗余依赖不会被拉取。
3. 不推荐的方案:peerDependencies或optionalDependencies
你提到的把非必需依赖移到peerDependencies并标记可选的方案其实不太合适——peerDependencies是用来声明宿主项目需要提供的依赖,而这些jest、storybook是组件库自己的开发工具,宿主项目根本不需要它们,这样做只会给宿主项目带来不必要的依赖警告。
至于optionalDependencies,npm默认还是会尝试安装这些依赖,只有当安装失败时才会跳过,所以确实解决不了你的问题。
补充:关于--ignore-scripts参数
你也可以尝试在安装组件库时加上npm install --ignore-scripts,这样npm会跳过prepare脚本,但前提是你已经预构建了组件库——否则安装后的包是未构建的源码,根本无法使用。所以这个参数更像是预构建方案的辅助选项,单独用的话风险很高。
内容的提问来源于stack exchange,提问作者Sl4sher

