在使用 Jenkins 自動化構建 Node.js 項目時,經常會遇到類似報錯:
ERR_PNPM_OUTDATED_LOCKFILE? Cannot install with "frozen-lockfile" because pnpm-lock.yaml is not up to date with package.json
Error: Cannot find module 'node_modules/vite/bin/vite.js'
對于初學者來說,這種報錯可能很迷惑。本文帶你從原理到實操,徹底搞懂問題原因和解決方案。
一、問題現象
在 Jenkins CI 上執行構建任務時,可能出現以下情況:
pnpm install
失敗,報錯:
ERR_PNPM_OUTDATED_LOCKFILE? Cannot install with "frozen-lockfile" because pnpm-lock.yaml is not up to date with package.json
- 構建命令報錯:
Error: Cannot find module 'node_modules/vite/bin/vite.js'
- 打包步驟失敗:
zip warning: name not matched: dist
zip error: Nothing to do!
二、問題根源分析
1. pnpm lockfile 不一致
-
pnpm 使用
pnpm-lock.yaml
來鎖定依賴版本,保證不同環境安裝依賴一致。 -
CI 環境(如 Jenkins)默認啟用
frozen-lockfile
模式,即:- 不會自動修改 lockfile
- 如果
package.json
中新增或修改了依賴,而 lockfile 未更新,就會報錯。
典型場景:
- 本地新增依賴:
pnpm add @zxing/browser jsqr qrcode-decoder quagga
package.json
改了,但pnpm-lock.yaml
沒更新或沒提交到 Git。- Jenkins 在 CI 環境拉取代碼后,執行
pnpm install
時就報錯了。
2. node_modules 缺失
由于 pnpm install
失敗:
node_modules
沒生成完整依賴- 構建工具(如 Vite)找不到模塊:
Cannot find module 'node_modules/vite/bin/vite.js'
- 構建中斷 → 打包 dist 文件失敗
三、解決方案
1. 本地更新 lockfile 并提交(推薦)
- 在本地項目根目錄執行:
pnpm install
- 會根據
package.json
更新pnpm-lock.yaml
。 - 注意不要使用
--frozen-lockfile
,否則不會更新。
- 提交更新:
git add package.json pnpm-lock.yaml
git commit -m "chore: update lockfile after adding new dependencies"
git push
- Jenkins 再次構建:
- CI 拉取最新代碼
pnpm install
會順利安裝依賴- 構建正常 → 打包成功
2. CI 臨時解決方案(不推薦)
如果只是測試或臨時構建,可以在 Jenkins 構建腳本里加:
pnpm install --no-frozen-lockfile
- 會忽略 lockfile 和 package.json 的不一致
- 強制安裝依賴
- ?? 風險:可能導致不同環境依賴版本不一致,不適合長期使用
3. 確保構建路徑正確
在 Jenkins 中,確保工作目錄存在:
cd /var/jenkins_home/workspace/jxc-web
pnpm install
- 如果 workspace 被清理或不存在,會報:
Error: ENOENT: no such file or directory, uv_cwd
- Jenkins job 配置中可以取消“構建前刪除工作區”,或者在構建腳本里自動創建目錄:
mkdir -p /var/jenkins_home/workspace/jxc-web
4. 檢查 Node.js 和 pnpm 版本
確保 Jenkins 使用的 Node.js 與本地一致:
node -v
pnpm -v
不同版本可能導致依賴安裝或 vite 構建失敗。
四、Jenkins 構建推薦流程
一個推薦的 Jenkins 構建腳本:
#!/bin/bash
set -e# 確保工作區存在
mkdir -p /var/jenkins_home/workspace/jxc-web
cd /var/jenkins_home/workspace/jxc-web# 拉取最新代碼
git reset --hard
git clean -fd
git pull origin main# 安裝依賴
pnpm install --frozen-lockfile# 構建項目
pnpm run build:dev# 打包 dist
zip -r dist.zip dist
? 關鍵點:
--frozen-lockfile
保證 CI 與 lockfile 一致- 如果 lockfile 有變動 → 在本地更新并提交
- 確保 workspace 路徑存在,避免
uv_cwd
錯誤 - Node.js、pnpm 版本與本地一致
五、總結
-
Jenkins 不會自動更新 pnpm lockfile → 鎖文件必須與 package.json 保持一致
-
構建失敗 的根本原因是依賴沒裝完整
-
最佳實踐:
- 本地修改依賴后同步更新 lockfile
- 提交到 Git
- CI 使用
--frozen-lockfile
保證環境一致
這樣就可以避免:
ERR_PNPM_OUTDATED_LOCKFILE
Cannot find module 'vite'
- 打包 dist 失敗
小白提示:
每次新增依賴后記得跑
pnpm install
并提交pnpm-lock.yaml
,CI 構建才不會報錯!