亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

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

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

理解 module、chunk 和 bundle

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

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

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

hash 的分類

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

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

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

hash

  • compilation

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

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

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

    • 此時我們配置 webpack 的 output 為 hash

      //  此時項目的
      mode: 'production',
      entry: {
          app: [path.resolve(__dirname, '../src/index.js')],
      },
      output: {
          filename: 'js/[name].[hash].js',
          hashDigestLength: 7,
          path: path.resolve(__dirname, '../dist'),
          publicPath: './',
      },
      
    • 項目依賴打包情況如下,我們可以看到所有的 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ù),主要是指:在瀏覽器運行過程中,webpack 用來連接模塊化應(yīng)用程序所需的所有代碼。它包含:在模塊交互時,連接模塊所需的加載和解析邏輯。包括:已經(jīng)加載到瀏覽器中的連接模塊邏輯,以及尚未加載模塊的延遲加載邏輯
  • manifest

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

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

                  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)容計算出的 hash 值,很顯然,hash 并不適合做本地持久化,所以我們使用 chunkhash 此時修改 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
    
  • 這個時候修改 list.js,然后繼續(xù)打包,css 的 hash 變了,正常因為它使用的是 hash 不是 chunkhash,list 的 hash 也變了,正常因為我們修改了這個文件,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
    ```
    
  • 這個時候我們?yōu)?list.js 引入一個新的 js,css 改變我們暫且不論,這個時候發(fā)現(xiàn) vendors.js, app.js, work.js 竟然全部改變了, 這不符合我們的預(yù)期,這是因為每個 module.id 會基于默認(rèn)的解析順序(resolve order)進行增量(類似于沒有指定 key 的 react 的組件的渲染)。也就是說,當(dāng)解析順序發(fā)生變化,ID 也會隨之改變,所以我們需要自己命名這個 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
    ```
    
  • 我們自己命名這個 ID 把,命名的方式如下

    // 將默認(rèn)的數(shù)字 id 命名規(guī)則換成路徑的方式。webpack 4 中當(dāng) mode 為 development 會默認(rèn)啟動
    optimization: {
        namedModules: true
    }
    // 但是如果把路徑作為ID難免太長,所以我們使用HashedModuleIdsPlugin來生成hash
    plugins: [
        new webpack.HashedModuleIdsPlugin(),
    ],
    
    // 此時進行打包的結(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
    
  • 此時為 list 再次 import 一個文件,打包之后 hash 的值是,此時我們發(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

  • 之前我們還有一個遺留問題,就是 css 的 hash 每次都會產(chǎn)生變化,是因為我們之前配置了抽離的 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 的值就不會每次都發(fā)生變化了,此時我們對項目進行打包,然后修改 work.js 我們會發(fā)現(xiàn) css 的 hash 并沒有發(fā)生(此處不在嘗試) 任何變化,完全符合我們的預(yù)期,但是我們卻發(fā)現(xiàn),我們是以 chunk 做 hash,所以導(dǎo)致了一個問題,list.js 和 list.css 的 hash 值一摸一樣,因為他們屬于同一個 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
    ```
    
  • 對 app.css 做修改,然后重新打包,打包結(jié)果如下,我們發(fā)現(xiàn),app.css 的 hash 發(fā)生了變化,但是 app.js 的 hash 也發(fā)生了變化,這就是因為 app.css 和 app.js 屬于同一個 chunk,所以這個時候我們就必須對 css 單獨處理讓他根據(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ā)生了改變,這又是為什么呢,通過試驗是因為 CSS moduley 引起的問題,因為 css 文件的改變也會改變到 js,初步猜測是 css module 的問題,經(jīng)過試驗發(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
    ```
    
  • 后來一想,其實跟上面的 app.js 和 app.css hash 一樣是同樣的問題,app.js 的改變,就是會改變 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
    
        /* 移除一個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 對moduleIds & chunkIds的優(yōu)化,不在是以數(shù)字作為id

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

如何使用 hash 做緩存呢?

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

Etag - Last-Modified

  • 1、客戶端請求一個頁面 A

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

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

  • 4、客戶再次請求頁面 A,并將上次請求時服務(wù)器返回的 Last-Modified/ETag 一起傳遞給服務(wù)器,也就是說發(fā)送 If-None-Match 頭,這個頭的內(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 和一個空的響應(yīng)體,當(dāng)然響應(yīng)頭也會包含 Last-Modified(Mon, 22 Mar 2018 10:10:10 GMT)和 ETag(2e681a-6-5d044840)

Cache-control

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

  • 打開新窗口

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

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

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

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

Expires

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

  • Expires 指定一個絕對的過期時間(GMT 格式)

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

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

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

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

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

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

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

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

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

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

      • 服務(wù)器收到請求,進行緩存的新鮮度再驗證:

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

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

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

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

max-age 配合 hash 做使用

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

/* 具體設(shè)置多少,個人覺得要看升級的頻率,在保證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)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • BootStrap中的表單大全

    BootStrap中的表單大全

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

最新評論