前端系統(tǒng)學(xué)習(xí) 2. 模塊化

1. 無模塊化

實(shí)現(xiàn):文件分離俺泣,順序?qū)?/p>

缺點(diǎn):污染全局作用域罗侯,變量名沖突導(dǎo)致的報(bào)錯(cuò)

2. IIFE (Immediately-invoked Function Expression)

實(shí)現(xiàn):利用函數(shù)塊級(jí)作用域

const iifeModule = (function(){

  let count = 1
  function increase () {
    return ++count
  }
  function reset () {
    return count = 0
  }
  return {
    increase,
    reset
  }

})()

iifeModule.increase()
iifeModule.reset()

優(yōu)化IIFE,加入模塊依賴

模塊導(dǎo)入使用 iife 傳參月杉,模塊導(dǎo)出使用 iife 的返回值

const iifeModule = (function(dependency1, dependency2){
  let count = 1
  function increase () {
    return ++count
  }
  function reset () {
    return count = 0
  }
  return {
    increase,
    reset
  }
})(dependency1, dependency2)

iifeModule.increase()
iifeModule.reset()

Revealing Module Pattern

揭示模式模仿了 OOP 的思想刃跛,隱藏私有變量,只暴露公有變量和函數(shù)來操作私有變量

IIFE 優(yōu)點(diǎn):

  • 從語法側(cè)解決了全局變量作用域的問題苛萎,有了模塊的雛形

IIFE 缺點(diǎn):

  • 多余的語法代碼
  • 除了解決作用域的問題桨昙,其他的復(fù)雜場(chǎng)景問題一概沒有考慮

3. CJS - Commonjs

nodejs 的模塊化方案

每個(gè)文件就是一個(gè)模塊,有自己的作用域首懈。在一個(gè)文件里面定義的變量绊率、函數(shù)谨敛、類究履,都是私有的,對(duì)其他文件不可見脸狸。

CJS 規(guī)范

CommonJS規(guī)范規(guī)定最仑,每個(gè)模塊內(nèi)部,module變量代表當(dāng)前模塊炊甲。這個(gè)變量是一個(gè)對(duì)象泥彤,它的exports屬性(即module.exports)是對(duì)外的接口。加載某個(gè)模塊卿啡,其實(shí)是加載該模塊的module.exports屬性吟吝。
require方法用于加載模塊

const dep1 = require('dep1Module')
const dep2 = require('dep2Module')

// use object dep1 do sth
...

exports.a = a
exports.b = b

// Or
module.exports = {
  a, b
}

實(shí)現(xiàn)邏輯

使用

(function (require, module, exports) {
  // use require
  require(...)

  // use exports
  exports.a = a

  // use module.exports
  module.exports = {
    a
  }

})()

// require 模擬
function require(dep) {
  // 定義閉包bm'ld
  const module = {}
  module.exports = {}

  const code = file.readFileSync('dep')

  // 函數(shù)執(zhí)行完成之后,module.exports 將會(huì)被賦值
  new Function('require', 'module', 'exports', code)(require, module, exports)

  // 導(dǎo)出 dep 的 emodule.exports
  return module.exports
}
  • 優(yōu)點(diǎn)
    CommonJS 率先在服務(wù)端實(shí)現(xiàn)了颈娜,從框架層面解決全局變量污染剑逃、依賴的問題
  • 缺點(diǎn)
    主要是服務(wù)端的解決方案,不適用于客戶端異步拉取依賴的場(chǎng)景

拋出新的問題 —— 異步依賴

4. AMD (Asynchronous Module Definition)

通過異步加載 + 允許定制回調(diào)

經(jīng)典實(shí)現(xiàn)框架:require.js

定義方式

/**
* 通過 define 定義一個(gè)模塊官辽,然后通過 require 進(jìn)行加載
* 最后一個(gè)參數(shù)是 工廠方法
**/
define(id, [...deps], callback)
require([...module], callback)

模塊的定義

define('myModule', ['dep1', 'dep2'], (dep1, dep2) => {
  // 業(yè)務(wù)邏輯
  let count = 0;
  const increase = () => ++count;
  const reset = () => {
    count = 0;
  }

  return {
    increase, reset
  }
})

模塊的引入

require(['myModule'], myModule => {
  myModule.increase()
})
  • 優(yōu)點(diǎn):解決了瀏覽器異步加載依賴場(chǎng)景的問題蛹磺,可以并行加載多個(gè)模塊
  • 缺點(diǎn):不能按需加載

5. UMD (Universal Module Definition)

UMD 頂部一般有這樣一段代碼來兼容 CJS 和 AMD

(function(root, factory) {
  if (typeof define === 'function' && define.amd) {
    // AMD
    define(['jquery', factory])
  } else if (typeof 'exports' === 'object') {
    // CJS
    module.exports = factory(require('jquery'))
  } else {
    // 將模塊綁定在全局變量上
    // 這里的 root.jQuery 也是之前已經(jīng)綁定了的 module
    root.myModule = factory(root.jQuery)
  }
})(this, function ($) {
  // myModule 業(yè)務(wù)代碼
  return {
    a,
    b
  }
})
  • 優(yōu)點(diǎn):兼容 AMD 和 CJS,可以在雙端運(yùn)行
  • 缺點(diǎn):未解決 AMD 無法按需加載的問題

6. CMD (Common Module Definition)

規(guī)范draft

主要應(yīng)用框架 sea.js

require & require.async

  • require 導(dǎo)入同步模塊
  • require.async 導(dǎo)入異步模塊同仆,第二個(gè)參數(shù)是 callback
define('myModule', (require, exports, module) => {
  let $ = require('jquery')
  // jquery 相關(guān)邏輯
  ...

  let dep1 = require.async(['dep1'], dep1 => {
    // dep1 module 相關(guān)業(yè)務(wù)邏輯
    ...

  })

})
  • 優(yōu)點(diǎn):按需加載萤捆,同時(shí)支持同步和異步 require
  • 缺點(diǎn):依賴打包,加載邏輯存在于每個(gè)模塊中,模塊體積擴(kuò)大

ESM

使用

import 導(dǎo)入模塊
export 導(dǎo)出模塊俗或,export default 導(dǎo)出默認(rèn)模塊

import dep1 from 'dep1'

// 業(yè)務(wù)邏輯
let count = 0
export const increase = () => ++count
export const reset = () => count = 0

export default {
  increase, reset
}

模板引入

<script type="module" src="myModule.js"></script>

node 端引入市怎,mjs

import { increase, reset } from './myModule.mjs'

increase()
reset()

動(dòng)態(tài)導(dǎo)入

ES11 原生解決方案

import('dep').then(dep => {
  ...
})
  • 優(yōu)點(diǎn):官方提出的統(tǒng)一形態(tài)的模塊化,解決了上面遇到的各種問題
    (模塊作用域辛慰、依賴導(dǎo)入導(dǎo)出焰轻、異步導(dǎo)入等)
  • 缺點(diǎn):本質(zhì)上還是運(yùn)行時(shí)的依賴分析

解決模塊化的新思路 —— 前端工程化

背景

根本問題 —— 運(yùn)行時(shí)的依賴分析

方案:編譯時(shí)分析依賴,同時(shí)優(yōu)化項(xiàng)目
grunt gulp webpack vite

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末昆雀,一起剝皮案震驚了整個(gè)濱河市辱志,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌狞膘,老刑警劉巖揩懒,帶你破解...
    沈念sama閱讀 212,884評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異挽封,居然都是意外死亡已球,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,755評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門辅愿,熙熙樓的掌柜王于貴愁眉苦臉地迎上來智亮,“玉大人,你說我怎么就攤上這事点待±龋” “怎么了?”我有些...
    開封第一講書人閱讀 158,369評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵癞埠,是天一觀的道長(zhǎng)状原。 經(jīng)常有香客問我,道長(zhǎng)苗踪,這世上最難降的妖魔是什么颠区? 我笑而不...
    開封第一講書人閱讀 56,799評(píng)論 1 285
  • 正文 為了忘掉前任,我火速辦了婚禮通铲,結(jié)果婚禮上毕莱,老公的妹妹穿的比我還像新娘。我一直安慰自己颅夺,他們只是感情好朋截,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,910評(píng)論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著碗啄,像睡著了一般质和。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上稚字,一...
    開封第一講書人閱讀 50,096評(píng)論 1 291
  • 那天饲宿,我揣著相機(jī)與錄音厦酬,去河邊找鬼。 笑死瘫想,一個(gè)胖子當(dāng)著我的面吹牛仗阅,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播国夜,決...
    沈念sama閱讀 39,159評(píng)論 3 411
  • 文/蒼蘭香墨 我猛地睜開眼减噪,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了车吹?” 一聲冷哼從身側(cè)響起筹裕,我...
    開封第一講書人閱讀 37,917評(píng)論 0 268
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎窄驹,沒想到半個(gè)月后朝卒,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,360評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡乐埠,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,673評(píng)論 2 327
  • 正文 我和宋清朗相戀三年抗斤,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片丈咐。...
    茶點(diǎn)故事閱讀 38,814評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡瑞眼,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出棵逊,到底是詐尸還是另有隱情伤疙,我是刑警寧澤,帶...
    沈念sama閱讀 34,509評(píng)論 4 334
  • 正文 年R本政府宣布歹河,位于F島的核電站掩浙,受9級(jí)特大地震影響花吟,放射性物質(zhì)發(fā)生泄漏秸歧。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,156評(píng)論 3 317
  • 文/蒙蒙 一衅澈、第九天 我趴在偏房一處隱蔽的房頂上張望键菱。 院中可真熱鬧,春花似錦今布、人聲如沸经备。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,882評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽侵蒙。三九已至,卻和暖如春傅蹂,著一層夾襖步出監(jiān)牢的瞬間纷闺,已是汗流浹背算凿。 一陣腳步聲響...
    開封第一講書人閱讀 32,123評(píng)論 1 267
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留犁功,地道東北人氓轰。 一個(gè)月前我還...
    沈念sama閱讀 46,641評(píng)論 2 362
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像浸卦,于是被迫代替她去往敵國(guó)和親署鸡。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,728評(píng)論 2 351

推薦閱讀更多精彩內(nèi)容