Webpack配置

Webpack配置

1. mode:模式

  1. development:開發(fā)模式

    啟用 NamedChunksPluginNamedModulesPlugin。

    NamedChunksPlugin:把chunk id變?yōu)橐粋€(gè)字符串標(biāo)識(shí)符。

    NamedModulesPlugin:當(dāng)開啟 HMR 的時(shí)候使用該插件會(huì)顯示模塊的相對(duì)路徑,建議用于開發(fā)環(huán)境。

  2. production:生產(chǎn)模式

    啟用 FlagDependencyUsagePlugin, FlagIncludedChunksPlugin, ModuleConcatenationPlugin, NoEmitOnErrorsPlugin, OccurrenceOrderPlugin, SideEffectsFlagPluginUglifyJsPlugin。

    FlagDependencyUsagePlugin:

    FlagIncludedChunksPlugin:

    ModuleConcatenationPlugin

    NoEmitOnErrorsPlugin

    OccurrenceOrderPlugin

    SideEffectsFlagPlugin

    UglifyJsPlugin

  3. 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'));
        })
}

注意:

  1. Webpack默認(rèn),bundle.js文件大于250KB(壓縮前)會(huì)認(rèn)為文件過大,會(huì)發(fā)生警告。
  2. 通過多入口將vendor(包含庫,框架等第三方不常用模塊打包產(chǎn)生的bundle)打包,提升效率
  3. 配置多頁應(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

注意:

  1. 開發(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ǔ)的位置
}

注意:

  1. 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í)各種各樣的資源文件。

原理:

  1. 每個(gè)loader本身就是一個(gè)函數(shù)
  2. webpack4之前,函數(shù)輸入和輸出都是字符串
  3. webpack4之后,函數(shù)輸入和輸出支持抽象語法樹(AST),目的減少重復(fù)代碼解析
  4. 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-loadercss-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";'
            }
        }
        ]
}

注意:

  1. webpack打包的時(shí)候按照數(shù)組從后往前的順序?qū)①Y源交給loader處理,因?yàn)樽詈笊У?style-loader 放前面。

  2. 關(guān)于PostCSS的處理

    1. postcss-loader 將PostCSS與Webpack連接,在根目錄下創(chuàng)建 postcss.config.js.

    2. Autoprefixer:根據(jù)caniuse.com的數(shù)據(jù),決定是否給css增加前綴

    3. stylelint: CSS 代碼質(zhì)量檢測(cè)工具(語法錯(cuò)誤,重復(fù)屬性)

    4. CSSNext:使用最新的CSS語法特性

    5. CSS Module:CSS模塊化

      1. 每個(gè)CSS文件中的樣式擁有單獨(dú)的作用域,不會(huì)和外界發(fā)生命名沖突。
      2. 對(duì)CSS進(jìn)行依賴管理,可以通過相對(duì)路徑引入CSS文件
      3. 通過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-loaderfile-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

模塊熱替換插件

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容