最近有个项目,是部署在2个服务器a.abc.com 和 b.abc.com ;这里假设用户群A,用户群B用,两者看到的页面很多是相同的,只是请求接口有点不同,还有个别不同。所以就想看能不能同用一份代码,用个标识去区分,在代码中根据标识,if判断一下,修改相关代码。打包时就根据标识,打包构建出不同的包。这样就可以避免复制2份代码,一改就要改2处地方。这里想到了平时用process.env.NODE_ENV用来区分开发环境,想着能不能也用它来做个标识;
日常工作,分为多个环境(开发,测试,生产),可能在不同环境用到的api不同,或其他数据不同。这时需要根据环境不同,运行不同代码,或者打包出不同代码。
我们平时常见是用process.env.NODE_ENV,这个去区分是各种环境,默认应该是dev,product这2种,本地开发建设dev,打包后就是product。假如我们还有测试test,预演preview,那就需要我们手动设置了。
设置环境
1.安装。因为在window和mac下用到命令是不同的。这里要用到cross-env,这个是解决不同系统之前的命令兼容问题。
npm install --save-dev cross-env
2.设置。在package.json中设置下面代码
"start:dev2": "cross-env NODE_ENV=test BUILD_ENV=a umi dev",// 设置开发环境是测试环境test, BUILD_ENV是自定义名称,会传给process.env,a是自定义的值,是标识,到时代码中用来判断,打包出不同代码
"start:dev3": "cross-env BUILD_ENV=b umi dev", "build:dev2": "cross-env BUILD_ENV=a umi build",// 打包出a环境的代码 "build:dev3": "cross-env BUILD_ENV=b umi build",// 打包出b环境的代码
这样,我们运行npm run start:dev2 就是运行在test环境中。同理,运行npm run-script build:dev2就是打包出要部署在a环境的代码;
3.全局化。process.env.NODE_ENV在打包配置config.ts可以直接用。但我们要在普通 xxx.js页面中用到process.env.NODE_ENV,是需要用到webpack的DefinePlugin,这样可以把它全局化,直接使用。
在普通项目中:
const webpack = require('webpack'); module.exports = { entry: { app: './src/app' }, output: { path: 'dist', filename: 'bundle.js' }, plugins: [ new webpack.DefinePlugin({ 'process.env.NODE_ENV':JSON.stringify('production')
})
]
};
umi项目中,在config.ts改:(详情可以在umi文档查看chainWebpack)
export default defineConfig({ outputPath:BUILD_ENV==='dev2'?'dist2':'dist3', // 打包到不同文件夹 chainWebpack:(config)=>{ // 修改参数 config.plugin('define').tap(([option,...rest])=>{ const options ={ ...option, BUILD_ENV:JSON.stringify(BUILD_ENV) // 这里需要json字符串化,不然在用到的地方,会变成一个变量。前面那个BUILD_ENV是定义全局的变量,所以在js页面能读取到,JSON.stringify后面的BUILD_ENV是上面结构出来的。
} return [options,...rest] }) } })
4.使用
在具体xxx.js中用,你打印process.env会发现,永远都是{NODE_ENV: "xxx"} ,所以得知在package.json设置的,可能只会在打包配置config.ts中读取到。?
页面里直接使用即可,console.log('BUILD_ENV', BUILD_ENV) 可以打印出值a,但用了ts的vscode会报一个错;
我们只要在src目录下的typings.d.ts声明一下就可以了
declare const BUILD_ENV: 'dev2' | 'dev3' | false;
然后在代码中可以愉快的根据标识,判断处理,打包出不同代码了;
let str='' if(BUILD_ENV ==='dev2'){ str='123' }else{ str='456' }