前端最強打包工具。
為什麼要用 webpack?
我覺得最主要的原因有兩點:
- 全域變數的衝突
- 希望在瀏覽器上引入 npm 下載的套件
過去在瀏覽器上引入套件時,通常是:
1 | <!-- jQuery --> |
src
是最簡單的方法,不過現在全域空間中就有 $
和 jQuery
這兩個變數。
問題來了,如果今天有另一個套件也用 $
來命名怎麼辦?這個就是全域變數的命名衝突。
但如果是 Node.js 的話就沒有這個問題,因為我們可以這樣做:
1 | // 自己命名 |
所以後來 ES6 推出了「ES Modules」,讓瀏覽器能夠有原生的「模組機制」。
但還是有一些問題:
- 不是所有瀏覽器都能支援
- 使用上蠻麻煩的(要加上
type=module
和搭配 server 執行才能使用) - 依然沒辦法用把 node_modules 裡的東西引入進來用
永遠記得一句話:
瀏覽器不支援或支援度很差的話,就自己寫一個工具來讓它支援就好了。
所以為了解決以上問題,webpack 就誕生了。
如果我想要引入用 npm 下載的 jquery,我可以開一支檔案來寫 jQuery:
1 | // CommonJS |
不管我要在裡面用 CommonJS 或 ES modules 來引入都沒問題。我只要記得寫好後用 webpack 打包,接著在 HTML 裡面加上一句:
1 | <!-- 打包好的模組 --> |
一切就完成了,而且還真的可以跑,很神奇吧?但不要忘了,這一切都是因為有 webpack 幫你在背後做處理,否則瀏覽器不可能做得到這些。
至於為什麼 webpack 可以做到?你可以想成是「webpack 直接幫你在瀏覽器上實作 require
或 import
這兩個函式」,大概是這樣。
總而言之,再次強調:
- webpack 是用來把模組打包起來的工具
- webpack 是用來把模組打包起來的工具
- webpack 是用來把模組打包起來的工具
補充-引入時是怎麼從 npm 裡面找到的?
其實沒有什麼黑魔法,以 jQuery 的例子來說,你可以在 node_modules 裡找到 jquery,資料夾結構大概是這樣:
1 | │ AUTHORS.txt |
接著打開 package.json 搜尋 main
會看到:
1 | { |
所以這就是被引入進來的 jQuery。其他套件也是這樣運作的,真的沒有什麼黑魔法,只是這樣而已。
webpack.config 基本結構
config 是用來設定 webpack 要怎麼打包,或是一些額外資訊,這邊先寫個最簡單的架構:
1 | module.exports = { |
認識 loader
webpack 強大的地方在於它不只把 JavaScript 當作模組,甚至能把圖片、CSS 等資源都當成是模組。
為了實現這個功能,必須要有一個東西來處理,那個東西就是「loader」。
簡單來說就是把「資源」載入成「瀏覽器看的懂的東西」,這就是 loader 的負責的工作。
這邊做個示範,假設我想要在 JavaScript 裡面載入 CSS:
1 | // 兩種都可以 |
為了載入 CSS,我需要兩個 loader:
- css-loader 解析 CSS 內容
- style-loader 把 CSS 插入 DOM
接著到 config 裡面設定 rule
:
1 | module.exports = { |
接著一樣 npm run build
打包,再載入 bundle.js 就完成了。
總之呢,基本規則都是這樣:
- 找出可以解析那個檔案格式的 loader
- 設定 config 中的 rules
- 打包
所以要載入 scss 的 config 就會這樣寫:
1 | module.exports = { |
認識 plug-in
webpack 本身也有一些能用的 plug-in,這邊拿 HtmlWebpackPlugin 來舉例。
簡單來說,這個 plug-in 是用來自動產生 HTML 檔。用的方式很簡單,安裝好後設定 config 就行了:
1 | // 引入 plug-in |
template
可以指定樣板。簡單來說就是叫 webpack 用 src
底下的 HTML 來產生,這樣就能先寫好 HTML 的內容。
最後只要打包就會自動產生 index.html
。