基於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,即可讀取當前操作系統的環境變量。
在node環境下,輸入 process.env
C:\Users\admin>node
Welcome to Node.js v14.15.1.
Type ".help" for more information.
> process.env
{
JAVA_HOME: 'C:\\Program Files\\Java\\jdk1.8.0_221',
MVN_HOME: 'D:\\soft\\apache-maven-3.6.1',
OneDrive: 'C:\\Users\\admin\\OneDrive',
OS: 'Windows_NT',
Path: '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\\Roaming\\npm;
}
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
為了抹平這種差異,我們可以引用一個三方包,來處理
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
