PS: 自从有了
yarn
, npm的 shrinkwrap 就被抛弃了,推荐大家使用yarn !
对于web developer来说,代码依赖管理一直都是个头疼的问题。自前端代码模块化开发以来,前端依赖管理也从原始的手动加载维护演化为基于模块仓库和工具的自动管理。目前相对比较流行的包管理工具是bower和npm。
bower && npm
bower的完全面向web的包管理工具。本身并不存储模块代码,对包结构也无强制规范。安装的依赖默认存储在bower_components
目录下,存储特点是扁平化的依赖结构,如果依赖库相互之间有版本冲突,bower会提示用户并让用户仲裁版本。
由于本身的设计缺陷无法满足复杂项目的构建需求,bower在社区也越来越不流行,但还有一些依赖只能通过bower安装(比如ember的一些库)。
npm起初是Node.js生态的包管理器,后来随着同构js库的发展,npm已经发展成了JavaScript生态的包管理器。npm模块遵循CommonJS规范,代码统一发布到npm仓库。安装的依赖存储在node_modules
目录下,依赖采用树形结构存放,也就是同一个依赖可能会存在不同的版本,对于web开发者来说要注意代码冗余。
部署版本问题
bower和npm都支持语义化版本号来定义依赖版本。给版本兼容和依赖升级带来一些便利,但也造成了版本的不确定性。在实际开发和部署时,往往会造成开发时和部署时安装的依赖版本不一致,给线上产品带来未知风险。
npm 锁定依赖版本
为此,npm提供了shrinkwrap
命令来解决这个问题。在开发阶段依赖稳定后,运行如下命令:
npm shrinkwrap
npm shrinkwrap--dev//将dev-dependencies计算在内
shrinkwrap会在根目录生成npm-shrinkwrap.json
文件。之后的npm install会参照这个文件的版本来安装。
注意项
- shrinkwrap计算时是根据当前依赖安装的目录结构生成的,如果你不能保证package.json文件定义的依赖与
node_modules
下已安装的依赖是匹配、无冗余的,建议在执行shrinkwrap命令前清理依赖并重新安装(rm -rf node_modules && npm install)或精简依赖(npm prune)。 - 默认情况下,shrinkwrap只计算dependencies依赖,而不计算dev-dependencies,如果在生产环境也需要开发依赖或你的依赖分类不清晰,使用
--dev
参数生成shrinkwrap文件确保不会出问题。 - 如果不需要关注dev-dependencies,建议npm install --production或npm prune --production
bower 锁定版本
bower官方并未提供该功能,这里提供下社区贡献的方案:bower-shrinkwrap-resolver
1.npm install bower -g
2.npm install bower-shrinkwrap-resolver -g
3.添加以下内容到.bowerrc
:
{
"resolvers": [
"bower-shrinkwrap-resolver"
]
}
之后执行bowerinstall,会自动生成bower-shrinkwrap.json
文件。如果需要重新生成,执行bower install --reset-shrinkwrap
。
参考资料
-npm shrinkwrap
-使用npm shrinkwrap来管理项目依赖
-那些年使用npm进行依赖管理所踩的坑
-uber/shrinkwrap