跳到主要内容

配置合适的多环境Api层

在前端项目中,api层的多环境是现在必不可少的配置。

一套完整的http请求流程,也就是api层如下所示

什么是多环境的Api

一般在开发中,前端项目都至少需要两个环境去部署测试,需要开发环境、生产环境。 同理后端也是需要两种环境去部署测试,因此在不同环境下请求的api接口也是不同的。

前端设计多环境Api层的痛点

  1. 不同的参数下打包可以输出依赖不同环境的代码,以便部署到各个环境下

    毋庸置疑这是多环境的核心。

  2. 控制粒度要精确到后端微服务下的各个组件

    现在后端将不同的功能模块分成不同的应用进程,所以每个进程的请求地址可以不同,前端需要根据后端的粒度来调整接口。

  3. 多个环境文件最好是有类型控制,防止某些环境代码缺失

    类型控制推荐typescirpt来控制,可用 flow 等进行平替。

  4. 多环境文件最好在webpack入口内可以使用热替换打包,以便在开发中更换地址调试

    因为在开发过程中可能随时有从一个环境到另一个环境的可能,这个时候为了不重复启动前端项目节约时间,在入口文件里定义的环境文件来进行热替换是必要的。

项目实践

我们需要一种多环境方法解决以上的痛点

主要是使用 webpack 插件 NormalModuleReplacementPlugin

NormalModuleReplacementPlugin

这个插件可以在两次构建时提供不同的行为

new webpack.NormalModuleReplacementPlugin(resourceRegExp, newResource);
  • resourceRegExp: RegExp
  • newResource string | ((arg0?: any) => void)

附上插件的配置

let appTarget = process.env.NODE_ENV === 'development' ? 'environment' : 'environment.prod'
const replacementPlugin = new NormalModuleReplacementPlugin(
/(.*)environment(\.*)/,
function (resource) {
resource.request = resource.request.replace(
/environment/,
`${appTarget}`
);
}
)

创建环境文件夹

因此可以创建一个文件夹管理所有环境文件

RUNOOB

使用环境文件

import { EnvironmentConfig } from './environment.interface' 

const environment: EnvironmentConfig = {
DASHBOARD_API: 'http://xx.xx.xx.xx:7000/control/v1',
TICKET_API: 'http://xx.xx.xx.xx:7010/control/v1',
}

export { environment }
// tsconfig.json
"paths": {
"@/*": ["src/*"]
}

传递参数

可以使用 cross-env 可以跨平台地讲参数传给

"scripts": {
"dev": "cross-env NODE_ENV=development webpack serve --mode=development",
"build": "cross-env NODE_ENV=production webpack --mode=production",
},

也可以使用 webpack --env 的形式来传递

"scripts": {
"dev": "npx webpack --env NODE_ENV=development",
"build": "npx webpack --env NODE_ENV=production",
}

输出

了解NormalModuleReplacementPlugin

在主体代码中加入混淆代码

console.log('@/enviroments/enviroment')

然后在插件中打印输出

const replacementPlugin = new NormalModuleReplacementPlugin(
// ...
function (resource) {
console.log(resource.request, 'ouput')
// ...
}
}

可以发现控制台打印出 import '@/enviroments/enviroment',并不包含我们加入的代码

可以推测在打包过程中 NormalModuleReplacementPlugin 的能力是通过 webpack 的插件函数,分析 compiler 中的 ast 树,将所有 import '@/enviroments/enviroment' 替换成 import '@/enviroments/enviroment.prod' 来完成多环境的输出