1. 程式人生 > 實用技巧 >基於webpack專案的全域性變數

基於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