webpack项目配置合适的多环境Api层

webpack项目配置合适的多环境Api层

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

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

multi333.png

什么是多环境的Api层
一般在开发中,前端项目都至少需要两个环境去部署测试,需要开发环境、生产环境。

同理后端也是需要两种环境去部署测试,因此在不同环境下请求的api接口也是不同的。

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

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

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

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

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

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

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

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

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

项目实践

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

主要是使用 webpack 插件 NormalModuleReplacementPlugin

1. NormalModuleReplacementPlugin

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

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

附上插件的配置

// webpack.config.js
const { NormalModuleReplacementPlugin } = webpack
// ...

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

2. 创建环境文件夹

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

direotey.png

3. 使用环境文件

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/*"]
}
复制代码

4. 传递参数

可以使用 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",
}
复制代码

5. 输出

  • 在开发环境下

Request URL: xx.xx.xx.xx:5000/control/v1/…

  • 在生产环境下

Request URL: xxxx.xx/control/v1/…

了解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' 来完成多环境的输出

猜你喜欢

转载自juejin.im/post/7106858027675811871