前言
春节期间对博客修修补补,在一次提交中,仅仅修改了一个字段名(date -> createDate),CI 构建突然失败。错误信息如下:
排查问题
1. 分析问题
因为只变更了字段名,没有变更配置文件,于是直接在 Github Action
重新执行历史成功的CI,结果发现也失败。那么定位问题就集中在yml
文件上。
2. 配置分析
frontend-deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v3
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: "21"
- name: Install Dependencies
working-directory: ./frontend
run: |
rm -rf node_modules package-lock.json
npm install
- name: Build
working-directory: ./frontend
run: npm run build
- name: Deploy to server
uses: appleboy/scp-action@master
with:
可以看到在Install Dependencies
环节会删除package-lock.json
在重新 npm install
,结合package.json
文件
"dependencies": {
"@element-plus/icons-vue": "^2.3.1",
"axios": "^1.6.2",
"bignumber.js": "^9.1.2",
"compressing": "^1.5.1",
"core-js": "^3.35.0",
"cors": "^2.8.5",
"cross-env": "^7.0.3",
"dotenv": "^16.3.1",
"element-plus": "^2.4.4",
"express": "^4.21.1",
"normalize.css": "^8.0.1",
"rxjs": "^7.8.0",
"vite": "^5.0.10",
"vue": "^3.4.3",
"vue-router": "^4.2.5",
"md-editor-v3": "5.2.1"
},
"devDependencies": {
"@typescript-eslint/eslint-plugin": "^6.16.0",
"@typescript-eslint/parser": "^6.16.0",
"@vitejs/plugin-vue": "^5.2.1",
"eslint": "^8.56.0",
"eslint-plugin-vue": "^9.19.2",
"sass": "^1.69.5",
"typescript": "^5.3.3",
"unplugin-auto-import": "^0.17.3",
"unplugin-vue-components": "^0.26.0"
},
而npm install + ^
可能会存在依赖问题
^
符号(兼容版本)- 正常版本(≥1.0.0):
"vite": "^4.5.1" // 允许 4.5.1 到 4.99.99
- 0.x 版本:
"pkg": "^0.5.1" // 允许 0.5.1 到 0.5.99
- 0.0.x 版本:
"pkg": "^0.0.1" // 严格锁定到 0.0.1
- 正常版本(≥1.0.0):
使用 npm ci
替代
npm ci 与 npm install有什么区别?
1. 依赖安装方式:
-
npm install
:- 根据 package.json 安装依赖
- 如果有 package-lock.json,会尽量遵循,但可能更新
- 可能更新 package-lock.json
-
npm ci
:- 严格根据 package-lock.json 安装依赖
- 必须有 package-lock.json
- 不会修改 package-lock.json
2. 使用场景:
-
npm install
:- 适用于开发环境
- 当需要添加/更新依赖时使用
- 允许版本范围和依赖更新
-
npm ci
:- 专门为 CI/CD 环境设计
- 用于生产环境构建
- 确保可重现的构建结果
3. 执行过程:
-
npm install
:- 可以单独安装包
- 增量更新 node_modules
- 运行速度相对较慢
-
npm ci
:- 总是删除现有的 node_modules
- 全新安装所有依赖
- 通常比 npm install 快
4. 版本处理:
-
npm install
:{ "dependencies": { "vite": "^5.0.10" // 可能安装 5.0.11 或更高版本 } }
-
npm ci
:// package-lock.json { "dependencies": { "vite": { "version": "5.0.10" // 严格安装这个版本 } } }
新的错误
重新提交,新的错误如下
npm ERR! `npm ci` can only install packages when your package.json and package-lock.json or npm-shrinkwrap.json are in sync. Please update your lock file with `npm install` before continuing.
这个错误说明 package.json 和 package-lock.json 不同步。
解决措施
1. 清理环境
rm -rf node_modules package-lock.json
2. 重新安装并生成 package-lock.json
npm install
重新push问题解决,CI成功。
总结
其实排查这个问题花费了不少时间,绕了几个弯子
- 当时在
Github Action
上看到这个错误日志时,主要去分析了这个问题
Cannot read properties of null (reading 'render')
at ConditionalExpression.render
造成这个问题原因可能有以下几种
- rollup的版本不对,因为将这个问题在Google搜索到的github时基本都是在说rollup的版本不对,原帖关于rollup版本4.16导致render的报错,但检查了我的package.json其实没有用到rollup,但vite内部依赖了rollup,检查了依赖下的rollup版本
npm ls rollup
大于4.17,然后就怀疑是 vite 的版本不对,降级到4.x.x时 CI 也成功了,但我感觉解决的方式偏了,因为之前一直成功的程序,突然说要变更配置文件,这不合理。
ConditionalExpression.render
表示条件渲染的时候出的错,搜索发现说v-if可能存在空值导致的,但我只更改了一个字段名并没有涉及到条件语句的更改,但也尝试修改了一下,果然无效。
最后吸取这次教训,有时候已经有“解决方案”了得思考一下这个解决方案是否合理的。欢迎大家访问我的博客,也提出宝贵的建议