一次Webpack配置文件的分離實(shí)戰(zhàn)記錄
前言
隨著前端技術(shù)的發(fā)展,業(yè)務(wù)邏輯的增多及功能化的繁瑣已經(jīng)成為前端人員最燒腦的問(wèn)題。前端自動(dòng)化構(gòu)建工具的出現(xiàn),為前端人員帶來(lái)了項(xiàng)目構(gòu)建上的福音,成為每個(gè)前端工程師必回的技術(shù)棧,目前比較流行的Webpack以萬(wàn)物皆模塊的思想構(gòu)建我們的前端項(xiàng)目,同樣也是筆者正在使用的一個(gè)前端自動(dòng)化構(gòu)建工具。
Webpack對(duì)于每個(gè)前端人員來(lái)說(shuō)都不會(huì)怎么陌生,它將每一個(gè)靜態(tài)文件當(dāng)做一個(gè)模塊,經(jīng)過(guò)一系列的處理為我們整合出最后的需要的js、css、圖片、字體等文件。
webpack.config.js就是Webpack的配置文件,這個(gè)文件需要自己在項(xiàng)目根目錄下手動(dòng)建立。
下面話不多說(shuō)了,來(lái)一起看看詳細(xì)的介紹吧
單個(gè)配置文件所造成的問(wèn)題
本文默認(rèn)電腦前的你已經(jīng)了解一些Webpack基礎(chǔ)的配置,并懂得了webpack.config.js配置文件的基礎(chǔ)搭建。
隨著我們業(yè)務(wù)邏輯的增多,圖片、字體、css、ES6以及CSS預(yù)處理器和后處理器逐漸的加入到我們的項(xiàng)目中來(lái),進(jìn)而導(dǎo)致配置文件的增多,使得配置文件書(shū)寫(xiě)起來(lái)比較繁瑣,更嚴(yán)重者(書(shū)寫(xiě)特定文件的位置會(huì)出現(xiàn)錯(cuò)誤)。更由于項(xiàng)目中不同的生產(chǎn)環(huán)境和開(kāi)發(fā)環(huán)境的配置,使得配置文件變得更加糟糕。
使用單個(gè)的配置文件會(huì)影響到任務(wù)的可重用性,隨著項(xiàng)目需求的增長(zhǎng),我們必須要找到更有效地管理配置文件的方法。
管理配置文件的幾種方法
配置文件的管理有一下幾種方法。
- 在每個(gè)環(huán)境的多個(gè)文件中維護(hù)配置,并通過(guò)--config參數(shù)將webpack指向每個(gè)文件,通過(guò)模塊導(dǎo)入共享配置。
- 將配置文件推送到庫(kù),然后引用庫(kù)。
- 將配置文件推送到工具。
- 維護(hù)單個(gè)配置文件的所有配置并在那里進(jìn)行分支并依賴--env參數(shù)。
本文以第四種方式闡述webpack配置文件的分離。
分離配置文件
我們?cè)诟夸浵聞?chuàng)建config文件夾,并創(chuàng)建四個(gè)配置文件,分別是:
- webpack.comm.js 公共環(huán)境的配置文件
- webpack.development.js 開(kāi)發(fā)環(huán)境下的配置文件
- webpack.production.js 生產(chǎn)環(huán)境下的配置文件
- webpack.parts.js 各個(gè)配置零件的配置文件

合并配置文件的工具
如果配置文件被分成了許多不同的部分,那么必須以某種方式來(lái)組合他們,通常就是合并數(shù)組和對(duì)象,webpack-merge很好的做到了這一點(diǎn)。
webpack-merge做了兩件事:它允許連接數(shù)組并合并對(duì)象,而不是覆蓋組合。
const merge = require("webpack-merge");
merge(
{a : [1],b:5,c:20},
{a : [2],b:10, d: 421}
)
//合并后的結(jié)果
{a : [1,2] ,b :10 , c : 20, d : 421}
使用webpack-merge合并配置文件
首先將webpack-merge添加到項(xiàng)目中
npm install webpack-merge --save-dev
首先設(shè)置各個(gè)配置文件的連接
webpack.config.js
const commConfig = require("./config/webpack.comm");
const developmentConfig = requie("./config/webpack.development");
const productionConfig = require("./config/webpack.development")
const merge = require("webpack-merge");
module.exports = mode => {
if(mode === "production"){
return merge(commConfig,productionConfig,{mode});
}
return merge(commConfig,developmentConfig,{mode});
}
上面代碼利用mode的值來(lái)判斷是開(kāi)發(fā)環(huán)境還是生產(chǎn)環(huán)境
webpack.comm.js
const merge = require("webpack-merge");
const parts = require("./webpack.parts") //引入配置零件文件
const config = {
//書(shū)寫(xiě)公共配置
}
module.exports = merge([
config,
parts......
])
webpack.production.js
const merge = require("webpack-merge");
const parts = require("./webpack.parts"); //引入配置零件文件
const config = {
//書(shū)寫(xiě)公共配置
}
modules.exports = merge([
config,
parts......
])
webpack.development.js
const merge = require("webpack-merge");
const parts = require("./webpack.parts"); //引入配置零件文件
const config = {
//書(shū)寫(xiě)公共配置
}
modules.exports = merge([
config,
parts......
])
使用--env值傳參
使用--env允許將字符串傳遞給配置。我們來(lái)修改下package.json
"dev": "webpack --env development ", "prod": "webpack --env production", "dev:server": "webpack-dev-server --env development "
這樣就使得env參數(shù)mode環(huán)境參數(shù)傳入到webpack.config.js中,就可以判斷是生產(chǎn)環(huán)境還是開(kāi)發(fā)環(huán)境。
如何寫(xiě)出可配置的webpack.parts.js
上面可以看出我們新建了一個(gè)webpack.parts.js文件,這個(gè)文件中主要是存放我們的一些配置零件。如何寫(xiě)出可配置,可拔插的配置零件。就是我們這個(gè)文件的最重要的部分。
以loadCSS為例:
exports.loadCSS = ({reg = /\.css$/,include,exclude,uses = []} = {}) => ({
module : {
rules:[{
test : reg,
include,
exclude,
use[{
loader : "style-loader",
},{
loader : "css-loader",
}].concat(uses),
}]
}
})
上面代碼中,利用exports導(dǎo)出單個(gè)配置零件,通過(guò)解構(gòu)賦值來(lái)傳入?yún)?shù)。使用數(shù)組的concat來(lái)連接外部導(dǎo)入的loader。參數(shù)解析:
- reg:表示loader匹配的test正則,默認(rèn)為css,這里可以是(less、sass、stylus)。
- include:表示所要打包的文件夾。
- exclude:表示要跳過(guò)打包的文件夾。
- uses:外部導(dǎo)入的loader。
在webpack.development.js中引入
module.exports = merge([
config,
parts.loadCSS({
reg : /\.less/,
use : ["less-loader"]
}),
parts.loadCSS(),
])
分離配置文件的好處
配置文件拆分可以是我們繼續(xù)擴(kuò)展配置。最重要的收益是我們可以提取不同目標(biāo)之間的共性。并且還可以識(shí)別要組合的較小配置部件,這些配置不見(jiàn)可以推送到自己的軟件包以跨項(xiàng)目使用。還可以將配置作為依賴項(xiàng)進(jìn)行管理,而不是在多個(gè)項(xiàng)目中復(fù)制類似的配置。
我自己的parts配置
展示一部分我自己的部件配置,由于在學(xué)習(xí)階段,不足的地方還望大佬們提出,學(xué)習(xí)進(jìn)步。
/**
* @name 本地服務(wù)器配置
* @param host 打開(kāi)的url
* @param port 打開(kāi)url的端口號(hào)
*
*/
exports.devServer = ({ host, port} = {}) => ({
devServer : {
stats : "errors-only",
host,
port,
open : true,
overlay : true,
}
})
/**
* @name 未從js中分離的cssLoader配置
* @param reg 匹配文件的后綴名test
* @param include 所要打包的文件夾
* @param exclude 跳過(guò)打包的文件夾
* @param uses 所要向loadCSS中添加的loader
*/
exports.loadCSS = ({reg = /\.css$/,include,exclude,uses = []} = {}) => {
return {
module: {
rules: [{
test: reg,
use: [{
loader: "style-loader"
}, {
loader: "css-loader"
}].concat(uses),
include,
exclude,
}]
},
}
}
/**
* @name 從js中分離的cssLoader配置
* @param reg 匹配文件的后綴名test
* @param include 所要打包的文件夾
* @param exclude 跳過(guò)打包的文件夾
* @param uses 所要向loadCSS中添加的loader
* */
const MiniCssExtrectPlugin = require("mini-css-extract-plugin");
exports.extractCSS = ({reg = /\.css$/,include,exclude,uses = []} = {}) => {
const plugin = new MiniCssExtrectPlugin({
filename : "styles/[name]-[hash:5].css",
})
return {
module: {
rules: [{
test: reg,
use: [{
loader: MiniCssExtrectPlugin.loader,
options : {
publicPath : "../"
}
}, {
loader: "css-loader"
}].concat(uses),
include,
exclude,
}]
},
plugins : [
plugin,
]
}
}
/**
* @name css tree-shaking:將沒(méi)有用到的css扔掉
* @param paths 監(jiān)聽(tīng)css tree-shaking 的文件名
*/
const PurifyCssPlugin = require("purifycss-webpack");
exports.purifyCSS = ({paths}) => ({
plugins : [
new PurifyCssPlugin({paths})
]
})
/**
* @name autoprefixer 為css樣式添加瀏覽器前綴
* @author wangchong
*/
exports.autoprefix =() =>({
loader : "postcss-loader",
options : {
plugins : () => [require("autoprefixer")]
}
})
/**
* @name loadImage :打包圖片資源
* @param include 所要打包的文件夾
* @param exclude 跳過(guò)打包的文件夾
* @param options loader的options配置
*/
exports.loadImage = ({include,exclude,options} = {}) => ({
module : {
rules : [
{
test : /\.(png|jpg)$/,
include,
exclude,
use : {
loader : "url-loader",
options,
}
}
]
}
})
文章總結(jié)自:Surviejs-webpack。
總結(jié)
以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,如果有疑問(wèn)大家可以留言交流,謝謝大家對(duì)腳本之家的支持。
相關(guān)文章
js實(shí)現(xiàn)新年倒計(jì)時(shí)效果
這篇文章主要介紹了js實(shí)現(xiàn)2015年新年倒計(jì)時(shí)效果,很快就要迎接新的一年,想知道距離2016還有多少天嗎?大家可以參考一下這篇文章2015-12-12
火狐和ie下獲取javascript 獲取event的方法(推薦)
下面小編就為大家?guī)?lái)一篇火狐和ie下獲取javascript 獲取event的方法(推薦)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2016-11-11
Bootstrap modal 多彈窗之疊加引起的滾動(dòng)條遮罩陰影問(wèn)題
這篇文章主要介紹了 Bootstrap modal 多彈窗之疊加引起的滾動(dòng)條遮罩陰影問(wèn)題,需要的朋友可以參考下2017-02-02
document.createElement()用法及注意事項(xiàng)(ff下不兼容)
今天處理了一個(gè)日期選擇器的ie和ff的兼容問(wèn)題,本來(lái)這種情況就很難找錯(cuò)誤,找了好久才把錯(cuò)誤定位到j(luò)s中創(chuàng)建元素的方法document.createElement(),這個(gè)方法在ie下支持這樣創(chuàng)建元素2013-03-03
用js實(shí)現(xiàn)圖片旋轉(zhuǎn)的兩種方案
這篇文章主要給大家介紹了關(guān)于用js實(shí)現(xiàn)圖片旋轉(zhuǎn)的兩種方案, 旋轉(zhuǎn)的效果就是根據(jù)鼠標(biāo)的的移動(dòng)距離來(lái)顯示不同的圖片,形成視覺(jué)差,仿佛就是在正真的旋轉(zhuǎn),需要的朋友可以參考下2023-07-07
antd?table長(zhǎng)表格出現(xiàn)滾動(dòng)條的操作方法
這篇文章主要介紹了antd?table長(zhǎng)表格如何出現(xiàn)滾動(dòng)條,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-06-06
Three.js+React實(shí)現(xiàn)帶火焰效果的艾爾登法環(huán)
《艾爾登法環(huán)》是最近比較火的一款游戲,觀察可以發(fā)現(xiàn)它的?Logo?是由幾個(gè)圓弧和線段構(gòu)成。本文使用?React?+?Three.js?技術(shù)棧,實(shí)現(xiàn)具有火焰效果艾爾登法環(huán)?Logo,感興趣的可以了解一下2022-03-03
微信小程序登錄按鈕遮罩浮層效果的實(shí)現(xiàn)方法
這篇文章主要給大家介紹了關(guān)于微信小程序登錄按鈕遮罩浮層效果的實(shí)現(xiàn)方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2018-12-12
解析arp病毒背后利用的Javascript技術(shù)附解密方法
解析arp病毒背后利用的Javascript技術(shù)附解密方法...2007-08-08

