掘金文章归档 · 第 88 篇 工程化 · 部署 4/4

vite 前端项目配置文件,解决打包一次、多服务器部署

public/settings.js 抽离配置 + prebuild 脚本替换生产配置,一次构建多环境生效

原文作者:随意_(掘金) | juejin.cn/post/7348994520589860890 | 发布于 2024-03-22 | 阅读 2,152 · 约 2 分钟

0背景

公司一个项目,会部署多台服务器,如演示环境、预生产、开发环境等等,总之环境个数很多。我们不能每次部署都 npm run build 一次,我们需要抽出一个配置项:打包一次,交给运维,运维部署只需要修改配置项中的对应 key 即可。

1何为前端配置项

举个例子,比如系统的 title、系统请求的根路径 baseAPI、文件服务器的根路径、地图服务路径、演示的模拟用户信息等,如下:

const defaultSettings = {
  minioBase: "http://baidu.com/minio/cestc-xingzhi-bucket", // minio路径
  baseApi: "/api", // 接口的base路径 开发为/api 生产可替换
  title: '测试的系统',
  defaultUser: '张三',
  mapUrl: '地图服务'
};

我们现在做的,就是将系统配置项抽离出来成单独文件,打包一次后,要运维修改对应配置,就可以部署多台服务器。

2以 VITE 为例(vue、react 均适用)

首先我们在 public 目录下,创建 settings.js 并写入配置项(如上方 defaultSettings),在 index.html 中引入,代码结构如下:

<!DOCTYPE html>
<html lang="zh-CN">
  <head>
    <meta charset="UTF-8" />
    <title>测试的系统</title>
    <script src="./settings.js"></script>
  </head>
  <body>
    <div id="root"></div>
  </body>
</html>

3代码中如何使用配置项

直接使用即可:

// 全局可访问 defaultSettings 变量
console.log(defaultSettings.baseApi)
console.log(defaultSettings.title)

如果使用 ts 报错,可根目录增加 global.d.ts 文件,并写好类型:

declare const defaultSettings: {
  minioBase: string
  baseApi: string
  title: string
  defaultUser: string
  mapUrl: string
}
⚠️ 如果此时 ts 仍然报错,查看 tsconfig.json 是否包含此类型文件。

4settings.js 替换为生产配置

如果频繁部署某一个环境:开发环境使用 settings.js 配置,生产配置的配置项有区别,不能频繁修改打包好的 settings.js。这时我们创建一个 settings-prod.js,每次 build 的时候写一个脚本,将 settings.js 中的内容替换为 settings-prod.js 的(当然这是一个实现思路,也可以 nginx 配置做代理,每次访问 settings.js 映射到服务器的系统配置路径)。

1. 创建文件

在 public 创建 settings-prod.js,在根目录创建 replace-settings.js(执行脚本),代码结构如下:

2. replace-settings.js 中代码脚本

作用是替换 settings 中的内容:

// replace-settings.js
import { readFile, writeFile } from "node:fs/promises";
import path from "node:path";
import { fileURLToPath } from "node:url";

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

const settingsProdPath = path.join(__dirname, "public", "settings-prod.js");
const settingsPath = path.join(__dirname, "public", "settings.js");

async function replaceSettings() {
  try {
    const data = await readFile(settingsProdPath, "utf8");
    await writeFile(settingsPath, data, "utf8");
    console.log("replaced");
  } catch (err) {
    console.error("no replaced", err);
  }
}

replaceSettings();

3. 配置 package.json

最后配置下 package.json,每次 build 需要先替换文件内容,再打包:

"scripts": {
  "dev": "vite",
  "prebuild": "node replace-settings.js",
  "build": "npm run prebuild && vite build",
  "lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
  "preview": "vite preview",
  "preinstall": "npx only-allow pnpm"
}
文件作用
public/settings.js开发环境配置,浏览器直接读取
public/settings-prod.js生产配置模板,供替换
replace-settings.jsbuild 前用 prod 内容覆盖 settings.js
📌 打包一次、多服务器部署:运维只需修改服务器上 settings.js 中对应 key,无需重新构建。