最近有個項目,是部署在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' }