npm ci;peerDependencies的作用;lock文件提交与否;xxxDependencies;
疑问
- jenkins上直接用npm ci是否比yarn install的打包时间更快?
还是那个g6装包问题,g6如果需求某个版本的tslib,是否是g6自身的问题?
所谓CI环境,应该是指类似jenkins上的包管理问题
- 如果 package-lock.json 和 npm-shrinkwrap.json 同时存在于项目根目录,package-lock.json 将会被忽略。
-
npm ci
npm ci 就是专门为 CI 环境准备的安装命令
npm ci相比npm install的不同之处
为什么单一的package.json文件不能确定唯一的依赖树
- 不同版本的npm的装包策略不同
- package.json指定的是范围,某些依赖可能更新了更新的版本
是否要提交lock文件
dependencies项目依赖
- 这些依赖都会成为线上生产环境中的代码组成部分。
- 会被下载!
- devDependencies 开发依赖
- 不会被自动下载
- 一般只在开发阶段起作用或只是在开发环境中需要用到
- 为辅助开发的工具包
- 比如 Webpack,预处理器 babel-loader、scss-loader,测试工具……
- peerDependencies 同版本依赖
- 如果你安装我,那么你最好也安装我对应的依赖。
- 使用场景
- 我是插件,我不能独立运行
- 我运行需要的核心库在peerDependencies里
- 我不希望核心库被重复下载
- bundledDependencies 捆绑依赖
- 和 npm pack 打包命令有关
- 指定的依赖包,必须先在 dependencies 和 devDependencies 声明过
optionalDependencies 可选依赖
- 不建议使用,会增加项目的复杂度和不确定性
- 你可以安装我,也可以不安装,佛系。
依赖管理实例
如何保证依赖包之间的强制最低版本要求?
create-react-app会对项目中的核心依赖进行检索,不符合会直接退出。 ```javascript // 下面的代码是node.js代码,管中窥豹,可以看出node.js在前端担任的角色。 // 值得细读,对依赖包的版本管理的复杂性、重要性会有更深的理解。 function verifyPackageTree() { const depsToCheck = [ ‘babel-eslint’, ‘babel-jest’, ‘babel-loader’, ‘eslint’, ‘jest’, ‘webpack’, ‘webpack-dev-server’, ];
const getSemverRegex = () => /\bv?(?:0|[1-9]\d).(?:0|[1-9]\d).(?:0|[1-9]\d)(?:-[\da-z-]+(?:.[\da-z-]+))?(?:+[\da-z-]+(?:.[\da-z-]+)*)?\b/gi; const ownPackageJson = require(‘../../package.json’); const expectedVersionsByDep = {}; depsToCheck.forEach(dep => { const expectedVersion = ownPackageJson.dependencies[dep]; if (!expectedVersion) {
throw new Error('This dependency list is outdated, fix it.');
} if (!getSemverRegex().test(expectedVersion)) {
throw new Error(
`The ${dep} package should be pinned, instead got version ${expectedVersion}.`
);
} expectedVersionsByDep[dep] = expectedVersion; });
let currentDir = __dirname;
while (true) { const previousDir = currentDir; currentDir = path.resolve(currentDir, ‘..’); if (currentDir === previousDir) {
// We've reached the root.
break;
}
const maybeNodeModules = path.resolve(currentDir, ‘node_modules’); if (!fs.existsSync(maybeNodeModules)) {
continue;
}
depsToCheck.forEach(dep => {
const maybeDep = path.resolve(maybeNodeModules, dep);
if (!fs.existsSync(maybeDep)) {
return;
}
const maybeDepPackageJson = path.resolve(maybeDep, 'package.json');
if (!fs.existsSync(maybeDepPackageJson)) {
return;
}
const depPackageJson = JSON.parse(
fs.readFileSync(maybeDepPackageJson, 'utf8')
);
const expectedVersion = expectedVersionsByDep[dep];
if (!semver.satisfies(depPackageJson.version, expectedVersion)) {
console.error(//...);
process.exit(1);
}
最佳实践
优先使用 npm v5.4.2 以上的 npm 版本
- 提交 package.json、lock文件
- 版本升级
- 依靠 npm update 命令升级到新的小版本
- 依靠 npm install @ 升级大版本
- 任何团队成员有更包操作,其他成员在拉取代码后,需执行install更新依赖
- 任何时候都不要手动修改lock文件