iT邦幫忙

2022 iThome 鐵人賽

DAY 20
0
Modern Web

前端技能樹的十萬個為什麼系列 第 20

Day 20 - 為什麼要用 Webpack

  • 分享至 

  • xImage
  •  

前言

前天介紹的 Babel,以及昨天介紹的 ES module,處理了一些關於程式碼編譯轉換,以及模組化的概念

有了它們之後,還需要一個整合性的工具,將這些零散的東西整合起來,今天來討論 Webpack。

先想一下

  • Webpack 是在什麼樣的時代誕生的?
  • Webpack 怎麼解決問題?
  • Webpack 的優缺點是什麼?
  • Webpack 適合什麼情境?

Webpack 是在什麼樣的時代誕生的?

我們已經有像是 ES module、CommonJS、AMD 等模組化工具,可以將 js 程式碼切割成多個模組,再透過 import / export 之類的語法,將模組組合起來

不過光有模組還不夠,畢竟除了自己寫的模組,也會需要引用一些從 npm 或 yarn 安裝的外部模組,外部安裝的模組會放在 node_modules 裡面,雖然可以把它們的路徑寫成這樣:

import XXX from './node_modules/xxx/index.js'

這樣其實是相對不方便的,閱讀性也比較差

同時,還需要處理各種模組工具的差異,比如 ES module 是用 import / export,而 CommonJS 則是用 require / module.exports需要一個工具能夠整合這些差異

另外,以上都只討論到純 js 的需求,如果今天想要把 html、css 甚至圖片檔案讀進來 js 裡面使用,都還沒有比較好的方式可以支援。

Webpack 怎麼解決問題?

Webpack 是一個 module bundler,顧名思義就是「將模組打包起來」的工具。

「模組」我們已經知道是透過 ES module 或 CommonJS 產生的,那「打包」呢?Webpack 的「打包」其實包含了很多事情,主要可以透過兩種設定來完成:

Loaders

Loaders 主要負責的是「將資源轉換為可讀取的模組」,是一種檔案的前處理,比如 html、css、TypeScript 甚至圖片檔案,都有相對應的 loader 可以處理:

module.exports = {
  module: {
    rules: [
      { test: /\.css$/, use: 'css-loader' },
      { test: /\.ts$/, use: 'ts-loader' },
      { test: /\.html$/, use: 'html-loader' },
    ],
  },
};

甚至針對有處理順序的檔案,也可以安排 bottom-up 的 chain 來處理,比如 sass -> css -> style:

  1. 將 sass 語法轉換為 css
  2. 將 css 樣式轉換為 JavaScript
  3. 將轉換後的 JavaScript 變成真正的 CSS 樣式,透過 <style> tag 插入 DOM tree
module.exports = {
  module: {
    rules: [
      {
        test: /\.css$/,
        use: ["style-loader", "css-loader", "sass-loader"]
      }
    ]
  }
};

更多可以參考官網列出來的 loaders 清單,甚至不夠用還可以自己用 Node.js 寫。

Plugins

Plugins 負責的是 loaders 做不到的事情,可以參考官網列出來的 plugins 清單

比如可以做到 Hot Module Replacement(HMR),也就是當我們成功打包過程式碼後,因為開發過程會頻繁去修改某些模組,但又不希望每次改幾行 code 就整個重新打包,這時就需要 HMR plugin 來幫忙,僅有修改到的局部模組重新打包,可以大幅提升開發效率。

另外像是圖片壓縮、程式碼 minify、uglify,以及 css 檔案分離等,都可以用 plugins 做到。

Webpack 建構流程

  1. 讀取 Webpack 的 config 參數檔案
  2. 從 entry 裡設定的入口檔案開始,如樹狀般,遞迴尋找其依賴的模組
  3. 每找到一個模組,就會根據設定的 loaders 做對應的轉換
  4. 這些模組會以 entry 為單位分組,一個 entry 與其依賴的所有模組被分為一個 chunk
  5. 最後 Webpack 會把所有 chunk 轉換 bundle 輸出
  6. 整個流程中,Webpack 會透過發布訂閱模式,在某些事件時機執行 plugin 裡的邏輯

Webpack 的優缺點是什麼?

優點

  • 兼容 CommonJS、AMD、ES module 規範
  • Tree shaking,針對一些實質上沒有被用到的模組,自動移除不打包
  • 多樣化的 loaders、plugins,強大的社群

缺點

Webpack 功能之多,也導致 config 設定檔相對困難,要寫出一個打包流程「不多不少剛剛好」的設定檔,往往需要一些時間嘗試,或者一開始就用 create-react-app 等建構工具自動完成。建議一開始就好好將 Webpack 設定檔寫好。

Webpack 適合什麼情境?

只要是使用模組化方式開發的程式碼,都非常適合使用 Webpack,基本上想不太到什麼不使用的理由,畢竟以現在複雜的程式環境來說,常常混雜了許多不同的資源,透過 Webpack 這樣的打包工具,能夠讓專注力更加集中在開發上面!

結語

心智圖放大版

Webpack 做掉的事情之多,可能需要一次鐵人賽 30 天的時間才講得完吧XD 實在很難在一天之內寫完,不過起碼抓住最核心的一些應用,以及為什麼使用 Webpack 的理由,我想只有在掌握了這一點之後,再循序漸進去理解每個 loader 與 plugin,才會更加事半功倍!

參考資料

Webpack
為什麼前端需要工程化? — webpack


上一篇
Day 19 - 為什麼要用 ES Module
下一篇
Day 21 - 為什麼要用 npm
系列文
前端技能樹的十萬個為什麼30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言