自动化部署,不管是 Jenkins 自动化构建还是 GitLab CI/CD 工具中, 安装前端依赖和构建前端工程必不可少(除非本地打包,上传打包文件方式)。
并不是每次代码变动都需要重新安装依赖,只有在依赖变动的时候才需要。比如新增依赖、删除依赖、依赖升级等。这几种操作都会让 package.json 文件发生变动,所以我们可以通过判断 package.json 文件是否有变动来决定是否需要重新安装依赖。
deploy.sh
# 判断 package.json 是否有变动
if git diff --quiet HEAD@{1} HEAD -- package.json; then
# 如果没有变动,检查是否存在 node_modules 文件夹
if [ ! -d "node_modules" ]; then # 如果不存在,执行 npm install
pnpm install
fi
else
# 如果有变动,执行 npm install
pnpm install
fi
pnpm build
deploy1.sh
为什么会有 deploy1.sh 的诞生(上线后一个月才踩坑),因为 deploy.sh 在执行的时候,正如之前所说,并不是每次都会变动依赖。 假设这样一个场景:我和同事协作开发, 我由于需要,新增了依赖,但是我这个功能不全,需要等到同事那边的功能发完才部署,此时我将代码推送,同事那边一旦发布的版本大于两个 git 提交版本,此时发布这个版本,比对近两次提交并未依赖变动,所以在发布执行 deploy.sh 时, 不会安装我的依赖。就会导致 build 时失败。
当然也可以修复,不写死判断近两次,而是和上一次 package.json 变动的记录对比,感兴趣的让你们的 GPT 员工改动下吧。
# 判断 package.json 是否有变动
if ! npm list --depth=0 >/dev/null 2>&1; then
echo "Some dependencies are missing. Running pnpm install..."
# 执行 pnpm install
pnpm install
else
echo "All dependencies are already installed."
fi
pnpm build
deploy1.sh 换了种思路,利用 npm 的特性。
- npm list 列出所有依赖。
- 并使用重定向操作符将标准输出(stdout)和标准错误输出(stderr)都重定向到 /dev/null,即丢弃输出。
- ! 是一个逻辑非操作符,它的存在用于判断命令是否失败。如果 npm list --depth=0 命令执行失败(即没有返回 0 的退出码),则执行 then 中的代码块。
结束
关于我为啥用了两个方案,一切都是 Chat GPT 的指示,它让我解决问题->出现问题->解决问题,最终才有了这个方案。目前已稳定在生产环境使用大半年。希望能帮助到大家。