Webpack中使用環(huán)境變量的各種正確姿勢
寫在前邊
你還在為Webpack中各種打包配置而煩惱嗎?
今天我們來聊聊webpack中注入環(huán)境變量的各種姿勢,或者你會覺得注入環(huán)境變量通過命令行注入不就可以了嗎?
如果你有這種想法,耐心看下去我相信你會有不一樣的收獲的~
畢竟所謂成長就是一點一滴積累的過程!讓我們來聊聊Webpack 5中使用環(huán)境變量的各種正確姿勢。
文章中從三個方面來講解Webpack流程中的環(huán)境變量:
- 業(yè)務(wù)代碼中注入使用webpack環(huán)境變量。
- 官方提供構(gòu)建過程使用webpack環(huán)境變量。
- 傳統(tǒng)環(huán)境變量方法使用webpack構(gòu)建過程環(huán)境變量。
業(yè)務(wù)代碼使用環(huán)境變量
使用webpack.DefinePlugin插件在業(yè)務(wù)代碼中注入環(huán)境變量
相信不少同學(xué)已經(jīng)應(yīng)用過這種場景,我們需要在打包過程中通過webpack注入一些全局變量在業(yè)務(wù)代碼中使用。
比如我們業(yè)務(wù)入口文件有這樣一段代碼:
// src/main.js
console.log('hello, Environment variable', __WEPBACK__ENV)
我們希望的是業(yè)務(wù)代碼中碰到這個__WEBPACK__ENV這個變量時,代碼中會認識這個變量并且輸出正確字符串值pacakges。
想一想我們應(yīng)該怎么做?
熟悉webpack的同學(xué)其實已經(jīng)想到了,我們可以通過webpack中的definePlugins這個插件進行注入:
const wepback = require('webpack')
// webpack.config.js
...
new webpack.DefinePlugin({
__WEBPACK__ENV: JSON.stringify('packages'),
TWO: '1+1',
});
我們通過在webpack的plugins中加入這段配置后當(dāng)我們運行打包命令后,此時我們業(yè)務(wù)代碼中如果出現(xiàn)__WEBPACK__ENV這個變量的話他就會幫我們替換成為'packages'這個字符串,從而達到類似環(huán)境變量注入的效果。
webpack.DefinePlugin引發(fā)的思考
或許你已經(jīng)很熟悉webpack.definePlugins這個插件的使用了,別著急讓我們耐心往下看看,由這段代碼我們引發(fā)出一下的幾個思考:
- 'packages'已經(jīng)是string類型了,為什么我們還要使用JSON.stringify()進行處理。
- 此時的環(huán)境變量真的就是所謂的環(huán)境變量嗎?
我們先來探討一下這兩個問題:
definePlugin所謂的”環(huán)境變量“實現(xiàn)方式
webpack官方文檔中這樣講到
(Note that because the plugin does a direct text replacement, the value given to it must include actual quotes inside of the string itself. Typically, this is done either with alternate quotes, such as '"production"', or by using JSON.stringify('production').)
其實他也就是再說webpack.definePlugins本質(zhì)上是打包過程中的字符串替換,比如我們剛才定義的__WEBPACK__ENV:JSON.stringify('packages')。
在打包過程中,如果我們代碼中使用到了__WEPBACK__ENV,webpack會將它的值替換成為對應(yīng)definePlugins中定義的值,本質(zhì)上就是匹配字符串替換,并不是傳統(tǒng)意義上的環(huán)境變量process注入。
這也就回答了我們第二個問題。
JSON.stringify()處理環(huán)境變量
接下來我們來看看第一個問題,正所謂實踐出真知。我們來試試對比配置兩次不同的definePlugin來看看結(jié)果:
// webpack.config.js
new webpack.DefinePlugin({
__WEBPACK__ENV: JSON.stringify('packages'),
TWO: '1+1',
});
// 打包后的代碼 這里我們關(guān)閉了devtools 羅列出打包后打包后的代碼
console.log('hello, Environment variable', 'packages')
// webpack.config.js
new webpack.DefinePlugin({
__WEBPACK__ENV: 'packages',
TWO: '1+1',
});
// 打包后的代碼 這里我們關(guān)閉了devtools 羅列出打包后打包后的代碼
console.log('hello, Environment variable', packages)
仔細對比這兩段代碼第一個問題的答案其實已經(jīng)很明了了,針對definePlugin這個插件我們使用它定義key:value全局變量時,他會將value進行會直接替換文本。所以我們通常使用JSON.stringify('pacakges')或者"'packages'"。
對于DefinePlugin的流程以及需要額外注意的細節(jié)我們差不多已經(jīng)說清除了,但是此時我們定義所謂的全局變量是在業(yè)務(wù)代碼中進行使用的。但此時如果我們對于打包構(gòu)建過程中想使用環(huán)境變量的話需要另一種方式來注入。
構(gòu)建過程中使用環(huán)境變量
通常我們在使用webpack過程中需要根據(jù)自己獨特的需求去使用環(huán)境變量進行動態(tài)打包,比如一些通過動態(tài)讀取項目中的文件夾從而在控制臺動態(tài)和用戶交互打包對應(yīng)不同的bundle。
此時在構(gòu)建過程中使用環(huán)境變量就顯得非常重要了,所謂構(gòu)建過程中使用環(huán)境變量簡單來說就是在非業(yè)務(wù)代碼中,比如webpack.config.js配置文件中注入環(huán)境變量。
我們來看看在項目中輸入這行代碼:
npx webpack --env goal=local --env production --progress --config ./webpack.config.js
此時這行代碼我們相當(dāng)于運行webpack讀取當(dāng)前目錄中的webpack.config.js配置文件進行打包,同時注入兩個環(huán)境變量goal和progress他們的值分別為local和true。
這樣我們就可以在配置文件中使用注入的環(huán)境變量了:
const path = require('path');
module.exports = (env) => {
// Use env.<YOUR VARIABLE> here:
console.log('Goal: ', env.goal); // 'local'
console.log('Production: ', env.production); // true
return {
entry: './src/index.js',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist'),
},
};
};
細心的你可以已經(jīng)發(fā)現(xiàn)了,這里我們的module.exports導(dǎo)出的是一個包含env的函數(shù),而并不是傳統(tǒng)的對象了。
通常,module.exports 指向配置對象。要使用 env 變量,你必須將 module.exports 轉(zhuǎn)換成一個函數(shù)的方式進行使用。
我們來看看如果不使用函數(shù)的話:
const path = require('path');
// Use env.<YOUR VARIABLE> here:
console.log('Goal: ', process.env.goal); // undefined
console.log('Production: ', process.env.production); // undefined
module.exports = {
entry: './src/index.js',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist'),
},
};
我們可以看到我們讀取node進程process中的env.goal/production發(fā)現(xiàn)兩個分別都是undefined。
也就是說通常我們使用--env在命令行中為webpack構(gòu)建過程注入環(huán)境變量時,需要將配置文件的module.exports導(dǎo)出一個函數(shù)的形式,從而在函數(shù)第一個參數(shù)中獲取對應(yīng)的key拿到對應(yīng)的環(huán)境變量value。
那么問題又來了,誒?假如我就是想在node的process中獲得對應(yīng)的環(huán)境變量呢?我應(yīng)該怎么辦,我就是不想寫一個函數(shù)。
傳統(tǒng)環(huán)境變量方法使用webpack構(gòu)建過程環(huán)境變量。
應(yīng)該怎么辦呢?其實webpack對應(yīng)打包的原理就是通過shell命令去執(zhí)行我們的配置文件(nodejs配置文件)。
假如我們在運行命令webpack時注入真正傳統(tǒng)意義上的環(huán)境變量而非通過--env是不是就可以了呢?接下來我們來試一試~
這里我們借助了一個非常好用的環(huán)境變量插件cross-env,它的使用方式很簡單可以幫助我們在不同環(huán)境下linux/windows...中以相同的方式去注入運行時環(huán)境變量,接下來我們來使用一下它:
不要忘記安裝npm install --save-dev cross-env。
// package.json "build": "cross-env NAME_W=aaa webpack --config ./webpack.config.js"
我們通過cross-env NAME_W=aaa注入了一個環(huán)境變量。
// webpack.config.js
console.log(process.env.NAME_W, 'env'); // 'aaa'
module.exports = {
entry: './src/a.js',
};
在我們的嘗試下,發(fā)現(xiàn)其實通過命令行傳統(tǒng)方式注入環(huán)境變量的形式也是可以的!這樣我們就逃離了導(dǎo)出必須是一個函數(shù)的限制可以"為所欲為了"。
總結(jié)
在webpack構(gòu)建以及業(yè)務(wù)代碼中,環(huán)境變量的注入對于我們的幫助是非常大的。當(dāng)需要一定體系的前端工程化代碼時,環(huán)境變量無論是在構(gòu)建過程還是業(yè)務(wù)代碼中都起到了至關(guān)重要的作用。
看到這里我們想說到的其實都已經(jīng)講到了,我們來進行一個簡單的總結(jié)吧:
在webpack打包業(yè)務(wù)代碼時,我們需要使用類似環(huán)境變量的方式使用一些全局變量時,可以通過webpack.DefinePlugin去定義一些變量從而在業(yè)務(wù)代碼中使用。(但是需要注意上邊講到的JSON.stringify())。
同時在構(gòu)建過程中,我們可以通過webpack官方提供的--env參數(shù)以及在配置文件中通過module.exports函數(shù)的方式使用--env定義的環(huán)境變量。
同時也可以在構(gòu)建過程中通過我們?nèi)粘J褂玫姆绞阶⑷氕h(huán)境變量而“逃脫”webpack的限制,直接使用命令行中定義的環(huán)境變量然后通過process.env.xxx去獲取。
到此這篇關(guān)于Webpack中使用環(huán)境變量的文章就介紹到這了,更多相關(guān)Webpack使用環(huán)境變量內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
在layui.use 中自定義 function 的正確方法
今天小編就為大家分享一篇在layui.use 中自定義 function 的正確方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-09-09
圖片輪換效果實現(xiàn)代碼(點擊按鈕停止執(zhí)行)
在這個實例中需要注意的是,要把images文件夾下圖片的命名設(shè)置為有順序的,1、2、3..才可以,感興趣的朋友可以參考下2013-04-04
uniapp如何手動實現(xiàn)讓input文本框聚焦效果
最近使用uniapp做一個評論的功能,遇到一個需求就是點擊上面的評論圖標(biāo),讓定位在底部的input框聚焦,下面這篇文章主要給大家介紹了關(guān)于uniapp如何手動實現(xiàn)讓input文本框聚焦效果的相關(guān)資料,需要的朋友可以參考下2023-12-12
JS構(gòu)建頁面的DOM節(jié)點結(jié)構(gòu)的實現(xiàn)代碼
本來想用json格式的,可是要么有重復(fù),要么得嵌套,所以改用對象嵌套數(shù)組2011-12-12
JavaScript實現(xiàn)刪除數(shù)組重復(fù)元素的5種常用高效算法總結(jié)
這篇文章主要介紹了JavaScript實現(xiàn)刪除數(shù)組重復(fù)元素的5種常用高效算法,結(jié)合實例形式總結(jié)分析了javascript刪除數(shù)組重復(fù)元素的幾種常見操作技巧,需要的朋友可以參考下2018-01-01

