講 Webpack 之前,先講 module 概念


Posted by tzutzu858 on 2021-04-21

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










Related Posts

[Week 2] JavaScript - 變數、陣列、物件、== 與 ===

[Week 2] JavaScript - 變數、陣列、物件、== 與 ===

[ 紀錄 ] 實戰練習 - 部落格 (以 Express 實作前端 + 後端)

[ 紀錄 ] 實戰練習 - 部落格 (以 Express 實作前端 + 後端)

Sass 實戰

Sass 實戰


Comments