支持二级目录部署方案

823 阅读1分钟

原因

  1. 同一套代码,给不同的企业部署在不同的环境,但是域名贵。
  2. 项目里使用的部分购买的第三方库,是根据域名收费的,用二级域名也不行。

结果

基于以上的原因,我们打算用不同的企业通过域名后的一级URL进行区分。

例如:

abc.com.cn/baidu // 这个代表给百度部署的

abc.com.cn/meituan // 这个达标给美团部署的

前端改动

主要是:前端静态资源统一加前缀,不同的企业加不同的前缀;调用接口的时候定义不同的baseUrl,方便nginx代理到各自部署的服务器,连接不同的数据。

  1. 静态资源请求地址加前缀(也就是publicPath和路由的basename)
  2. 修改封装的axios文件给接口调用统一新增baseUrl,这里注意如果是直接引用的axios,所以也要去加上baseUr,以及iframe的src如果是走的反向代理的地址,也需要加上这个baseUrll。

注意:以上内容可以通过配置package.json打包命令配置变量读取到前缀名,加一个新的打包方式build:web,这样如果要改前缀,只需要改一下package.json打包命令的地方,其他地方读取的这里的变量,

    "scripts": {
    "start": "rescripts start",
    "build": "rescripts build",
    "build:web": "rescripts build --mode web$$$",
    "test": "rescripts test",
    "eject": "react-scripts eject"
  },

注意这里用web$$$,是为了不和其他的字符冲突,方便后续批量替换。 然后在配置文件里面去读取一下这个--mode 后面的变量,

let basename = '';
let baseurl = '';
const { argv } = process;
const index = argv.findIndex((arg) => arg === '--mode');
if (index > -1 && argv[index + 1]) {
  // 拼接一下basename
  basename = `/${argv[index + 1]}`;
  baseurl = `/${argv[index + 1]}/server`
}

然后通过webpack.DefinePlugin把这个basename定义成一个全局变量,在修改publicPath和路由的basename,以及接口的baseUrl。这些地方使用这个变量就可以了。

打包

这样,前端执行yarn build:web

部署,nginx配置

以下是基于静态资源前缀为web,baseUrl/web,baseUrl为/web/server/,相关的nginx配置

server {
  listen 8005;
  listen [::]:8005;
  server_name abc.com.cn;
  root /Users/zengxiaobai/projects/dist;
    location /web$$$ {
      # 主应用静态资源路径
      alias /Users/zengxiaobai/projects/dist;
      index index.html index.htm;
      try_files $uri $uri/ /index.html;
    }
  location /nstweb/server/ {
    # 应用接口反向代理
    proxy_pass https://abc.test.cn;
    }
}

运维部署的时候,可以执行以下命令全局替换前缀

find 目录/ -type f -exec sed -i -e "s/原字符串/新字符串/g" {} ;

目录为dist包的地址,原字符串默认为web$$$,新字符串为新增企业的二级目录的名字,运维自行定义,

比如以下命令为我要把dist下面的主应用的所有文件夹前缀为nstweb改为baidu:

find /Users/zengxiaobai/projects/dist/ -type f -exec sed -i -e "s/web$$$/baidu/g" {} ;