進(jìn)階篇——webpack進(jìn)階用法(三)

??上一章節(jié)主要介紹了webpack的進(jìn)階篇中的一些高階功能的使用和配置,這些還能在代碼中進(jìn)行一些配置、構(gòu)建?,F(xiàn)在來主要介紹一些webpack4特性原理分析,可能會(huì)比較枯燥,但是很實(shí)用。

1.Tree Shaking的使用和與案例分析

QQ截圖20200822173328.png

注:當(dāng)mode設(shè)置production的時(shí)候TreeShaking是默認(rèn)開啟的

(1)什么是DCE

我們了解tree shaking的之前,就要先了解一個(gè)概念DCE。

QQ截圖20200822175116.png

意思就是說沒有用到的代碼,就會(huì)被“殺死”;什么是DCE代碼呢?如上圖左邊寫的要求:
代碼不被執(zhí)行,不可到達(dá):不會(huì)執(zhí)行的代碼,如if(false) {}這條if就回永遠(yuǎn)不被執(zhí)行;
代碼執(zhí)行的結(jié)果不會(huì)被用到:這句話的含義是指定義了一個(gè)函數(shù),并且return一個(gè)結(jié)果,但是在調(diào)用這個(gè)函數(shù)時(shí),這個(gè)結(jié)果永遠(yuǎn)不會(huì)用到;
代碼只會(huì)影響死變量(只寫不讀):這句話的含義是當(dāng)我們定義了一個(gè)變量,并且給這個(gè)變量設(shè)置了數(shù)據(jù),但是永遠(yuǎn)沒有用到這個(gè)變量。
只要符合上述的三個(gè)要求,就是DCE代碼,在構(gòu)建的過程中就會(huì)把這些代碼刪除掉,不會(huì)打包到bundle中。

(2)tree shaking原理
QQ截圖20200822193309.png
(3)tree shaking 實(shí)戰(zhàn)演練
① 自定義一個(gè)js文件
QQ截圖20200822202315.png
② 在js文件里應(yīng)用a方法
QQ截圖20200822202726.png
③ 配置webpack.prod.js
  1. 未開啟tree shaking的情況
    設(shè)置modenone,因?yàn)閠ree shaking在mode為production的情況下是默認(rèn)開啟的,npm run build構(gòu)建項(xiàng)目,情況如下
    QQ截圖20200822203558.png

    可以看到我們只是在js文件中只引用了a方法,但是沒有進(jìn)行任何的調(diào)用,構(gòu)建的時(shí)候把這兩個(gè)方法都打包了進(jìn)來,顯然會(huì)增加項(xiàng)目的體積
  2. 開啟tree shaking的情況
    設(shè)置modeproduction
    QQ截圖20200822204035.png

    可以發(fā)現(xiàn)這兩個(gè)方法都沒有引用進(jìn)來
  3. 使用a方法,并且開啟tree shaking


    QQ截圖20200822204321.png

    構(gòu)建項(xiàng)目


    QQ截圖20200822204510.png

    可見a方法是調(diào)用到了,再來搜索一下b方法
    QQ截圖20200822204629.png

    b方法并沒有加載進(jìn)來,從而達(dá)到了tree shaking的目的。

  4. 其他


    QQ截圖20200822204911.png

    上述情況,雖然引用了a方法,看看構(gòu)建的時(shí)候是否將a方法引用了進(jìn)來


    QQ截圖20200822205041.png

    可以看到a方法并沒有打包進(jìn)來。

2.Scope Hoisting使用和原理分析

我們先來看下webpack在沒有使用該特性的情況下,webpack構(gòu)件時(shí)的包效果如下

QQ截圖20200823152157.png

可以發(fā)下產(chǎn)生了很多的閉包函數(shù),這樣會(huì)產(chǎn)生什么樣的后果呢?如下
QQ截圖20200823152443.png

這就有個(gè)問題,為什么webpack打包會(huì)產(chǎn)生這么多的閉包呢?是因?yàn)?strong>模塊轉(zhuǎn)換
QQ截圖20200823152709.png

QQ截圖20200823152925.png

(1)scope hoisting原理
QQ截圖20200823153629.png
(2)scope hoisting使用
QQ截圖20200823153809.png
(3)實(shí)戰(zhàn)演練
① 未開啟scope hoisting的情況
QQ截圖20200823155932.png

構(gòu)建項(xiàng)目


QQ截圖20200823160501.png
① 開啟scope hoisting的情況
QQ截圖20200823160907.png

構(gòu)建項(xiàng)目


QQ截圖20200823161202.png

3.代碼分割和動(dòng)態(tài)import

前面學(xué)過基礎(chǔ)庫分離,講述過SplitChunksPlugin插件,將頁面進(jìn)行分離,但這只是基礎(chǔ)分離,現(xiàn)在來看一下高階的代碼分割和動(dòng)態(tài)import

QQ截圖20200823205013.png

(1)js懶加載的方式
QQ截圖20200823211434.png

有兩種懶加載的方式,如上圖所述

  1. CommonJS: require.ensure;
  2. 動(dòng)態(tài)import(推薦);
    目前動(dòng)態(tài)import能夠兼容好webpack。這節(jié)主要講述import
(2)如何使用動(dòng)態(tài)import
QQ截圖20200823211843.png

分割后的效果如下


QQ截圖20200823211957.png
(2)動(dòng)態(tài)import實(shí)戰(zhàn)演練

第一步安裝babel插件
npm install @babel/plugin-syntax-dynamic-import --save-dev
第二步
配置.babelrc文件

QQ截圖20200823212916.png

第三步創(chuàng)建一個(gè)text.js文件,如下
QQ截圖20200823213034.png

第四步在index.js下做如下配置
QQ截圖20200823213644.png

最后一步:npm run build

4.webpack中使用eslint

使用eslint能夠規(guī)范代碼,便于團(tuán)隊(duì)合作,能夠避免一些不必要的錯(cuò)誤。

QQ截圖20200829173634.png

QQ截圖20200829173841.png

QQ截圖20200829174106.png

QQ截圖20200829174158.png

QQ截圖20200829174330.png

QQ截圖20200829174420.png

5.webpack 打包庫和組件

面試題

QQ截圖20200829175513.png

壓縮版:適用于開發(fā)階段;
非壓縮版:適用于發(fā)布上線;
QQ截圖20200829185906.png

QQ截圖20200829190010.png

除了上面的引用方式還支持
QQ截圖20200829190130.png

QQ截圖20200829190208.png

(1)實(shí)戰(zhàn)演練
① 創(chuàng)建項(xiàng)目
mkdir large-number
cd large-number
npm init
② 搭建webpack環(huán)境

npm install webpack webpack-cli -D

③ 重構(gòu)項(xiàng)目目錄
360截圖18720120496570.png

src/index.js代碼如下

export default function add(a, b) {
    let i = a.length - 1;
    let j = b.length - 1;
    let carry = 0;
    let ret = '';
    while(i >= 0 || j >= 0) {
        let x = 0;
        let y = 0;
        let sum;

        if(i >= 0) {
            x = a[i] - '0';  // 轉(zhuǎn)成數(shù)字
            i--;
        }
        if(j >= 0) {
            y = b[j] - '0';  // 轉(zhuǎn)成數(shù)字
            j--;
        }

        sum = x + y + carry;
        if(sum >= 10) {
            carry = 1;
            sum -= 10;
        } else {
            carry = 0;
        }

        ret = sum + ret;
    }

    if(carry) {
        ret = carry + ret;
    }

    return ret;
}

// add('999', '1');
④ 編寫webpack配置文件
module.exports = {
    entry: {
        'large-number': './src/index.js',
        'large-number.min': './src/index.js'
    },
    output: {
        filename: '[name].js',
        library: 'largeNumber',
        libraryTarget: 'umd',
        libraryExport: 'default'
    }
}
// libraryExport:最好設(shè)置成default,不然引用的時(shí)候,就要在方法后面加上default,顯得過于冗余
⑤ 配置package.json文件
360截圖1872012274119115.png
⑥ 打包構(gòu)建

npm run build

360截圖17981130393752.png

然后打開項(xiàng)目目錄中的dist文件夾
360截圖181412139211391.png

我們打開這兩個(gè)文件,發(fā)現(xiàn)都被壓縮了,不符合我們的需求(開發(fā)版是非壓縮版,非開發(fā)版是壓縮版),那么怎么辦呢?如下
360截圖17610611143017.png

如上圖,將mode設(shè)置成none,關(guān)閉默認(rèn)壓縮,然后添加一個(gè)optimization,將minimize設(shè)置成true,然后通過配置minimizer設(shè)置正則匹配,只對(duì)mini.js進(jìn)行壓縮即可。
注:我們使用了TerserPlugin這個(gè)壓縮插件,他可以針對(duì)ES6的語法進(jìn)行壓縮,如果使用有些插件,就不會(huì)針對(duì)es6進(jìn)行壓縮,可能會(huì)報(bào)錯(cuò),所以推薦使用TerserPlugin,因此我們要先安裝一下這個(gè)插件
npm install terser-webpack-plugin -D
安裝好之后,在webpack.config.js頭部導(dǎo)入進(jìn)來
360截圖16700618425050.png

最后重新打包,發(fā)現(xiàn)只有mini.js文件進(jìn)行了壓縮
360截圖17891230399281.png

總結(jié)

這借主要介紹了一寫webpack的原理,下節(jié)是進(jìn)階的完結(jié)篇來源

?著作權(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),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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