AriaNg 编译失败!关于 lockfile的简单了解
今天把AriaNg拉了下来,关于 lockfile 的简单了解
今天闹了个乌龙.
把 AriaNg 项目拉下来编译,结果报错了.我以为发现了项目的 bug,兴冲冲地提了 issue 和 PR,结果最后发现是我自己的问题 -- 因为我用 pnpm 去编译一个 npm 项目.
事情经过
把项目拉下来之后,习惯性地用 pnpm install 安装依赖,然后 pnpm build 构建,结果上来就炸了:
[23:05:07] Error in plugin "gulp-cssnano"
Message:
Option safe was removed. Use parser: require("postcss-safe-parser")
cssnano 的 safe 选项被移除了?
我第一反应是:这项目有 bug 啊!
进行反馈
仔细看了一下报错,感觉问题很明确:cssnano 新版本移除了 safe 参数,需要换成 preset: 'default'.
于是我: 提交了 issue #828,顺手改了代码,提了对应的 PR
当时还觉得自己挺厉害,发现问题还顺手修复了.
问题没有这么简单
提交之后,维护者回复说:我这边复现不了啊.
他用 docker + npm 跑了一遍,完全正常.
我就纳闷了,同样的代码,为什么我这边就报错?
自己观察作者发的日志可以看出来,项目用的是 npm,有 package-lock.json,但我用的是 pnpm 安装的...
pnpm 会忽略 npm 的 lockfile 啊!
真正的原因
原因找到了:
| 步骤 | npm (正确) | pnpm (我用的) |
|---|---|---|
| 读取 lockfile | package-lock.json |
无视,自己解析 |
| 依赖版本 | 严格锁定 | 拉取最新兼容版 |
| cssnano 版本 | 旧版 (有 safe 参数) |
新版 (safe 被移除) |
因为 pnpm 不识别 npm 的 package-lock.json,所以它按照 package.json 里的版本范围,拉了最新的 cssnano.而新版 cssnano 正好做了不兼容变更,把 safe 参数干掉了.
所以根本不是项目的 bug,是我自己操作不对.
关于 lockfile 的一点认识
这次事件给我上了一课:
不同包管理器的 lockfile 不通用
| 包管理器 | lockfile | 说明 |
|---|---|---|
| npm | package-lock.json |
npm 官方格式 |
| pnpm | pnpm-lock.yaml |
pnpm 自有格式 |
| yarn | yarn.lock |
yarn 自有格式 |
以前总觉得 npm/pnpm/yarn 大部分时候都互相兼容,随便用哪个都行.这次才发现,这个 lockfile 是各玩各的,不能直接用.
lockfile 的意义
lockfile 存在的意义就是锁定依赖版本,保证每个人、每次安装的依赖都是完全一样的.
没有 lockfile (或者 lockfile 不被识别) 的话:
-
依赖版本可能漂移
-
哪天某个依赖发了个 breaking change,你的项目就炸了
-
这就是为什么 "我本地好好的,到线上就挂了" 的经典问题
教训
还是需要注意,使用项目原配的包管理器的
不要想当然以为都一样 ,大部分时候确实能跑,但出问题的时候,往往就是这些 "小细节" 导致的
后续
这个细节问题,我还是第一次遇见的说.没想到pnpm竟然还是有和npm不兼容的地方.
那个 PR 嘛... 虽然初衷是好的,但确实是我操作不当导致的.
不过话说回来,safe 选项被移除也是事实,等以后 cssnano 真的升级了,这个问题还是会出现的.所以这个 PR 说不定也不算完全没用?
就当是提前适配了吧.