基於webpack專案的全域性變數
基於webpack專案的全域性變數
熟悉vue的同學,肯定知道有.env或env.development類似於這樣的配置檔案來定義app的全域性變數。那麼這是如何實現的呢?如果我沒用vue,比如我用的react或者純手工的webpack專案。我怎麼去實現這個功能呢?以下詳細描述,也是vue支援配置檔案的原理。
如何嚮應用注入全域性變數?
答案是,通過webpack.DefinePlugin
具體用法如下
webpack.config.js
const webpack = require('webpack'); module.exports = { plugins: [ new webpack.DefinePlugin({ appName:"'測試app'", version:1.0 }) ] };
index.js
console.log(appName);
如何像vue那樣讀取專屬配置檔案呢?
首先你需要定義這樣的配置檔案 .env
appName="測試app"
然後定義一個解析這樣檔案的方法 readEnv.js
const fs = require('fs'); const path = require('path'); // 讀取環境變數的檔案把它轉化成物件 module.exports = (file) => { // flie為檔案路徑 let fileName = path.join(__dirname, file); let data = fs.readFileSync(fileName, { encoding: 'utf8' }) let d = data.replace(/\r/g, ',').replace(/\n/g, '') // 把換行和回車替換 let arr = d.split(',').map(item => { return item.split('=') }) // [ [ 'a', '1' ], [ 'b', '2' ] ] let obj = {} arr.forEach(item => { obj[item[0]] = item[1] }) return obj //{ a: '1', b: '2' } // 可以接著處理 /* 像vue-cli3 新版create-react-app 一樣規定環境變數的Key必須以(VUE_APP_) (REACT_APP_) 開頭 */ }
最後使用 webpack.config.js
const webpack = require('webpack');
const readEnv = require('./readEnv')
const env = readEnv('./.env');
module.exports = {
plugins: [
new webpack.DefinePlugin({
...env
})
]
};
如何根據不同環境,使用不同配置檔案呢?
這裡是利用了node的環境變數,所以需要了解下node和環境變數知識
環境變數
環境變數是什麼呢?
其實我們可以把它理解為"系統的視線範圍",
沒錯,配置進入了環境變數的程式,就等於是進入了系統的視線範圍,
開啟DOS命令視窗後輸入程式名,
系統就會把在其視線內的環境變數內的程式找出來,
如果程式沒有配置進入環境的變數的話,那系統自然就找不到。
window下檢視環境變數:cmd>輸入set回車,你就能看到類似於如下的列印,就是系統的環境變量了
JAVA_HOME=C:\Program Files\Java\jdk1.8.0_221
Path=C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Windows\System32\OpenSSH\;C:\Program Files\Java\jdk1.8.0_221\bin;C:\Program Files\Git\cmd;C:\Program Files\nodejs\;D:\soft\apache-maven-3.6.1\bin;C:\Users\admin\AppData\Local\Microsoft\WindowsApps;C:\Users\admin\AppData\Roaming\npm;C:\Users\admin\AppData\Local\Programs\Microsoft VS Code\bin
PATHEXT=.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC
...
檢視某個具體的環境變數, set 環境變數名,比如 set JAVA_HOME。會列印如下
C:\Users\admin>set JAVA_HOME
JAVA_HOME=C:\Program Files\Java\jdk1.8.0_221
臨時設定環境變數(重啟會失效)
set JAVA_HOME=123
node與系統環境變數
node應用是如何讀寫當前作業系統的環境變數呢?
每一個node程式,都有一個當前程式的程序物件process。
這個物件裡有一個屬性env,即可讀取當前作業系統的環境變數。
process.env
node程式不能設定環境變數,只能讀取
注入環境變數並編譯
通過編輯packge.json的script,
我們可以在執行webpack編譯前,
修改或新增本次webpack編譯時(即本次node程式執行時)的環境變數
packge.json指令碼如下:
"scripts": {
"dev": "set NODE_ENV=development && webpack",
"build": "set NODE_ENV=production && webpack"
}
新增兩個配置檔案
.env 和 .env.development。內容分別如下
appName="正式app"
appName="測試app"
核心程式碼如下webpack.config.js
const webpack = require('webpack');
const readEnv = require('./readEnv');
const isDev = process.env.NODE_ENV==='development';
const injectEnvDate = isDev?readEnv('./.env.development'):readEnv('./.env');
module.exports = {
plugins: [
new webpack.DefinePlugin({
...injectEnvDate
})
]
};
入口程式index.js
console.log(process.env.NODE_ENV+':'+appName);
測試驗證
嘗試執行編譯測試 npm run dev
看看編譯後的程式碼 ```javascript console.log("development:測試app"); ``` 已經生效
## 相容性問題 當我們在mac或和linux上執行 npm run build或dev的時候會報錯
因為linux上設定環境變數的語法和window不一樣
window是 set JAVA_HOME=xxx
linux是JAVA_HOME=xxx
為了抹平這種差異,我們可以引用一個三方包,來處理 ```shell yarn add --dev cross-env ```
然後修改script命令
"scripts": {
"dev": "cross-env NODE_ENV=develop webpack", //注意這裡沒有&&
"build":"cross-env NODE_ENV=production webpack"
}
參考:
https://www.cnblogs.com/tugenhua0707/p/9780621.html
https://segmentfault.com/q/1010000009324489