前端自动化编译Jenkins

1. Windows安装虚拟机

下载 VMware Workstation

2. 下载 Ubuntu 镜像

Ubuntu 24.04.4 LTS

3. 创建虚拟机选择镜像

查看网络:输入 ip a
成功标志:看到 ens33 下面有了 inet 192.168.1.x 这样的真实 IP!

如果你之后需要用 Xshell、终端远程连接这台 Ubuntu:保留勾选「Install OpenSSH server」,密码认证也保持勾选即可

4. SSH 远程连接

在现有 Ubuntu 终端输入:

sudo apt update
sudo apt install openssh-server -y

启动并设置开机自启:

sudo systemctl start ssh
sudo systemctl enable ssh

确认 SSH 运行:

sudo systemctl status ssh

看到 active (running) 就 ok。

确认虚拟机 IP

hostname -I

使用 MobaXterm 连接虚拟机

5. 本地极简安装 Jenkins

直接用 Ubuntu 系统自带包安装 Jenkins(彻底避开 Docker 网络问题)

# 先更新软件源
sudo apt update

# 直接安装 OpenJDK(Jenkins 依赖)
sudo apt install openjdk-17-jdk -y

# 添加 Jenkins 官方源密钥
curl -fsSL https://pkg.jenkins.io/debian-stable/jenkins.io-2023.key | sudo gpg --dearmor -o /usr/share/keyrings/jenkins-keyring.gpg

# 添加 Jenkins 软件源
echo "deb [signed-by=/usr/share/keyrings/jenkins-keyring.gpg] https://pkg.jenkins.io/debian-stable binary/" | sudo tee /etc/apt/sources.list.d/jenkins.list

# 安装 Jenkins
sudo apt update

### 极简兜底方案(国内可用、一步到位)

#### 1. 先清理无效源

```bash
sudo rm /etc/apt/sources.list.d/jenkins.list

2. 直接用Jenkins 国内离线包 安装,彻底绕开源问题

Jenkins 最新版最低要求 Java 21 / 25,升级系统 Java 到 21

sudo apt install openjdk-21-jdk -y

# 设置默认Java版本
sudo update-alternatives --config java

# 下载Jenkins稳定版war包
wget https://mirrors.tuna.tsinghua.edu.cn/jenkins/war-stable/latest/jenkins.war

# 重新启动现有war包即可
java -jar jenkins.war --httpPort=8080

3. 直接启动运行(无需 Docker、无需系统服务)

nohup java -jar jenkins.war --httpPort=8080 > jenkins.log 2>&1 &

6. 配置 Jenkins

1. 必备插件安装

登录 Jenkins → 左侧「系统管理」→「插件管理」→「可选插件」,搜索并安装:

  • Git Plugin (拉取代码)
  • NodeJS Plugin (前端编译环境)
  • 配置 Node.js

    • 找到 NodeJS → 点击 新增NodeJS
    • 自定义名称:node20
    • 勾选 Install automatically
    • 版本选:20.x.x
    • 保存
  • 配置 git

    • 进入 Manage Jenkins(系统管理)
    • 进入 Global Tool Configuration(全局工具配置)
    • 找到 Git
    • 点击 Add Git
    • Name 填:git
    • Path to Git executable 填:/usr/bin/git
    • 保存

2. 新建前端构建任务(核心)

新建任务

  • 首页 → 新建任务
  • 名字:前端自动打包
  • 选择:自由风格项目 (Freestyle)
  • 确定

开启「自定义脚本选择」(最关键)

勾选:

This project is parameterized

点击 Add Parameter → Choice Parameter

按下面填写:

  • Name :
RUN_SCRIPT
  • Choices一行一个 ,对应你 package.json 的 scripts):
build:LNFX
build:LNSY
build:YN
build:EW
build:EA
build:YD
build:GN
build:AHJD
build:GJDT
build:GJDTDB
build:GJDTNM
build:GJDTSX
build:GJDTXA
build:DT
build:DTAH
build:DTJS
build:DTSH
build:JDCC
build:YN2
build:DTXJHM
build:GSZDJ
build:DTHN
build:DTTKT
build:LNDT
build:JXDTJK
build:ZDJGYY
build:ZJJK
build:DTGDZQ
build:GDTWCJK
build:HNYNJK
  • Description :
选择要执行的命令

源码管理(拉代码)

  • Git

  • Repository URL:填你的 Gitee/GitHub 仓库地址

  • Credentials:添加你的仓库账号密码(personal_access_tokens->read_repository权限)

  • Branch*/main*/master

构建环境

  • 勾选:Provide Node & npm bin/ folder to PATH
  • 选择:node20

Triggers(自动触发 + 定时检测)

  • 只勾选这一项:

Poll SCM

  • Schedule 填写(直接复制):
H/2 * * * *

构建步骤(最重要!)

  • 增加构建步骤 → 执行 shell

  • 粘贴下面这段通用前端自动化打包脚本 (直接复制):

#!/bin/bash
set -e
# 1. 兼容老项目
export NODE_OPTIONS=--openssl-legacy-provider
# 🔥 强制关闭所有编译检查(关键)
#export DISABLE_ESLINT_PLUGIN=true
#export ESLINT_NO_DEV_ERRORS=true
#export VUE_CLI_SERVICE_NO_ERRORS=true

# 还原正确的 package.json(echarts 4.9.0)
git checkout -- package.json

# 2. 国内镜像
#npm config set registry https://registry.npmmirror.com

# ==========================================
# 🔥 核心:安装时 跳过二进制编译(解决 mozjpeg 报错!)
# 以后加新包也能正常装,同时不炸图片压缩
# ==========================================
install_deps() {
  # --- 1. 仅清理旧的构建产物 ---
  # 这一步必须保留,防止旧代码影响新包
  echo "清理旧的构建产物..."
  rm -rf dist
  rm -rf 70*_dist* # 清理历史文件夹
  rm -f *.zip       # 清理旧压缩包

  # 1. 彻底删除可能导致冲突的旧缓存和目录
  #rm -rf node_modules
  #rm -rf package-lock.json
  #rm -rf .cache
  #rm -rf node_modules/.cache

  # 2. 清理 npm 全局缓存(防止损坏的包反复被调用)
  #npm cache clean -f

  # 3. 重新设置镜像源
  npm config set registry https://registry.npmmirror.com

  echo "正在安装依赖..."

  # 4. 关键:移除 --ignore-scripts!
  # 如果是因为某个特定包(如 mozjpeg)报错,我们应该针对性解决,而不是全局跳过脚本。
  # 使用 --legacy-peer-deps 处理 Vue2/3 依赖冲突问题
  npm install --legacy-peer-deps

  # 5. 特殊处理 node-sass (如果你的项目还在用它)
  # 很多时候 node-sass 需要手动触发一次 rebuild 才能在 Linux 环境跑通
  if [ -d "node_modules/node-sass" ]; then
    echo "检测到 node-sass,尝试重新构建二进制文件..."
    npm rebuild node-sass
  fi
}

# 每次都执行(新加包能装上)
install_deps

# ====================== 构建逻辑 ======================
# 1. 这里的 DATE 必须和 Node 脚本里的 formattedDate 逻辑完全一致
DATE=$(date +%Y%m%d)
# 2. 这里的项目前缀获取逻辑 (假设你的 RUN_SCRIPT 是 build:LNFX)
# 我们把 build: 后面的名字取出来
PROJECT_NAME=$(echo ${RUN_SCRIPT} | cut -d':' -f2)

# 3. 这里的目录名必须和你的 setup.js 逻辑完全同步:70 + 项目名 + _dist + 日期
DIR_NAME="70${PROJECT_NAME}_dist${DATE}"

echo "====================================="
echo "🚀 预期构建目录: ${DIR_NAME}"
echo "====================================="

echo "====================================="
echo "🚀 开始构建:npm run ${RUN_SCRIPT}"
echo "====================================="

# 在 echo "🚀 预期构建目录: ${DIR_NAME}" 下方加入
if [ -z "${PROJECT_NAME}" ]; then
    echo "❌ 错误:无法从 RUN_SCRIPT (${RUN_SCRIPT}) 中提取项目名称!"
    exit 1
fi

npm run ${RUN_SCRIPT}

# 5. 【关键修复】打包逻辑
# 不再写死 if/else,直接根据上面生成的 DIR_NAME 去找
if [ -d "${DIR_NAME}" ]; then

```bash
echo "✅ 找到目录 ${DIR_NAME},开始压缩..."
rm -f *.zip
zip -r "${DIR_NAME}.zip" "${DIR_NAME}"
echo "✅ 成功生成压缩包: ${DIR_NAME}.zip"
else
    # 容错:打印当前目录下的所有文件夹,方便调试
    echo "❌ 错误:未找到目录 ${DIR_NAME}"
    echo "当前目录下存在的目录有:"
    ls -d */
    exit 1
fi

构建后操作(实现下载)

  • 增加构建后操作 → Archive the artifacts
  • Files to archive 里填:
70*_dist*.zip

7. 编译与下载

image.png

status产物下载,consoleOutput日志查看

8. 其他报错

安装zip

sudo apt update && sudo apt install zip -y

图片压缩 依赖的系统库

sudo apt-get update
sudo apt-get install -y autoconf automake libtool libpng-dev libjpeg-dev gcc g++ make

服务器证书验证失败(因为你的 GitLab 是私有地址、自签名证书,Git 默认不让拉)关闭 Git SSL 验证

git config --global http.sslVerify false
git config --global https.sslVerify false

Waiting for next available executor

1. 之前的失败任务卡住了“工位”

虽然任务显示失败了,但有时进程可能在后台挂起,占用了执行器。

  • 解决方法
    • 看看左侧栏的 “Build Executor Status” (构建执行状态)。
    • 如果有任务正在运行且进度条不动,点击旁边的 红色小叉叉 强制停止它。

2. 默认并发设置太低

Jenkins 默认可能只设置了 1 个或 2 个执行器。如果你之前的任务还在“取消中”或者有其他任务在排队,它就会显示等待。

  • 手动增加执行器数量
    1. 点击左侧的 Manage Jenkins (管理 Jenkins)。
    2. 点击 Nodes (节点管理,旧版本叫 Manage Nodes and Clouds)。
    3. 点击列表中的 Built-In Node (或者名为 master 的节点)旁边的 齿轮(Configure)
    4. 找到 Number of executors (执行器数量),把它从 1 或 2 改成 5
    5. 点击 Save

重启jenkins

pkill -f jenkins 
pkill -f java
nohup java -jar /home/wzy/jenkins.war --httpPort=8080 > /dev/null 2>&1 &

VMware 扩容

sudo lvextend -l +100%FREE /dev/mapper/ubuntu--vg-ubuntu--lv
sudo resize2fs /dev/mapper/ubuntu--vg-ubuntu--lv

局域网共享

如果虚拟机网络是192的地址,可以共享,但是出现了build失败,因为无法连接外网下载npm包

所以在电脑通过一个node服务接收局域网访问与转发

const express = require('express');
const { createProxyServer } = require('http-proxy');

const app = express();
// 创建一个代理实例
const proxy = createProxyServer({});

// 目标:你的 Ubuntu 虚拟机地址
const TARGET_URL = 'http://172.26.215.195:8080';

console.log(`🚀 正在启动转发服务...`);

### 代码示例

```javascript
console.log(👉 外部访问: http://192.168.188.43:8080);
console.log(👉 内部转发: ${TARGET_URL});

// **核心转发逻辑**
app.use((req, res) => {
  // 修改请求头,让 **Jenkins** 以为请求是直接发给它的
  req.headers.host = '172.26.215.195:8080';

  proxy.web(req, res, { target: TARGET_URL }, (err) => {
    console.error('转发错误:', err);
    res.status(500).send('转发到虚拟机失败,请检查虚拟机是否开启');
  });
});

// 监听 **8080** 端口
app.listen(8080, '0.0.0.0', () => {
  console.log('✅ 代理服务已就绪,等待同事连接...');
});