webpack入門筆記(2)

前言:承接之前的webpack學習,請看完入門筆記1後再看本章內容

webpack入門筆記(1)

第 7 章:Webpack 配置詳情

7.1 entry

entry: 入口起點

  1. string --> './src/index.js',單入口
    打包形成一個 chunk。 輸出一個 bundle 文件。此時 chunk 的名稱默認是 main
  2. array --> ['./src/index.js', './src/add.js'],多入口
    所有入口文件最終只會形成一個 chunk,輸出出去只有一個 bundle 文件。
    (一般只用在 HMR 功能中讓 html 熱更新生效)
  3. object,多入口
    有幾個入口文件就形成幾個 chunk,輸出幾個 bundle 文件,此時 chunk 的名稱是 key 值

--> 特殊用法:

1 entry: {
2   // 最終只會形成一個chunk, 輸出出去只有一個bundle文件。
3   index: ['./src/index.js', './src/count.js'], 
4   // 形成一個chunk,輸出一個bundle文件。
5   add: './src/add.js'
6 }

 

7.2 output

 1 output: {
 2   // 文件名稱(指定名稱+目錄)
 3   filename: 'js/[name].js',
 4   // 輸出文件目錄(將來所有資源輸出的公共目錄)
 5   path: resolve(__dirname, 'build'),
 6   // 所有資源引入公共路徑前綴 --> 'imgs/a.jpg' --> '/imgs/a.jpg'
 7   publicPath: '/',
 8   chunkFilename: 'js/[name]_chunk.js', // 指定非入口chunk的名稱
 9   library: '[name]', // 打包整個庫後向外暴露的變量名
10   libraryTarget: 'window' // 變量名添加到哪個上 browser:window
11   // libraryTarget: 'global' // node:global
12   // libraryTarget: 'commonjs' // conmmonjs模塊 exports
13 },

 

7.3 module

 1 module: {
 2   rules: [
 3     // loader的配置
 4     {
 5       test: /\.css$/,
 6       // 多個loader用use
 7       use: ['style-loader', 'css-loader']
 8     },
 9     {
10       test: /\.js$/,
11       // 排除node_modules下的js文件
12       exclude: /node_modules/,
13       // 只檢查src下的js文件
14       include: resolve(__dirname, 'src'),
15       enforce: 'pre', // 優先執行
16       // enforce: 'post', // 延後執行
17       // 單個loader用loader
18       loader: 'eslint-loader',
19       options: {} // 指定配置選項
20     },
21     {
22       // 以下配置只會生效一個
23       oneOf: []
24     }
25   ]
26 },

 

7.4 resolve

 1 // 解析模塊的規則
 2 resolve: {
 3   // 配置解析模塊路徑別名: 優點:當目錄層級很複雜時,簡寫路徑;缺點:路徑不會提示
 4   alias: {
 5     $css: resolve(__dirname, 'src/css')
 6   },
 7   // 配置省略文件路徑的後綴名(引入時就可以不寫文件後綴名了)
 8   extensions: ['.js', '.json', '.jsx', '.css'],
 9   // 告訴 webpack 解析模塊應該去找哪個目錄
10   modules: [resolve(__dirname, '../../node_modules'), 'node_modules']
11 }

 

這樣配置後,引入文件就可以這樣簡寫:import '$css/index';

7.5 dev server

 1 devServer: {
 2   // 運行代碼所在的目錄
 3   contentBase: resolve(__dirname, 'build'),
 4   // 監視contentBase目錄下的所有文件,一旦文件變化就會reload
 5   watchContentBase: true,
 6   watchOptions: {
 7     // 忽略文件
 8     ignored: /node_modules/
 9   },
10   // 啓動gzip壓縮
11   compress: true,
12   // 端口號
13   port: 5000,
14   // 域名
15   host: 'localhost',
16   // 自動打開瀏覽器
17   open: true,
18   // 開啓HMR功能
19   hot: true,
20   // 不要顯示啓動服務器日誌信息
21   clientLogLevel: 'none',
22   // 除了一些基本信息外,其他內容都不要顯示
23   quiet: true,
24   // 如果出錯了,不要全屏提示
25   overlay: false,
26   // 服務器代理,--> 解決開發環境跨域問題
27   proxy: {
28     // 一旦devServer(5000)服務器接收到/api/xxx的請求,就會把請求轉發到另外一個服務器3000
29     '/api': {
30       target: 'http://localhost:3000',
31       // 發送請求時,請求路徑重寫:將/api/xxx --> /xxx (去掉/api)
32       pathRewrite: {
33         '^/api': ''
34       }
35     }
36   }
37 }

 

其中,跨域問題:同源策略中不同的協議、端口號、域名就會產生跨域。

正常的瀏覽器和服務器之間有跨域,但是服務器之間沒有跨域。代碼通過代理服務器運行,所以瀏覽器和代理服務器之間沒有跨域,瀏覽器把請求發送到代理服務器上,代理服務器替你轉發到另外一個服務器上,服務器之間沒有跨域,所以請求成功。代理服務器再把接收到的響應響應給瀏覽器。這樣就解決開發環境下的跨域問題。

7.6 optimization

contenthash 緩存會導致一個問題:修改 a 文件導致 b 文件 contenthash 變化。

因爲在 index.js 中引入 a.js,打包後 index.js 中記錄了 a.js 的 hash 值,而 a.js 改變,其重新打包後的 hash 改變,導致 index.js 文件內容中記錄的 a.js 的 hash 也改變,從而重新打包後 index.js 的 hash 值也會變,這樣就會使緩存失效。(改變的是a.js文件但是 index.js 文件的 hash 值也改變了)

解決辦法:runtimeChunk --> 將當前模塊記錄其他模塊的 hash 單獨打包爲一個文件 runtime,這樣 a.js 的 hash 改變只會影響 runtime 文件,不會影響到 index.js 文件

 1 output: {
 2   filename: 'js/[name].[contenthash:10].js',
 3   path: resolve(__dirname, 'build'),
 4   chunkFilename: 'js/[name].[contenthash:10]_chunk.js' // 指定非入口文件的其他chunk的名字加_chunk
 5 },
 6 optimization: {
 7   splitChunks: {
 8     chunks: 'all',
 9     /* 以下都是splitChunks默認配置,可以不寫
10     miniSize: 30 * 1024, // 分割的chunk最小爲30kb(大於30kb的才分割)
11     maxSize: 0, // 最大沒有限制
12     minChunks: 1, // 要提取的chunk最少被引用1次
13     maxAsyncRequests: 5, // 按需加載時並行加載的文件的最大數量爲5
14     maxInitialRequests: 3, // 入口js文件最大並行請求數量
15     automaticNameDelimiter: '~', // 名稱連接符
16     name: true, // 可以使用命名規則
17     cacheGroups: { // 分割chunk的組
18       vendors: {
19         // node_modules中的文件會被打包到vendors組的chunk中,--> vendors~xxx.js
20         // 滿足上面的公共規則,大小超過30kb、至少被引用一次
21         test: /[\\/]node_modules[\\/]/,
22         // 優先級
23         priority: -10
24       },
25       default: {
26         // 要提取的chunk最少被引用2次
27         minChunks: 2,
28         prority: -20,
29         // 如果當前要打包的模塊和之前已經被提取的模塊是同一個,就會複用,而不是重新打包
30         reuseExistingChunk: true
31       }
32     } */
33   },
34   // 將index.js記錄的a.js的hash值單獨打包到runtime文件中
35   runtimeChunk: {
36     name: entrypoint => `runtime-${entrypoint.name}`
37   },
38   minimizer: [
39     // 配置生產環境的壓縮方案:js/css
40     new TerserWebpackPlugin({
41       // 開啓緩存
42       cache: true,
43       // 開啓多進程打包
44       parallel: true,
45       // 啓用sourceMap(否則會被壓縮掉)
46       sourceMap: true
47     })
48   ]
49 }

 

第 8 章:webpack5

此版本重點關注以下內容:

  • 通過持久緩存提高構建性能.
  • 使用更好的算法和默認值來改善長期緩存.
  • 通過更好的樹搖和代碼生成來改善捆綁包大小.
  • 清除處於怪異狀態的內部結構,同時在 v4 中實現功能而不引入任何重大更改.
  • 通過引入重大更改來爲將來的功能做準備,以使我們能夠儘可能長時間地使用 v5.

1.下載

  • npm i webpack@next webpack-cli -D

2.自動刪除 Node.js Polyfills

 

早期,webpack 的目標是允許在瀏覽器中運行大多數 node.js 模塊,但是模塊格局發生了變化,許多模塊用途現在主要是爲前端目的而編寫的。webpack <= 4 附帶了許多 node.js 核心模塊的 polyfill,一旦模塊使用任何核心模塊(即 crypto 模塊),這些模塊就會自動應用。

儘管這使使用爲 node.js 編寫的模塊變得容易,但它會將這些巨大的 polyfill 添加到包中。在許多情況下,這些 polyfill 是不必要的。webpack 5 會自動停止填充這些核心模塊,並專注於與前端兼容的模塊。

 

遷移:

  •  儘可能嘗試使用與前端兼容的模塊。
  • 可以爲 node.js 核心模塊手動添加一個 polyfill。錯誤消息將提示如何實現該目標。

 

3.Chunk 和模塊 ID

添加了用於長期緩存的新算法。在生產模式下默認情況下啓用這些功能。

chunkIds: "deterministic", moduleIds: "deterministic"

Chunk ID

你可以不用使用 import(/* webpackChunkName: "name" */ "module") 在開發環境來爲 chunk 命名,生產環境還是有必要的

webpack 內部有 chunk 命名規則,不再是以 id(0, 1, 2)命名了

4.Tree Shaking

  1. webpack 現在能夠處理對嵌套模塊的 tree shaking
 1 // inner.js
 2 export const a = 1;
 3 export const b = 2;
 4 
 5 // module.js
 6 import * as inner from './inner';
 7 export { inner };
 8 
 9 // user.js
10 import * as module from './module';
11 console.log(module.inner.a);

 

在生產環境中, inner 模塊暴露的 b 會被刪除

  1. webpack 現在能跟多個模塊之前的關係
1 import { something } from './something';
2 
3 function usingSomething() {
4   return something;
5 }
6 
7 export function test() {
8   return usingSomething();
9 }

 

 

當設置了"sideEffects": false時,一旦發現test方法沒有使用,不但刪除test,還會刪除"./something"

  1. webpack 現在能處理對 Commonjs 的 tree shaking

 

5.Output

 

webpack 4 默認只能輸出 ES5 代碼

webpack 5 開始新增一個屬性 output.ecmaVersion, 可以生成 ES5 和 ES6 / ES2015 代碼.

如:output.ecmaVersion: 2015

 

6.SplitChunk

 

1 // webpack4
2 minSize: 30000;
3  
4 
5 // webpack5
6 minSize: {
7   javascript: 30000,
8   style: 50000,
9 }

 

7.Caching

1 // 配置緩存
2 cache: {
3   // 磁盤存儲
4   type: "filesystem",
5   buildDependencies: {
6     // 當配置修改時,緩存失效
7     config: [__filename]
8   }
9 }

緩存將存儲到 node_modules/.cache/webpack

8.監視輸出文件

 之前 webpack 總是在第一次構建時輸出全部文件,但是監視重新構建時會只更新修改的文件。

 此次更新在第一次構建時會找到輸出文件看是否有變化,從而決定要不要輸出全部文件。

 

9.默認值

  • entry: "./src/index.js
  • output.path: path.resolve(__dirname, "dist")
  • output.filename: "[name].js"

 

 

 

其他

webpack入門筆記(1)

webpack官網:https://www.webpackjs.com/concepts/

其他優秀的webpack推薦:Webpack4不求人系列(共5篇)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章