Webpack 是一個打包程式碼必備 bundler
為什麼需要 Webpack
webpack is a module bundler.
module 翻譯成模組或大陸翻譯叫模塊,模組的概念就是當你完成一個程式或 function 或每一個功能,例如在 jQuery 還沒誕生之前,你寫了一個類似 jQuery 的 library,但你要怎麼分享出去 ? 最簡單方法可能是寫一個 function 或檔案給別人,別人就去用。
舉幾個例子來說
Node.js 的模組
在 Node.js 創一個 utils.js
檔案
const Utils = {
first: function (str) {
return str[0]
},
last: function (str) {
return str[str.length - 1]
}
}
module.exports = Utils
假設我寫了兩個超棒的 function (痾...先假裝一下他是很棒的 function)
那這樣別人的 js 檔案,就可以使用 require
這個語法來引入, const utils = require('./utils')
然後去使用他就好,console.log(utils.first('ya'))
所以 Node.js 模組使用的概念就是用 module.exports
這個語法打包
使用時,用 require
把模組給引入
但這並不是在 JavaScript 的規範裡面,而是一套叫做「CommonJS」的標準。
browser 的模組
在瀏覽器上面不太一樣,我們從來沒有在瀏覽器用過 require
的語法
為什麼沒有 ? 因為瀏覽器不支援
之前在用 jQuery 的時候,都是 <script src = "code.jquery.com/jquery-3.1.1.js"></script>
這樣就有個全域變數可以用,例如 $
或 jQuery
匿名衝突
如果我自己寫一個 library 叫做 tzu library 好了,我想說我也要取一個很短的暱稱,剛好就是用 $
但如果別人同時引用兩個 library 的時候,一個 jQuery
一個我寫的 tzu library
,那這樣可能就不知道 $
字號到底是代表 jQuery
還是我寫的tzu library
因此 jQuery 提供一個 function 叫做 jQuery.noConflict(),當有衝突時可以用 .noConflict()
去解決衝突,通常用 global 變數命名的都會有這種問題,瀏覽器因為沒有 require
的語法,他也只能這樣子用,但回到 Node.js 不會有這問題是因為在 import 時,前面可以自己命名,我要叫const aaa = require('./utils')
或是 const bbb = require('./utils')
隨你開心。
總結 module 模組化
要拉回來一點,模組化就是把東西包好,要給別人用,那要怎麼用 ? 上面有講到 Node.js 和 browser 兩個不同例子, Node.js 用 module.exports
打包,require
去引入,瀏覽器則是透過全域變數。
其實早期時瀏覽器因為沒有模組的機制真的很不方便,因此有些人就時做了一些規範,比如說
不同的模組化規範
CommonJS , AMD , UMD
這些規範就像是各家牌子的充電線,功能目的都是一樣的,都是充電傳輸,但是他的頭長的不太一樣
所以不同的模組化規範他們的目的都是一樣,但背後的規範不太一樣
但上述規範都不是官方規範,直到...
ES Modules
瀏覽器原生支援一個規範叫做 ES Modules,屬於 ES6 的語法
用法 : export 和 import
開一個 utils.js
檔案
export function first(str) {
return str[0]
}
開另一個 index.js
檔案
import { first } from './utils.js'
console.log(first('abc'))
在 html 引入時,記得要加 type="module"
瀏覽器才看得懂
<script src = "./index.js" type="module"></script>
如果上述檔案要測試執行,沒辦法用檔案的方式直接打開,必須要開一個 server ,再來因為這些規範比較新,在舊的瀏覽器上面沒有辦法跑
結論 :
瀏覽器沒有支援的東西,用個工具自己轉換就好了
所以有些工具可以用這些模組化的規範,透過某個程式做些事情就可以丟到瀏覽器上面執行
拉回到 Webpack
Webpack 就是把 module 全部包在一起做些轉換便可以在瀏覽器上執行
因此官網才會說 webpack is a module bundler.
其實他把這個概念推得更廣一點
不只 module 還有其它圖片之類的
官網才會有 bundle your images 、 bundle your scripts 、 bundle your styles、 bundle your assets