VUE CLI -全局 CLI 配置

1,002 阅读4分钟

vue.config.js

vue.config.js是一个可选的配置文件,如果项目的 (和 package.json 同级的) 根目录中存在这个文件,那么它会被 @vue/cli-service 自动加载。你也可以使用 package.json 中的 vue 字段,但是注意这种写法需要你严格遵照 JSON 的格式来写。

这个文件应该导出一个包含了选项的对象:

// vue.config.js

/**
 * @type {import('@vue/cli-service').ProjectOptions}
 */
module.exports = {
  // 选项...
}

或者,你也可以使用 @vue/cli-service 提供的 defineConfig 帮手函数,以获得更好的类型提示:

// vue.config.js
const { defineConfig } = require('@vue/cli-service')

module.exports = defineConfig({
  // 选项
})

publicPath

  • Type: string
  • Default: '/' 一般情况下,在项目代码内是会有
  • .env.dev
  • .env.st
  • .env.production
  • .env.uat 四个文件,分别对应四个环境的环境变量,publicPath就是为了指定不同环境下的后端域名地址,这些配置文件主要是替换掉全局的process的env,通过在不同文件中配置不同的环境变量。
module.exports = {
  publicPath: process.env.VUE_APP_PUBLIC_PATH
}

关于文件名:必须以如下方式命名,不要乱起名,也无需专门手动控制加载哪个文件

  • .env 全局默认配置文件,不论什么环境都会加载合并
  • .env.development 开发环境下的配置文件
  • .env.production 生产环境下的配置文件 关于文件内容:

注意:属性名必须以VUE_APP_开头,比如VUE_APP_XXX

NODE_ENV='production' 
VUE_APP_BASE_URL = 'http://99.15.222.110:8080' 
VUE_APP_PUBLIC_PATH = 'http://99.15.222.110:8080'

关于文件的加载:

根据启动命令vue会自动加载对应的环境,vue是根据文件名进行加载的,所以上面说“不要乱起名,也无需专门控制加载哪个文件”

比如执行npm run serve命令,会自动加载.env.development文件 在package.json中配置scripts

"scripts": {
    "dev": "vue-cli-service serve --mode development",
    "build:dev": "vue-cli-service build --mode dev",
    "build:st": "vue-cli-service serve --mode st",
    "build:uat": "vue-cli-service serve --mode uat",
    "build:prod": "vue-cli-service serve --mode production",
    "lint": "vue-cli-service lint"
}

devServer

  • Type: Object

    所有 webpack-dev-server 的选项都支持。注意:

    • 有些值像 hostport 和 https 可能会被命令行参数覆写。
    • 有些值像 publicPath 和 historyApiFallback 不应该被修改,因为它们需要和开发服务器的 publicPath 同步以保障正常的工作。

基本用法

mmodule.exports = {
  //...
  devServer: {
    proxy: {
      '/api': 'http://localhost:3000'
    }
  }
};
请求到 /api/xxx 现在会被代理到请求 http://localhost:3000/api/xxx, 
例如 /api/user 现在会被代理到请求 http://localhost:3000/api/user

devServer.proxy反向代理地址模糊相似规则

例如项目中有两个反向代理如下:
A: http://192.168.1.100:80
B: http://192.168.1.135:80
我们忽略端口,此时A、B分别代理不同的服务器 我们给代理地址添加一下这样的别名如下:

proxy: {
  '^/api': {
    target: 'http://192.168.1.100:80', // A Server
    changeOrigin: true,
    secure: false,
    pathRewrite: {'^/api': ''}
  },
  '^/apihrp': {
    target: 'http://192.168.1.135:80', // B Server
    changeOrigin: true,
    secure: false,
    pathRewrite: {'^/apihrp': ''}
  }
}
上面的参数列表中有一个changeOrigin参数, 是一个布尔值, 
设置为true, 本地就会虚拟一个服务器接收你的请求并代你发送该请求。

默认情况下,不接受运行在 HTTPS 上,且使用了无效证书的后端服务器。
如果你想要接受,只要设置 secure: false 就行。

/api 代理A服务器下的/api地址

/apihrp 代理B服务器下的/apihrp地址

但是如果按此顺序添加,这里呢有个隐藏的命名规则的坑地址模糊相似 假设当我们访问/apihrp/abc时,也就是真实地址B服务器/apihrp/abc。 此时Webpack 会优先匹配到 /api, 然后找到/api的代理配置 最终生成地址 A服务器/api/abc。

这里可能会问为什么不是 地址/apihrp/xxx呢?

此时Webpack只是对url pathname进行了正则开始匹配 即 /^/xxx/,然后用不改变开始别名进行查询/api 而是 /apihrp 首先了解一个特性js循环对象是按照编写顺序进行循环的。 所以上面先添加的/api 后有 /apihrp。

简单演示一下这个过程

const pathname = "/apihrp/abc"; // 输入的地址
const alias = "/api" // 代理别名
const targetAndPath = " http://192.168.1.100:80/api" // 代理地址:服务器+路径
const reg = RegExp("^"+alias); // 如果通过
if (reg.test(pathname)) { // 通过
    return pathname.replace(RegExp("^" + alias), targetAndPath); 
    // http://192.168.1.100:80/api135/abc
}
// 不通过 迭代下一个

要解决这个问题只能在项目中代理配置表按照命名的从大到小进行排序添写就可以了, 或者换一个跟所有匹配都不沾边的别名。如下:
proxy: {
  '^/apihrp': {
      target: 'http://192.168.1.135:80', // B Server
      changeOrigin: true,
      secure: false,
      pathRewrite: {'^/apihrp': ''}
  },
  '^/api': {
      target: 'http://192.168.1.100:80', // A Server
      changeOrigin: true,
      secure: false,
      pathRewrite: {'^/api': ''}
  }
}