欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

一文搞懂webpack?hash持久化的原理

 更新時(shí)間:2022年06月20日 11:01:10   作者:chrisPaul101755  
本文主要介紹了webpack?hash持久化的原理,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

理解 module、chunk 和 bundle

  • module 就是我們通過 import 引入的各種模塊

  • chunk 是 webpack 根據(jù)功能拆分出來的模塊,包括入口文件, 動(dòng)態(tài) import,lazy 等的文件以及 splitChunks 拆分出來的代碼,chunk 可能包含多個(gè) module

  • bundle 就是 webpack 打包之后的各個(gè)文件,于 chunk 一般一一對(duì)應(yīng)

hash 的分類

  • hash:the hash of the module identifier(根據(jù) module_id 序列的變化而變化)

  • chunkHash:the hash of the chunk content(chunkHash,根據(jù)每一個(gè) chunk 內(nèi)容的變化而變化)

  • contentHash:the hash of extracted content(根據(jù)內(nèi)容變化而變化)

hash

  • compilation

    • webpack 的 hash 是根據(jù) compilation 計(jì)算出來的,compilation 對(duì)象代表某個(gè)版本的資源對(duì)應(yīng)的編譯進(jìn)程,當(dāng)我們的文件發(fā)生改變的時(shí)候, 進(jìn)而能夠針對(duì)改動(dòng)生產(chǎn)全新的編譯文件。compilation 對(duì)象包含當(dāng)前模塊資源、待編譯文件、有改動(dòng)的文件和監(jiān)聽依賴的所有信息,如果我們修改某一個(gè)文件,那么此時(shí)整個(gè)項(xiàng)目的 hash 都會(huì)改變
  • compiler

    • compiler 對(duì)象代表的是配置完備的 Webpack 環(huán)境。 compiler 對(duì)象只在 Webpack 啟動(dòng)時(shí)構(gòu)建一次,由 Webpack 組合所有的配置項(xiàng)構(gòu)建生成,compiler 對(duì)象代表的是不變的 webpack 環(huán)境,compilation 是針對(duì)隨時(shí)可變的項(xiàng)目文件
  • module_id

    • webpack 通過給每一個(gè)模塊一個(gè) module_id 來處理各個(gè)模塊之間的依賴關(guān)系,而默認(rèn)的 id 命名規(guī)則是根據(jù)模塊引入的順序賦予一個(gè)整數(shù)(1,2,3),所以任意的增添或者刪除一個(gè)模塊的依賴,都會(huì)對(duì)整個(gè)的 ID 序列產(chǎn)生影響,最后影響 hash 值,這些模塊會(huì)被 runtime 和 manifest 和引用到
  • 對(duì)于圖片、字體、PDF 等資源該 hash 還是可以生成一個(gè)唯一值的

    • 此時(shí)我們配置 webpack 的 output 為 hash

      //  此時(shí)項(xiàng)目的
      mode: 'production',
      entry: {
          app: [path.resolve(__dirname, '../src/index.js')],
      },
      output: {
          filename: 'js/[name].[hash].js',
          hashDigestLength: 7,
          path: path.resolve(__dirname, '../dist'),
          publicPath: './',
      },
      
    • 項(xiàng)目依賴打包情況如下,我們可以看到所有的 hash 的值都是一樣的

                      Asset       Size  Chunks                                Chunk Names
                css/app.2f3933e.css   52 bytes       0  [emitted] [immutable]         app
               css/list.2f3933e.css    1.5 KiB       1  [emitted] [immutable]         list
            css/vendors.2f3933e.css   71.2 KiB       2  [emitted] [immutable]         vendors
         css/vendors.2f3933e.css.gz   7.85 KiB          [emitted]
                         index.html   1.33 KiB          [emitted]
                  js/app.2f3933e.js   6.63 KiB       0  [emitted] [immutable]         app
                 js/list.2f3933e.js   50.9 KiB       1  [emitted] [immutable]         list
         js/list.2f3933e.js.LICENSE   120 bytes         [emitted]
              js/list.2f3933e.js.gz     15 KiB          [emitted]
              js/vendors.2f3933e.js    340 KiB       2  [emitted] [immutable]  [big]  vendors
      js/vendors.2f3933e.js.LICENSE  423 bytes          [emitted]
           js/vendors.2f3933e.js.gz   91.8 KiB          [emitted]
                 js/work.2f3933e.js  188 bytes       3  [emitted] [immutable]         work
      

runtime 和 manifest

  • webpack 通過 runtime 和 manifest 來管理所有模塊的交互

  • runtime

    • runtime,以及伴隨的 manifest 數(shù)據(jù),主要是指:在瀏覽器運(yùn)行過程中,webpack 用來連接模塊化應(yīng)用程序所需的所有代碼。它包含:在模塊交互時(shí),連接模塊所需的加載和解析邏輯。包括:已經(jīng)加載到瀏覽器中的連接模塊邏輯,以及尚未加載模塊的延遲加載邏輯
  • manifest

    • 當(dāng) compiler 開始執(zhí)行、解析和映射應(yīng)用程序時(shí),它會(huì)保留所有模塊的詳細(xì)要點(diǎn)。這個(gè)數(shù)據(jù)集合稱為 "manifest",當(dāng)完成打包并發(fā)送到瀏覽器時(shí),runtime 會(huì)通過 manifest 來解析和加載模塊。無論你選擇哪種 模塊語法,那些 import 或 require 語句現(xiàn)在都已經(jīng)轉(zhuǎn)換為 webpack_require 方法,此方法指向模塊標(biāo)識(shí)符(module identifier)。通過使用 manifest 中的數(shù)據(jù),runtime 將能夠檢索這些標(biāo)識(shí)符,找出每個(gè)標(biāo)識(shí)符背后對(duì)應(yīng)的模塊
  • runtime 和 manifest 是一個(gè)每次打包都可能變化的不穩(wěn)定的因素,所以他會(huì)導(dǎo)致一些問題,比如,我們對(duì)整個(gè)項(xiàng)目的文章在做一次打包,打包結(jié)果如下,我們發(fā)現(xiàn),我們什么也沒有改動(dòng)但是 hash 全部發(fā)生了變化,原因就是 runtime 和 manifest 這些所謂的樣板文件

                    Asset       Size  Chunks                                Chunk Names
                 css/app.2f3933e.css   52 bytes       0  [emitted] [immutable]         app
                css/list.2f3933e.css    1.5 KiB       1  [emitted] [immutable]         list
             css/vendors.2f3933e.css   71.2 KiB       2  [emitted] [immutable]         vendors
          css/vendors.2f3933e.css.gz   7.85 KiB          [emitted]
                          index.html   1.33 KiB          [emitted]
                   js/app.2f3933e.js   6.63 KiB       0  [emitted] [immutable]         app
                  js/list.2f3933e.js   50.9 KiB       1  [emitted] [immutable]         list
          js/list.2f3933e.js.LICENSE  120 bytes          [emitted]
                js/list.2f3933e.js.gz     15 KiB          [emitted]
                js/vendors.2f3933e.js    340 KiB       2  [emitted] [immutable]  [big]  vendors
        js/vendors.2f3933e.js.LICENSE  423 bytes          [emitted]
              js/vendors.2f3933e.js.gz   91.8 KiB          [emitted]
                    js/work.2f3933e.js  188 bytes       3  [emitted] [immutable]         work
    
  • 如何解決這個(gè)問題

    • 我們可以把 runtime 和 manifest 提取出來,去掉這兩個(gè)不穩(wěn)定因素,然后打包發(fā)現(xiàn) hash 并未改變,但是我們多了一個(gè) mainfest 文件
    optimization: {
        runtimeChunk: {
            name: 'manifest',
        },
    }
    
    • 再次打包代碼,不斷的打包 hash 都不會(huì)改變

                  Asset       Size  Chunks                                Chunk Names
                css/app.c870f3f.css        52 bytes        0  [emitted] [immutable]         app
               css/list.c870f3f.css        1.5 KiB         1  [emitted] [immutable]         list
            css/vendors.c870f3f.css        71.2 KiB        3  [emitted] [immutable]         vendors
         css/vendors.c870f3f.css.gz        7.85 KiB           [emitted] index.html 1.4 KiB [emitted]
                  js/app.c870f3f.js        3.62 KiB        0  [emitted][immutable] app
                 js/list.c870f3f.js        50.9 KiB        1  [emitted][immutable] list
         js/list.c870f3f.js.LICENSE        120 bytes          [emitted]
              js/list.c870f3f.js.gz        15 KiB             [emitted]
             js/manifest.c870f3f.js        3.07 KiB         2 [emitted][immutable] manifest
              js/vendors.c870f3f.js        340 KiB          3 [emitted][immutable] [big] vendors
      js/vendors.c870f3f.js.LICENSE       423 bytes          [emitted]
           js/vendors.c870f3f.js.gz       91.8 KiB           [emitted]
                 js/work.c870f3f.js       188 bytes        4 [emitted][immutable] work
      

chunkhash

  • chunk 就是模塊。chunkhash 也就是根據(jù)模塊內(nèi)容計(jì)算出的 hash 值,很顯然,hash 并不適合做本地持久化,所以我們使用 chunkhash 此時(shí)修改 webpack 的配置

    ```javascript
    optimization: webpackBase.optimization,
    mode: 'production',
    entry: {
        app: [path.resolve(__dirname, '../src/index.js')],
    }
    ```
    
  • 修改配置之后打包的結(jié)果是(CSS 的結(jié)果還是一樣的,我們稍后處理)

                Asset       Size  Chunks                                Chunk Names
                css/app.8b9de76.css   71.3 KiB       0  [emitted] [immutable]         app
             css/app.8b9de76.css.gz   7.88 KiB          [emitted]
             css/vendors.8b9de76.css    1.5 KiB       3  [emitted] [immutable]         vendors
                          index.html   1.27 KiB          [emitted]
                   js/app.0df5dd7.js    340 KiB       0  [emitted] [immutable]  [big]  app
           js/app.0df5dd7.js.LICENSE  423 bytes          [emitted]
                 js/app.0df5dd7.js.gz   92.5 KiB          [emitted]
                   js/list.111956e.js   2.48 KiB       1  [emitted] [immutable]         list
               js/manifest.aa8eb6d.js   3.13 KiB       2  [emitted] [immutable]         manifest
                js/vendors.49e3e7f.js   48.5 KiB       3  [emitted] [immutable]         vendors
        js/vendors.49e3e7f.js.LICENSE  120 bytes          [emitted]
             js/vendors.49e3e7f.js.gz   13.8 KiB          [emitted]
                   js/work.1b2fd82.js  188 bytes       4  [emitted] [immutable]         work
    
  • 這個(gè)時(shí)候修改 list.js,然后繼續(xù)打包,css 的 hash 變了,正常因?yàn)樗褂玫氖?hash 不是 chunkhash,list 的 hash 也變了,正常因?yàn)槲覀冃薷牧诉@個(gè)文件,work 的 hash 并沒有變化,完全正常

    ```javascript
            Asset       Size  Chunks                                Chunk Names
                     css/app.1a93a35.css   71.3 KiB       0  [emitted] [immutable]         app
                  css/app.1a93a35.css.gz   7.88 KiB          [emitted]
                  css/vendors.1a93a35.css    1.5 KiB       3  [emitted] [immutable]         vendors
                               index.html   1.27 KiB          [emitted]
                        js/app.0df5dd7.js    340 KiB       0 [emitted] [immutable]  [big]  app
                js/app.0df5dd7.js.LICENSE  423 bytes         [emitted]
                     js/app.0df5dd7.js.gz   92.5 KiB         [emitted]
                       js/list.5b187e3.js   2.48 KiB       1 [emitted] [immutable]         list
                   js/manifest.3752b77.js   3.13 KiB       2 [emitted] [immutable]         manifest
                    js/vendors.49e3e7f.js   48.5 KiB       3 [emitted] [immutable]         vendors
            js/vendors.49e3e7f.js.LICENSE   120 bytes        [emitted]
                 js/vendors.49e3e7f.js.gz   13.8 KiB         [emitted]
                       js/work.1b2fd82.js   188 bytes      4 [emitted] [immutable] work
    ```
    
  • 這個(gè)時(shí)候我們?yōu)?list.js 引入一個(gè)新的 js,css 改變我們暫且不論,這個(gè)時(shí)候發(fā)現(xiàn) vendors.js, app.js, work.js 竟然全部改變了, 這不符合我們的預(yù)期,這是因?yàn)槊總€(gè) module.id 會(huì)基于默認(rèn)的解析順序(resolve order)進(jìn)行增量(類似于沒有指定 key 的 react 的組件的渲染)。也就是說,當(dāng)解析順序發(fā)生變化,ID 也會(huì)隨之改變,所以我們需要自己命名這個(gè) moduleid

    ```javascript
            Asset       Size  Chunks                                Chunk Names
                 css/app.636f1cd.css   52 bytes       0  [emitted] [immutable]         app
                css/list.636f1cd.css    1.5 KiB       1  [emitted] [immutable]         list
             css/vendors.636f1cd.css   71.2 KiB       3  [emitted] [immutable]         vendors
          css/vendors.636f1cd.css.gz   7.85 KiB          [emitted]
                          index.html    1.4 KiB          [emitted]
                   js/app.0b4c163.js   3.62 KiB       0  [emitted][immutable] app
                  js/list.d02fa6a.js     51 KiB       1  [emitted][immutable] list
          js/list.d02fa6a.js.LICENSE  120 bytes          [emitted]
                js/list.d02fa6a.js.gz     15 KiB          [emitted]
               js/manifest.3a9ff17.js   3.09 KiB       2  [emitted][immutable]
       manifest js/vendors.a1bfd17.js    340 KiB       3  [emitted][immutable] [big] vendors
        js/vendors.a1bfd17.js.LICENSE  423 bytes          [emitted]
             js/vendors.a1bfd17.js.gz   91.8 KiB          [emitted]
                   js/work.f70d2d8.js  188 bytes         4 [emitted][immutable] work
    ```
    
  • 我們自己命名這個(gè) ID 把,命名的方式如下

    // 將默認(rèn)的數(shù)字 id 命名規(guī)則換成路徑的方式。webpack 4 中當(dāng) mode 為 development 會(huì)默認(rèn)啟動(dòng)
    optimization: {
        namedModules: true
    }
    // 但是如果把路徑作為ID難免太長,所以我們使用HashedModuleIdsPlugin來生成hash
    plugins: [
        new webpack.HashedModuleIdsPlugin(),
    ],
    
    // 此時(shí)進(jìn)行打包的結(jié)果是
    
        Asset       Size  Chunks                                Chunk Names
                  css/app.d36a7df.css   52 bytes       0  [emitted] [immutable]         app
                 css/list.d36a7df.css    1.5 KiB       1  [emitted] [immutable]         list
              css/vendors.d36a7df.css   71.2 KiB       3  [emitted] [immutable]         vendors
           css/vendors.d36a7df.css.gz   7.85 KiB          [emitted]
                           index.html    1.4 KiB          [emitted]
                    js/app.5aef12b.js   3.74 KiB      0  [emitted] [immutable]         app
                   js/list.9dbf1d7.js   51.5 KiB      1  [emitted] [immutable]         list
           js/list.9dbf1d7.js.LICENSE  120 bytes         [emitted]
                js/list.9dbf1d7.js.gz   15.7 KiB         [emitted]
               js/manifest.cf2b1ee.js   3.09 KiB      2  [emitted] [immutable]         manifest
                js/vendors.612571f.js    343 KiB      3  [emitted] [immutable]  [big]  vendors
        js/vendors.612571f.js.LICENSE  423 bytes         [emitted]
             js/vendors.612571f.js.gz   97.7 KiB         [emitted]
                   js/work.3d8d43d.js  196 bytes      4  [emitted] [immutable]         work
    
  • 此時(shí)為 list 再次 import 一個(gè)文件,打包之后 hash 的值是,此時(shí)我們發(fā)現(xiàn) app.js 的值沒有變,list 的值改變了,vendors 和 work 都沒變完全符合我們的預(yù)期,至此 js hash 的過程已經(jīng)完全結(jié)束

    ```javascript
        Asset       Size  Chunks                                Chunk Names
                css/app.39db041.css   52 bytes       0  [emitted] [immutable]         app
                css/list.39db041.css    1.5 KiB       1  [emitted] [immutable]         list
             css/vendors.39db041.css   71.2 KiB       3  [emitted] [immutable]         vendors
          css/vendors.39db041.css.gz   7.85 KiB          [emitted]
                          index.html    1.4 KiB          [emitted]
                   js/app.5aef12b.js   3.74 KiB       0  [emitted] [immutable]         app
                  js/list.a0c9911.js   51.5 KiB       1  [emitted] [immutable]         list
          js/list.a0c9911.js.LICENSE  120 bytes          [emitted]
                js/list.a0c9911.js.gz   15.7 KiB          [emitted]
               js/manifest.14406a1.js   3.09 KiB       2  [emitted] [immutable]         manifest
                js/vendors.612571f.js    343 KiB       3  [emitted] [immutable]  [big]  vendors
        js/vendors.612571f.js.LICENSE  423 bytes          [emitted]
             js/vendors.612571f.js.gz   97.7 KiB          [emitted]
                    js/work.3d8d43d.js  196 bytes       4  [emitted] [immutable]         work
    ```
    

contentHash

  • 之前我們還有一個(gè)遺留問題,就是 css 的 hash 每次都會(huì)產(chǎn)生變化,是因?yàn)槲覀冎芭渲昧顺殡x的 css 是 hash,根據(jù)上面的文章,我們修改為 chunkhash

    ```javascript
    // 之前的配置
    miniCssExtract: new MiniCssExtractPlugin({
        filename: 'css/[name].[hash].css',
        chunkFilename: 'css/[name].[hash].css',
        ignoreOrder: false,
    });
    // 修改之后的配置
    miniCssExtract: new MiniCssExtractPlugin({
        filename: 'css/[name].[chunkhash].css',
        chunkFilename: 'css/[name].[chunkhash].css',
        ignoreOrder: false,
    });
    ```
    
  • 修改為 chunkhash 之后,當(dāng)然 css 的值就不會(huì)每次都發(fā)生變化了,此時(shí)我們對(duì)項(xiàng)目進(jìn)行打包,然后修改 work.js 我們會(huì)發(fā)現(xiàn) css 的 hash 并沒有發(fā)生(此處不在嘗試) 任何變化,完全符合我們的預(yù)期,但是我們卻發(fā)現(xiàn),我們是以 chunk 做 hash,所以導(dǎo)致了一個(gè)問題,list.js 和 list.css 的 hash 值一摸一樣,因?yàn)樗麄儗儆谕粋€(gè) chunk

    ```javascript
        Asset       Size  Chunks                                Chunk Names
                 css/app.5aef12b.css   52 bytes       0  [emitted] [immutable]         app
                css/list.a0c9911.css    1.5 KiB       1  [emitted] [immutable]         list
             css/vendors.612571f.css   71.2 KiB       3  [emitted] [immutable]         vendors
          css/vendors.612571f.css.gz   7.85 KiB          [emitted]
                          index.html    1.4 KiB          [emitted]
                   js/app.5aef12b.js   3.74 KiB       0  [emitted] [immutable]         app
                  js/list.a0c9911.js   51.5 KiB       1  [emitted] [immutable]         list
          js/list.a0c9911.js.LICENSE  120 bytes          [emitted]
                js/list.a0c9911.js.gz   15.7 KiB          [emitted]
               js/manifest.171619f.js   3.12 KiB       2  [emitted] [immutable]         manifest
                js/vendors.612571f.js    343 KiB       3  [emitted] [immutable]  [big]  vendors
        js/vendors.612571f.js.LICENSE  423 bytes          [emitted]
              js/vendors.612571f.js.gz   97.7 KiB          [emitted]
                    js/work.3d8d43d.js  196 bytes       4  [emitted] [immutable]         work
    ```
    
  • 對(duì) app.css 做修改,然后重新打包,打包結(jié)果如下,我們發(fā)現(xiàn),app.css 的 hash 發(fā)生了變化,但是 app.js 的 hash 也發(fā)生了變化,這就是因?yàn)?app.css 和 app.js 屬于同一個(gè) chunk,所以這個(gè)時(shí)候我們就必須對(duì) css 單獨(dú)處理讓他根據(jù)自己的 content 去做 hash 而不是 chunk

    ```javascript
        Asset       Size  Chunks                                Chunk Names
                  css/app.131454e.css   52 bytes       0  [emitted] [immutable]         app
                 css/list.a0c9911.css    1.5 KiB       1  [emitted] [immutable]         list
              css/vendors.612571f.css   71.2 KiB       3  [emitted] [immutable]         vendors
           css/vendors.612571f.css.gz   7.85 KiB          [emitted]
                           index.html    1.4 KiB          [emitted]
                    js/app.131454e.js   3.74 KiB       0  [emitted] [immutable]         app
                   js/list.a0c9911.js   51.5 KiB       1  [emitted] [immutable]         list
           js/list.a0c9911.js.LICENSE  120 bytes          [emitted]
                js/list.a0c9911.js.gz   15.7 KiB          [emitted]
               js/manifest.171619f.js   3.12 KiB       2  [emitted] [immutable]         manifest
                js/vendors.612571f.js    343 KiB       3  [emitted] [immutable]  [big]  vendors
        js/vendors.612571f.js.LICENSE  423 bytes          [emitted]
             js/vendors.612571f.js.gz   97.7 KiB          [emitted]
                   js/work.3d8d43d.js  196 bytes       4  [emitted] [immutable]         work
    ```
    
  • 修改配置然后重新打包代碼

    // 修改配置
    miniCssExtract: new MiniCssExtractPlugin({
        filename: 'css/[name].[contenthash].css',
        chunkFilename: 'css/[name].[contenthash].css',
        ignoreOrder: false,
    });
    
    /* 重新打包代碼如下,可以看到app.js和app.css的hash不一致了 */
        Asset       Size  Chunks                                Chunk Names
                  css/app.15e0de3.css   52 bytes       0  [emitted] [immutable]         app
                 css/list.8298c67.css    1.5 KiB       1  [emitted] [immutable]         list
              css/vendors.353f491.css   71.2 KiB       3  [emitted] [immutable]         vendors
           css/vendors.353f491.css.gz   7.85 KiB          [emitted]
                           index.html    1.4 KiB          [emitted]
                    js/app.131454e.js   3.74 KiB       0  [emitted] [immutable]         app
                   js/list.a0c9911.js   51.5 KiB       1  [emitted] [immutable]         list
           js/list.a0c9911.js.LICENSE  120 bytes          [emitted]
                js/list.a0c9911.js.gz   15.7 KiB          [emitted]
               js/manifest.88160aa.js   3.12 KiB       2  [emitted] [immutable]         manifest
                js/vendors.612571f.js    343 KiB       3  [emitted] [immutable]  [big]  vendors
        js/vendors.612571f.js.LICENSE  423 bytes          [emitted]
             js/vendors.612571f.js.gz   97.7 KiB          [emitted]
                   js/work.3d8d43d.js  196 bytes       4  [emitted] [immutable]         work
    
  • 修改 app.css,然后再次打包代碼,打包結(jié)果如下,我們發(fā)現(xiàn) 除了 app.css hash 改變,app.js 的 hash 一樣的發(fā)生了改變,這又是為什么呢,通過試驗(yàn)是因?yàn)?CSS moduley 引起的問題,因?yàn)?css 文件的改變也會(huì)改變到 js,初步猜測(cè)是 css module 的問題,經(jīng)過試驗(yàn)發(fā)現(xiàn)即使去掉 cssMOdule 還是有同樣的問題

    ```javascript
                                    Asset       Size  Chunks                                Chunk Names
             css/app.29ae3c7.css   52 bytes       0  [emitted] [immutable]         app
             css/list.8298c67.css    1.5 KiB       1  [emitted] [immutable]         list
          css/vendors.353f491.css   71.2 KiB       3  [emitted] [immutable]         vendors
       css/vendors.353f491.css.gz   7.85 KiB          [emitted]
                       index.html    1.4 KiB          [emitted]
                js/app.3bafc2a.js   3.74 KiB       0  [emitted] [immutable]         app
               js/list.a0c9911.js   51.5 KiB       1  [emitted] [immutable]         list
       js/list.a0c9911.js.LICENSE  120 bytes          [emitted]
            js/list.a0c9911.js.gz   15.7 KiB          [emitted]
           js/manifest.88160aa.js   3.12 KiB       2  [emitted] [immutable]         manifest
            js/vendors.612571f.js    343 KiB       3  [emitted] [immutable]  [big]  vendors
    js/vendors.612571f.js.LICENSE  423 bytes          [emitted]
         js/vendors.612571f.js.gz   97.7 KiB          [emitted]
               js/work.3d8d43d.js  196 bytes       4  [emitted] [immutable]         work
    ```
    
  • 后來一想,其實(shí)跟上面的 app.js 和 app.css hash 一樣是同樣的問題,app.js 的改變,就是會(huì)改變 chunk 的值,所以把修改 webpack 的配置如下

            Asset       Size  Chunks                                Chunk Names
                css/app.44b7866.css   38 bytes       0  [emitted] [immutable]         app
               css/list.8298c67.css    1.5 KiB       1  [emitted] [immutable]         list
            css/vendors.353f491.css   71.2 KiB       3  [emitted] [immutable]         vendors
          css/vendors.353f491.css.gz   7.85 KiB          [emitted]
                          index.html    1.4 KiB          [emitted]
                   js/app.ca738c5.js   3.67 KiB       0  [emitted] [immutable]         app
                  js/list.1895c1a.js   51.5 KiB       1  [emitted] [immutable]         list
          js/list.1895c1a.js.LICENSE  120 bytes          [emitted]
               js/list.1895c1a.js.gz   15.7 KiB          [emitted]
               js/manifest.b7ee988.js   3.12 KiB       2  [emitted] [immutable]         manifest
                js/vendors.38fec86.js    343 KiB       3  [emitted] [immutable]  [big]  vendors
        js/vendors.38fec86.js.LICENSE  423 bytes          [emitted]
             js/vendors.38fec86.js.gz   97.7 KiB          [emitted]
                   js/work.ea3817c.js  196 bytes       4  [emitted] [immutable]         work
    
    /* 修改css之后然后再次打包,果然解決了之前的問題 */
    
        Asset       Size  Chunks                                Chunk Names
                 css/app.208b221.css   39 bytes       0  [emitted] [immutable]         app
                css/list.8298c67.css    1.5 KiB       1  [emitted] [immutable]         list
             css/vendors.353f491.css   71.2 KiB       3  [emitted] [immutable]         vendors
           css/vendors.353f491.css.gz   7.85 KiB          [emitted]
                           index.html    1.4 KiB          [emitted]
                    js/app.ca738c5.js   3.67 KiB       0  [emitted] [immutable]         app
                   js/list.1895c1a.js   51.5 KiB       1  [emitted] [immutable]         list
           js/list.1895c1a.js.LICENSE  120 bytes          [emitted]
                js/list.1895c1a.js.gz   15.7 KiB          [emitted]
               js/manifest.b7ee988.js   3.12 KiB       2  [emitted] [immutable]         manifest
                js/vendors.38fec86.js    343 KiB       3  [emitted] [immutable]  [big]  vendors
        js/vendors.38fec86.js.LICENSE  423 bytes          [emitted]
             js/vendors.38fec86.js.gz   97.7 KiB          [emitted]
                   js/work.ea3817c.js  196 bytes       4  [emitted] [immutable]         work
    
        /* 移除一個(gè)list引用的模塊,再次打包,完全符合預(yù)期 */
                Asset       Size  Chunks                                Chunk Names
                  css/app.208b221.css   39 bytes       0  [emitted] [immutable]         app
                 css/list.8298c67.css    1.5 KiB       1  [emitted] [immutable]         list
              css/vendors.353f491.css   71.2 KiB       3  [emitted] [immutable]         vendors
           css/vendors.353f491.css.gz   7.85 KiB          [emitted]
                           index.html    1.4 KiB          [emitted]
                    js/app.ca738c5.js   3.67 KiB       0  [emitted] [immutable]         app
                   js/list.271a546.js   51.5 KiB       1  [emitted] [immutable]         list
           js/list.271a546.js.LICENSE  120 bytes          [emitted]
                js/list.271a546.js.gz   15.7 KiB          [emitted]
               js/manifest.a2e6ed1.js   3.12 KiB       2  [emitted] [immutable]         manifest
                js/vendors.38fec86.js    343 KiB       3  [emitted] [immutable]  [big]  vendors
        js/vendors.38fec86.js.LICENSE  423 bytes          [emitted]
             js/vendors.38fec86.js.gz   97.7 KiB          [emitted]
                   js/work.ea3817c.js  196 bytes       4  [emitted] [immutable]         work
    

webpack5

webpack5 對(duì)moduleIds & chunkIds的優(yōu)化,不在是以數(shù)字作為id

optimization:{
    moduleIds:'deterministic',
    chunkIds:'deterministic'
},

如何使用 hash 做緩存呢?

很多人知道 hash,但是要不項(xiàng)目配置為 hash,不利于做長期緩存,要不前端配置好了,但是不知道如何配合后端做長期緩存,這就涉及到 http 緩存的

Etag - Last-Modified

  • 1、客戶端請(qǐng)求一個(gè)頁面 A

  • 2、服務(wù)器返回頁面 A,并在給 A 加上一個(gè) Last-Modified(Mon, 22 Mar 2018 10:10:10 GMT)和 ETag(2e681a-6-5d044840)

  • 3、客戶端展現(xiàn)該頁面,并將頁面連同 Last-Modified/ETag 一起緩存

  • 4、客戶再次請(qǐng)求頁面 A,并將上次請(qǐng)求時(shí)服務(wù)器返回的 Last-Modified/ETag 一起傳遞給服務(wù)器,也就是說發(fā)送 If-None-Match 頭,這個(gè)頭的內(nèi)容 就是 2e681a-6-5d044840,發(fā)送 If-Modified-Since(Mon, 22 Mar 2018 10:10:10 GMT)

  • 5、服務(wù)器判斷發(fā)送過來的 Etag 和 Last-Modified 與本地匹配,如果沒有修改,不返回 200,返回 304,直接返回響應(yīng) 304 和一個(gè)空的響應(yīng)體,當(dāng)然響應(yīng)頭也會(huì)包含 Last-Modified(Mon, 22 Mar 2018 10:10:10 GMT)和 ETag(2e681a-6-5d044840)

Cache-control

  • Cache-control 判斷瀏覽器是否需要發(fā)送請(qǐng)求而不需要服務(wù)器對(duì)比,常見的取值有 private、no-cache、max-age、must- revalidate、no-store 等,默認(rèn)為 private,Cache-control 值為“no-cache”時(shí),訪問此頁面不會(huì)在 Internet 臨時(shí)文章夾留下頁面?zhèn)浞?/p>

  • 打開新窗口

    • 值為 private、no-cache、must-revalidate,那么打開新窗口訪問時(shí)都會(huì)重新訪問服務(wù)器。 而如果指定了 max-age 值,那么在此值內(nèi)的時(shí)間里就不會(huì)重新訪問服務(wù)器,例如: Cache-control: max-age=5(表示當(dāng)訪問此網(wǎng)頁后的 5 秒 內(nèi)再次訪問不會(huì)去服務(wù)器)
  • 在地址欄回車

    • 值為 private 或 must-revalidate 則只有第一次訪問時(shí)會(huì)訪問服務(wù)器,以后就不再訪問。 值為 no-cache,那么每次都會(huì)訪問。 值為 max-age,則在過期之前不會(huì)重復(fù)訪問
  • 按后退按扭

    • 值為 private、must-revalidate、max-age,則不會(huì)重訪問, 值為 no-cache,則每次都重復(fù)訪問
  • 按刷新按扭或者 F6

    • 無論為何值,都會(huì)重復(fù)訪問

Expires

  • Expires 和 max-age 都可以用來指定文檔的過期時(shí)間,但是也有不同

  • Expires 指定一個(gè)絕對(duì)的過期時(shí)間(GMT 格式)

  • max-age 指定的是從文檔被訪問后的存活時(shí)間,這個(gè)時(shí)間是個(gè)相對(duì)值(比如:3600s),相對(duì)的是文檔第一次被請(qǐng)求時(shí)服務(wù)器記錄的 Request_time(請(qǐng)求時(shí)間)

  • 有的服務(wù)器, max-age 是這樣計(jì)算出來的,expires - request_time

靜態(tài)資源服務(wù)器的緩存

  • 如果是第一次訪問,請(qǐng)求報(bào)文首部不會(huì)包含相關(guān)字段,服務(wù)端在發(fā)送文件前做如下處理

    • 如服務(wù)器支持 ETag,設(shè)置 ETag 頭
    • 如服務(wù)器支持 Last-Modified,設(shè)置 Last-Modified 頭

    • 設(shè)置 Expires 頭 + 設(shè)置 Cache-Control 頭(設(shè)置其 max-age 值)瀏覽器收到響應(yīng)后會(huì)存下這些標(biāo)記,并在下次請(qǐng)求時(shí)帶上與 ETag 對(duì)應(yīng)的請(qǐng)求首部 If-None-Match 或與 Last-Modified 對(duì)應(yīng)的請(qǐng)求首部 If-Modified-Since

  • 如果是重復(fù)的請(qǐng)求

    • 瀏覽器判斷緩存是否過期(通過 Cache-Control 和 Expires 確定, 兩者都存在 Cache-Control為主)

      • 如果未過期,直接使用緩存內(nèi)容,也就是強(qiáng)緩存命中,并不會(huì)產(chǎn)生新的請(qǐng)求

      • 如果已過期,會(huì)發(fā)起新的請(qǐng)求,并且請(qǐng)求會(huì)帶上 If-None-Match 或 If-Modified-Since,或者兼具兩者(兩者都存在Etag 為主)

      • 服務(wù)器收到請(qǐng)求,進(jìn)行緩存的新鮮度再驗(yàn)證:

        • 首先檢查請(qǐng)求是否有 If-None-Match 首部,沒有則繼續(xù)下一步,有則將其值與文檔的最新 ETag 匹配,失敗則認(rèn)為緩存不新鮮,成功則繼續(xù)下一步

        • 接著檢查請(qǐng)求是否有 If-Modified-Since 首部,沒有則保留上一步驗(yàn)證結(jié)果,有則將其值與文檔最新修改時(shí)間比較驗(yàn)證,失敗則認(rèn)為緩存不新鮮,成功則認(rèn)為緩存新鮮

        • 當(dāng)兩個(gè)首部皆不存在或者驗(yàn)證結(jié)果是不新鮮時(shí),發(fā)送 200 及最新文件,并在首部更新新鮮度。

        • 當(dāng)驗(yàn)證結(jié)果是緩存仍然新鮮時(shí)(也就是弱緩存命中),不需發(fā)送文件,僅發(fā)送 304,并在首部更新新鮮度

max-age 配合 hash 做使用

在保持 hash 不變性的前提下,我們可以使用 max-age 來設(shè)置前端緩存

/* 具體設(shè)置多少,個(gè)人覺得要看升級(jí)的頻率,在保證hash不變性的前提下,設(shè)置1y 比較合理https://expressjs.com/zh-cn/guide/using-middleware.html */
app.use(
  express.static(path.join(__dirname, "public"), {
    maxAge: "1y",
    expires: "1y",
    Etag: false,
    lastModified: false,
  })
);

參考文章

到此這篇關(guān)于一文搞懂webpack hash持久化的原理的文章就介紹到這了,更多相關(guān)webpack hash持久化內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • BootStrap中的表單大全

    BootStrap中的表單大全

    這篇文章主要介紹了BootStrap中的表單大全,包括基礎(chǔ)表單,內(nèi)聯(lián)表單和水平表單等知識(shí),本文介紹的非常詳細(xì),具有參考借鑒價(jià)值,需要的朋友可以參考下
    2016-09-09
  • js實(shí)現(xiàn)掃雷源代碼

    js實(shí)現(xiàn)掃雷源代碼

    這篇文章主要為大家詳細(xì)介紹了js實(shí)現(xiàn)掃雷源代碼,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-11-11
  • JavaScript取得gridview中獲取checkbox選中的值

    JavaScript取得gridview中獲取checkbox選中的值

    這篇文章主要介紹了 js取得gridview中獲取checkbox選中的值,本文給大家分享兩段代碼片段,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下
    2017-07-07
  • JavaScript數(shù)據(jù)結(jié)構(gòu)與算法之棧詳解

    JavaScript數(shù)據(jù)結(jié)構(gòu)與算法之棧詳解

    這篇文章主要介紹了JavaScript數(shù)據(jù)結(jié)構(gòu)與算法之棧詳解,本文講解了對(duì)棧的操作、對(duì)棧的實(shí)現(xiàn)實(shí)例等內(nèi)容,需要的朋友可以參考下
    2015-03-03
  • JavaScript?ECMAScript?6(ES2015~ES2022)所有新特性總結(jié)

    JavaScript?ECMAScript?6(ES2015~ES2022)所有新特性總結(jié)

    這篇文章主要介紹了JavaScript?ECMAScript?6(ES2015~ES2022)所有新特性總結(jié),文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下
    2022-07-07
  • js+html5實(shí)現(xiàn)手機(jī)九宮格密碼解鎖功能

    js+html5實(shí)現(xiàn)手機(jī)九宮格密碼解鎖功能

    這篇文章主要為大家詳細(xì)介紹了js+html5實(shí)現(xiàn)手機(jī)九宮格密碼解鎖功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-07-07
  • 詳解JS實(shí)現(xiàn)系統(tǒng)登錄頁的登錄和驗(yàn)證

    詳解JS實(shí)現(xiàn)系統(tǒng)登錄頁的登錄和驗(yàn)證

    這篇文章主要介紹了JS實(shí)現(xiàn)系統(tǒng)登錄頁的登錄和驗(yàn)證,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-04-04
  • webpack 靜態(tài)資源集中輸出的方法示例

    webpack 靜態(tài)資源集中輸出的方法示例

    這篇文章主要介紹了webpack 靜態(tài)資源集中輸出的方法示例,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-11-11
  • 原生JS實(shí)現(xiàn)小小的音樂播放器

    原生JS實(shí)現(xiàn)小小的音樂播放器

    這篇文章主要為大家詳細(xì)介紹了原生JS實(shí)現(xiàn)音樂播放器,支持循環(huán)、隨機(jī)播放,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-10-10
  • 基于pako.js實(shí)現(xiàn)gzip的壓縮和解壓功能示例

    基于pako.js實(shí)現(xiàn)gzip的壓縮和解壓功能示例

    這篇文章主要介紹了基于pako.js實(shí)現(xiàn)gzip的壓縮和解壓功能,結(jié)合具體實(shí)例形式分析了pako.js實(shí)現(xiàn)字符串壓縮與解壓縮的相關(guān)操作技巧,需要的朋友可以參考下
    2017-06-06

最新評(píng)論