常見(jiàn),但是總回答不好的面試題:JS 模塊化以及模塊打包器
Hello,大家好,我是 Sunday。
如今的前端已經(jīng)是一套非常復(fù)雜的體系了,甚至延伸出來(lái)了所謂“微前端”的概念。而支撐這些復(fù)雜邏輯的前提就是 模塊化 的概念。
但是,我在和很多的同學(xué)溝通(做技術(shù)摸底)的過(guò)程中,卻發(fā)現(xiàn):很多同學(xué)并不清楚模塊化的知識(shí)。
這個(gè)說(shuō)實(shí)話(huà),開(kāi)發(fā)天天用,但是猛地這么一背問(wèn),很多同學(xué)都沒(méi)有回答的很好。
所以說(shuō),今天咱們就借助這邊文章,來(lái)說(shuō)一說(shuō):模塊化 以及 模塊打包器!
什么是模塊?
在 JavaScript 中,模塊就像一個(gè)單獨(dú)的代碼包,我們可以在程序的不同部分中使用它。
該包被封裝在指定的范圍內(nèi),可重用且易于維護(hù)。
圖片
如上圖所示:它可以通過(guò)將代碼分解為更易于使用的、更小的部分 來(lái)幫助保持代碼的組織性。
通常情況下:每一個(gè) JS 文件都將是一個(gè)模塊! 所以,我們可以 簡(jiǎn)單的 把一個(gè)模塊理解為一個(gè) js 文件(注意:這只是簡(jiǎn)單的理解)
JS 的模塊化體系
最初的時(shí)候,JS 是不支持任何模塊系統(tǒng)的。所以,就產(chǎn)生了很多 社區(qū)模塊化規(guī)范,比較常見(jiàn)的有:
- AMD
- CMD
- UMD
- ...
不過(guò)好處是,這些模塊化規(guī)范,在現(xiàn)在的開(kāi)發(fā)中幾乎已經(jīng)不可見(jiàn)了。除了 UMD 規(guī)范,在庫(kù)打包中依然存在。
所以,從目前來(lái)看,我們不需要深入了解它們。
雖然,以上的社區(qū)化規(guī)范,我們不需要深入了解。但是,目前常用的 兩種 模塊化方式,大家必須要知道:
- CommonJS:主要應(yīng)用在 Node 端。以 module.exports 導(dǎo)出,以 require 導(dǎo)入。
module.exports = {
name: '張三'
}
-----
const {name} = require('路徑')
- ES6 Module:主要應(yīng)用在 瀏覽器端。以 export(按需導(dǎo)出) 或者 export default(默認(rèn)導(dǎo)出) 導(dǎo)出,以 import 導(dǎo)入
export const name = '張三' // 可以寫(xiě)多個(gè)
// 一個(gè)模塊(JS文件)只能寫(xiě)一個(gè)
export default {
name: '李四'
}
-----
import {name} from '路徑' // 按需導(dǎo)入
import obj from '路徑' // 默認(rèn)導(dǎo)入
模塊打包器
常見(jiàn)的模塊打包器有很多,比如:Webpack、Vite、Rollup、Parcel、Browserify 等等。
他們的作用主要是:把一個(gè)或多個(gè)模塊,按照?qǐng)?zhí)行的順序添加到 html 文件中。打包出來(lái)的的內(nèi)容,一般被稱(chēng)為 bundle
圖片
而隨著前端項(xiàng)目的復(fù)雜度越來(lái)越高,這些打包器也被賦予了更多的能力,比如:
- 使用Tree Shaking過(guò)程從包中刪除未使用的代碼
- 通過(guò)減少獲取模塊所需的 HTTP 請(qǐng)求數(shù)量來(lái)優(yōu)化 Javascript 的加載
- 還包括代碼壓縮、捆綁包分割和代碼分塊等功能,以進(jìn)一步優(yōu)化捆綁包大小
- 甚至還而已自定義 loader 或 plugin 來(lái)賦予它們更多的能力
答案
那么最后,讓我們回答這個(gè)問(wèn)題:
JS 中的模塊化指的是 代碼和邏輯分割 的一種方式。通常,我們可以簡(jiǎn)單的把一個(gè)js文件理解為一個(gè)模塊。
最初的 JS 中并不支持模塊化,因此延伸出來(lái)很多社區(qū)模塊化方案,比如:AMD、UMD,但是目前除了 UMD 之外,其他都已經(jīng)很少見(jiàn)了。
現(xiàn)在,常用的模塊化主要有兩種:CJS(Node 端)、ESM(瀏覽器端)。
隨著前端項(xiàng)目越來(lái)越復(fù)雜,又延伸出來(lái)模塊打包器的概念。特別是在一些框架的使用中,這是非常有用的。