配置合适的多环境Api层
在前端项目中,api
层的多环境是现在必不可少的配置。
一套完整的http请求流程,也就是api
层如下所示
Api
层一般在开发中,前端项目都至少需要两个环境去部署测试,需要开发环境、生产环境。 同理后端也是需要两种环境去部署测试,因此在不同环境下请求的api接口也是不同的。
前端设计多环境Api层的痛点
不同的参数下打包可以输出依赖不同环境的代码,以便部署到各个环境下
毋庸置疑这是多环境的核心。
控制粒度要精确到后端微服务下的各个组件
现在后端将不同的功能模块分成不同的应用进程,所以每个进程的请求地址可以不同,前端需要根据后端的粒度来调整接口。
多个环境文件最好是有类型控制,防止某些环境代码缺失
类型控制推荐
typescirpt
来控制,可用flow
等进行平替。多环境文件最好在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}`
);
}
)
创建环境文件夹
因此可以创建一个文件夹管理所有环境文件
使用环境文件
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",
}
输出
在开发环境下 Request URL: http://xx.xx.xx.xx:5000/control/v1/draftbox
在生产环境下 Request URL: http://xxxx.xx/control/v1/draftbox
了解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'
来完成多环境的输出