Webpack配置
1. mode:模式
-
development:開發(fā)模式
啟用
NamedChunksPlugin和NamedModulesPlugin。NamedChunksPlugin:把chunk id變?yōu)橐粋€(gè)字符串標(biāo)識(shí)符。
NamedModulesPlugin:當(dāng)開啟 HMR 的時(shí)候使用該插件會(huì)顯示模塊的相對(duì)路徑,建議用于開發(fā)環(huán)境。
-
production:生產(chǎn)模式
啟用
FlagDependencyUsagePlugin,FlagIncludedChunksPlugin,ModuleConcatenationPlugin,NoEmitOnErrorsPlugin,OccurrenceOrderPlugin,SideEffectsFlagPlugin和UglifyJsPlugin。FlagDependencyUsagePlugin:
FlagIncludedChunksPlugin:
ModuleConcatenationPlugin
NoEmitOnErrorsPlugin
OccurrenceOrderPlugin
SideEffectsFlagPlugin
UglifyJsPlugin
none:不開啟任何插件
2. entry:入口
entry配置的多種形式:字符串、數(shù)組、對(duì)象、函數(shù)。
2.1 字符串
module.exports = {
entry: './src/index.js'
}
2.2 數(shù)組
作用:將多個(gè)資源預(yù)先合并,在打包時(shí)將數(shù)組中最后一個(gè)元素作為實(shí)際入口路徑。
module.exports = {
entry: ['babel-polyfill', './src/index.js']
}
2.3 對(duì)象
多入口文件配置
module.exports = {
entry: {
page1: './src/page1.js',
page2: './src/page2.js'
}
}
2.4 函數(shù)
module.exports = {
entry: () => './src/index.js'
}
module.exports = {
entry: () => ({
// 添加一些動(dòng)態(tài)邏輯獲取工程的入口
if (boolean) {
return './src/index.js'
} else {
return './src/main.jss'
}
// 或者
// 返回一個(gè)Promise對(duì)象進(jìn)行異步操作
return new Promise(resolve => resolve('./src/index.js'));
})
}
注意:
- Webpack默認(rèn),bundle.js文件大于250KB(壓縮前)會(huì)認(rèn)為文件過大,會(huì)發(fā)生警告。
- 通過多入口將vendor(包含庫,框架等第三方不常用模塊打包產(chǎn)生的bundle)打包,提升效率
- 配置多頁應(yīng)用,減少資源體積。
3. output:資源出口
module.exports = {
mode: 'development',
entry: './src/index.js',
output: {
filename: 'bundle.js',
path: path.join(__dirname, 'assets'),
publicPath: '/dist/'
}
}
output的配置項(xiàng):
3.1 filename
控制輸出資源的文件名
bundle.js: 設(shè)置為固定的文件名
[name].js: entry設(shè)置為對(duì)象的key值(上述2.3的page1.js和page2.js)
[hash].js: 當(dāng)前打包的所有資源的hash
[chunkhash].js: 當(dāng)前chunk內(nèi)容的hash
[id]: 當(dāng)前chunk的ID
[query]: filename配置項(xiàng)中的query
注意:
- 開發(fā)環(huán)境不必要設(shè)置chunkhash,強(qiáng)烈推薦生產(chǎn)環(huán)境配置chunkhash,目的是控制客戶端緩存。
3.2 path
指定資源輸出的位置,必須為絕對(duì)路徑(默認(rèn)為dist目錄)。
{
path: path.join(__dirname, 'dist') // build構(gòu)建后資源存儲(chǔ)的位置
}
注意:
- Webpack-dev-server 也有publicPath參數(shù),請(qǐng)?jiān)O(shè)置該參數(shù)和webpack的path路徑相同。
3.3 publicPath:
由JS或CSS內(nèi)部請(qǐng)求的間接資源(異步加載的CSS,CSS請(qǐng)求圖片、字體等)的請(qǐng)求位置。
當(dāng)前html請(qǐng)求路徑為:https://weixin.dongyin.net/coach/index.html
打包之后異步資源為chunk-a3b82d.js文件
1. 相對(duì)路徑:以構(gòu)建之后的html為基準(zhǔn),獲取頁面資源的相對(duì)路徑(請(qǐng)求地址如果為https://www.test.com)
{
publicPath: '' // 請(qǐng)求地址為:https://weixin.dongyin.net/coach/chunk-a3b82d.js
publicPath: './js' // 請(qǐng)求地址:https://www.test.com/coach/js/chunk-a3b82d.js
publicPath: '../assets' // 請(qǐng)求地址:https://www.test.com/assets/chunk-a3b82d.js
}
2. Host相關(guān)
{
publicPath: '/' // 請(qǐng)求地址為:https://weixin.dongyin.net/chunk-a3b82d.js
publicPath: '/js' // 請(qǐng)求地址:https://www.test.com/coach/js/chunk-a3b82d.js
publicPath: '/dist' // 請(qǐng)求地址:https://www.test.com/coach/dist/chunk-a3b82d.js
}
3. CDN相關(guān)
{
publicPath: 'https://cdn.com' // 請(qǐng)求地址為:https://cdn.com/chunk-a3b82d.js
publicPath: '//cdn.com/app' // 請(qǐng)求地址為://cdn.com/app/chunk-a3b82d.js
}
4. Module
兩個(gè)配置:
4.1 noParse
對(duì)指定的內(nèi)容不解析:noParse: /^(vue|vue-router|vuex|vuex-router-sync)$/
4.2 rules
一個(gè)web工程通常包含HTML、JS、CSS、模版、圖片、字體、SVG等多種類型的靜態(tài)資源,資源之間又存在著某種聯(lián)系。
對(duì)于Webpack來說,這些靜態(tài)資源都是模塊,我們可以加載一個(gè)JS文件一樣去加載他們,但是JS又確實(shí)不認(rèn)識(shí)他們,于是有了Loader輔助webpack,認(rèn)識(shí)各種各樣的資源文件。
原理:
- 每個(gè)loader本身就是一個(gè)函數(shù)
- webpack4之前,函數(shù)輸入和輸出都是字符串
- webpack4之后,函數(shù)輸入和輸出支持抽象語法樹(AST),目的減少重復(fù)代碼解析
- webpack先對(duì)代碼解析=>由每一個(gè)loader對(duì)解析結(jié)果進(jìn)行一一處理=>處理完成,交給webpack繼續(xù)處理
4.3 常用loader
{
// 正則表達(dá)式,匹配成功的模塊使用該規(guī)則
test: /\.css$/,
// string|array: 使用的loader
use: 'raw-loader',
// 排除指定目錄下的模塊
exclude: /node_modules/,
// 包含指定目錄下的模塊
include: /src/,
// 只有src/pages下的js文件加載css
issuer: {
test: '/\.js$/',
include: /src/pages
},
// 強(qiáng)制該loader在所有l(wèi)oader之前執(zhí)行,避免被其他loader更改過(比如:eslint-loader需要先執(zhí)行)
enforce: 'pre'
}
1. exclude和include同時(shí)存在且不沖突,取并集
2. exclude和include同時(shí)存在有沖突,exclude優(yōu)先級(jí)高
1. raw-loader
raw-loader 解析文本文件(比如.txt后綴但不局限于.txt的文件)
{
test: /\.txt$/,
use: 'raw-loader'
}
2. 樣式loader集合
sass-loader 解析sass/scss樣式(sass-loader起連接作用,主要是node-sass解析sass/scss內(nèi)容)
css-loader 解析css后綴的文件,解析結(jié)果返回字符串。
vue-style-loadere 基于 style-loader,被 vue-loader 依賴
style-loader 將 css-loader 的解析結(jié)果(字符串)以內(nèi)聯(lián)標(biāo)簽<style>形式插入到 <head> 標(biāo)簽內(nèi)。
postcss 編譯插件的容器,將接收的樣式源代碼交由編譯插件處理,最后輸出css。
{
test: /\.css$/,
use: ['style-loader', 'css-loader']
}
{
test: /\.scss$/,
use: [
/* config.module.rule('sass').oneOf('normal') */
{
loader: 'vue-style-loader',
options: {
sourceMap: false,
shadowMode: false
}
},
/* config.module.rule('scss').oneOf('normal').use('css-loader') */
{
loader: 'css-loader',
options: {
sourceMap: false,
importLoaders: 2
}
},
/* config.module.rule('scss').oneOf('normal').use('postcss-loader') */
{
loader: 'postcss-loader',
options: {
sourceMap: false
}
},
/* config.module.rule('scss').oneOf('normal').use('sass-loader') */
{
loader: 'sass-loader',
options: {
sourceMap: false,
data: '@import "@/scss/_variables.scss";@import "@/scss/_mixins.scss";'
}
}
]
}
注意:
webpack打包的時(shí)候按照數(shù)組從后往前的順序?qū)①Y源交給loader處理,因?yàn)樽詈笊У?
style-loader放前面。-
關(guān)于PostCSS的處理
postcss-loader將PostCSS與Webpack連接,在根目錄下創(chuàng)建postcss.config.js.Autoprefixer:根據(jù)caniuse.com的數(shù)據(jù),決定是否給css增加前綴
stylelint: CSS 代碼質(zhì)量檢測(cè)工具(語法錯(cuò)誤,重復(fù)屬性)
CSSNext:使用最新的CSS語法特性
-
CSS Module:CSS模塊化
- 每個(gè)CSS文件中的樣式擁有單獨(dú)的作用域,不會(huì)和外界發(fā)生命名沖突。
- 對(duì)CSS進(jìn)行依賴管理,可以通過相對(duì)路徑引入CSS文件
- 通過compose輕松復(fù)用其他CSS模塊
{ test: /\.css$/, use: [ 'style-loader', { loader: 'css-loader', options: { modules: true, localIdentName: '[name]__[local]__[hash:base64:5]' } } ] }
postcss.config.js內(nèi)容
const autoprefixer = require('autoprefixer');
const stylelint = require('stylelint');
module.exports = {
plugins: [
autoprefixer({
grid: true,
browsers: ['> 1%', 'last 3 versions', 'android 4.2', 'ie 8']
}),
stylelint({
config: {
rules: {
'declaration-no-important': true
}
}
})
]
}
3. babel-loader
babel-loader 處理ES6+編譯為ES5。
與此同時(shí),還需要下載幾個(gè)包:
babel-loader:Babel與Webpack協(xié)同工作的模塊(起連接作用)。
@babel/core:Babel編譯器的核心模塊。
@babel/preset-env:Babel官方推薦的預(yù)置器,可根據(jù)用戶設(shè)置的目標(biāo)環(huán)境自動(dòng)添加所需的插件和補(bǔ)丁編譯ES6+代碼。
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
cacheDirectory: true,
preset: [
['env', { module: false }]
]
}
}
}
注意:
1. babel-loader 對(duì)所有JS后綴文件設(shè)置規(guī)則,需要在exclude中添加node_modules,提升打包速度。
2. 使用cacheDirectory配置,啟用緩存機(jī)制,避免未改變過的模塊二次編譯。
3. @babel/preset-env 將ES6 Module轉(zhuǎn)化為CommonJS,導(dǎo)致Webpack的tree-shaking特性失效,將modules設(shè)置為false,禁用模塊語句轉(zhuǎn)化,將ES6 Module的語法交給Webpack本身處理。
4. babel-loader 支持從.babelrc文件讀取babel配置,將presets和plugins從webpack配置文件讀取出來,達(dá)到同樣效果。
4. file-loader
file-loader 用于處理打包文件類型的資源,返回其publicPath。
{
test: /\.(png|jpe?g|gif|webp)$/,
use: [
{
loader: 'file-loader',
options: {
name: 'static/img/[name].[hash:8].[ext]',
publicPath: './otherPath/' // 覆蓋webpack.output.publicPath
}
}
]
}
注意:
1. 如果沒有設(shè)置webpack的output的publicPath值,返回 文件名
2. 如果設(shè)置webpack的output的publicPath值,返回 webpack.output.publicPath+文件名
5. url-loader
url-loader 與 file-loader 功能類似,但是可以 設(shè)置閾值,小于該閾值則返回對(duì)應(yīng)文件的base64編碼。
{
test: /\.(png|jpe?g|gif|webp)(\?.*)?$/,
use: [
{
loader: 'url-loader',
options: {
limit: 4096,
fallback: {
loader: 'file-loader',
options: {
name: 'static/img/[name].[hash:8].[ext]'
}
}
}
}
]
}
注意:
1. 設(shè)置了limit屬性,值為4096,當(dāng)圖片大小超過4kb的時(shí)候,會(huì)被轉(zhuǎn)為base64的格式
6. vue-loader
vue-loader 處理vue組件。
但是,還需要
vue-template-compiler 編譯Vue模版
sass-loader 處理sass/scss
css-loader 處理css樣式
{
test: /\.vue$/,
use: 'vue-loader'
}
5. Plugins
5.1 VueLoaderPlugin
Vue-loader必須配合VueLoaderPlugin插件才能正常工作。
5.2 DefinePlugin
創(chuàng)建一個(gè)在編譯時(shí)可以配置的全局常量
5.3 HotModuleReplacementPlugin
模塊熱替換插件