前端模塊化之 ES modules

前言

ES modules 是原生 JavaScript 提供的模塊功能看锉,逐漸被更多的瀏覽器開(kāi)始支持

入門(mén)篇

先了解下基礎(chǔ)用法赵刑。

html 文件中使用 ES modules 語(yǔ)法執(zhí)行 js

在 script 標(biāo)簽中 設(shè)置 type = module,瀏覽器就會(huì)以 ES modules 的標(biāo)準(zhǔn)去執(zhí)行 script 標(biāo)簽中的 JavaScript 代碼荚虚。默認(rèn)情況下洼滚,代碼是以嚴(yán)格模式執(zhí)行的歪脏。

<script type="module">
    console.log('this is es module')
</script>

私有作用域

每一個(gè)設(shè)置 type=module 的標(biāo)簽內(nèi)都會(huì)形成一個(gè)私有作用域。作用域之間的變量不能直接共享技扼。

<script type="module">
    var a = 1
    console.log(a)
</script>

<script type="module">
    console.log(a)
</script>

第 1 組 script 中的代碼正常輸出變量 a 的值伍玖,第 2 段會(huì)報(bào)以下錯(cuò)誤:a is not defined。

外鏈 JS 文件加載

ES modules 會(huì)以 CORS 方式加載外部 js 文件剿吻。提供 js 文件的服務(wù)器需要設(shè)置 CORS 后窍箍,ES modules 的 script 標(biāo)簽才能正常加載文件。

<script type="module" src="https://unpkg.com/jquery@3.6.0/dist/jquery.js"></script> //第一個(gè)文件服務(wù)器配置了CORS
<script type="module" src="https://abc.com/jquery@3.6.0/dist/jquery.js"></script> //第二個(gè)沒(méi)有配置

結(jié)果:第 1 組 script 標(biāo)簽加載成功丽旅,第 2 組加載失敗椰棘。

延遲執(zhí)行,作用與 defer 一致榄笙。

未設(shè)置 type = module 前邪狞,會(huì)先執(zhí)行完 01_demo.js 的代碼。p 標(biāo)簽的渲染會(huì)被阻塞办斑。
設(shè)置 type = module 后外恕,p 標(biāo)簽的渲染不會(huì)被阻塞。

<script src="./01_demo.js" type="module"></script>
<p>測(cè)試</p>

導(dǎo)出

導(dǎo)出方式

// module.js - 單獨(dú)導(dǎo)出
export var name = "foo module";
export class A {}
export function bar() {}

// 統(tǒng)一導(dǎo)出
var name = "foo module";
class A {}
function bar() {}
export { name, A, bar }

// app.js - 導(dǎo)入
import { name } from "./module.js";
console.log(name);

導(dǎo)出重命名

const age = 25;
export { age as Age };

默認(rèn)模塊導(dǎo)出,導(dǎo)入時(shí)也要重命名

const age = 25;
export { age as default };
export default age;

import { default as Age } from './module.js'
import Age from './module.js'
console.log(Age)

注意事項(xiàng):

1.導(dǎo)出時(shí)乡翅,export 后面不是字面量對(duì)象鳞疲。import 后面也不是對(duì)象解構(gòu)。
2.export default { name, age } 是等價(jià)于導(dǎo)出一個(gè)對(duì)象蠕蚜,export { a, b, c } 則是固定用法尚洽。
3.進(jìn)行導(dǎo)入操作時(shí),導(dǎo)入的是同一份引用靶累,是引用關(guān)系腺毫,并非值,這一點(diǎn)與 common.js 不一樣挣柬。在導(dǎo)入之后潮酒,不能對(duì)導(dǎo)入變量進(jìn)行修改,它是一個(gè)只讀的關(guān)系邪蛔。

導(dǎo)入

1.導(dǎo)入語(yǔ)句中急黎,需要指定完整路徑,不能忽略文件后綴名(但是現(xiàn)有第三包,或者其也是支持不寫(xiě)文件后綴名)勃教。而 common js 是支持忽略文件后綴名淤击。
2.路徑必須以 / 開(kāi)頭。導(dǎo)入路徑支持使用 cdn url 外鏈 js 文件的形式故源。
3.以下導(dǎo)入方式等價(jià)于執(zhí)行導(dǎo)入文件中的 js 代碼污抬。

import {} from './module.js'
import './module.js'

4.將模塊中所有內(nèi)容一次性導(dǎo)入,通過(guò)對(duì)象.變量方式訪(fǎng)問(wèn)绳军。

import * as xxx   from './module.js'

5.動(dòng)態(tài)導(dǎo)入,import() 等價(jià)于函數(shù)調(diào)用,非函數(shù)調(diào)用形式只能置于頂層印机。

import('./module.js').then(module => {
   console.log(module)
})

6.默認(rèn)成員和具名成員導(dǎo)入。

import { name, age, default as title } from './module.js'
import title, { name, age } froom './module.js'

導(dǎo)出導(dǎo)入成員

一種代碼組織方式删铃,將散落模塊組織成新模塊耳贬。

// components/button.js
export const Button = "Button component";

// components/radio.js
export const Radio = "Radio component";

// components/index.js
import { Button } from "./button.js";
import { Radio } from "./radio.js";
export { Button, Radio };
// app.js
import { Button, Radio } from "./component/index.js";
console.log(Button);
console.log(Radio);

Polyfill 篇

ES modules 是 ES6 推出的新語(yǔ)法特性,在低版本瀏覽器上需要通過(guò) Polyfill 方式去解決兼容性問(wèn)題.
script 添加 nomodule 設(shè)置猎唁,避免在正常瀏覽器出現(xiàn)代碼執(zhí)行兩次的情況咒劲。nomodule 表示當(dāng)前瀏覽器不支持 modules 的情況下加載使用。

<script nomodule src="https://unpkg.com/promise-polyfill@8.2.0/dist/polyfill.min.js"></script>
<script nomodule src="https://unpkg.com/browser-es-module-loader@0.4.1/dist/babel-browser-build.js"></script>
<script nomodule src="https://unpkg.com/browser-es-module-loader@0.4.1/dist/browser-es-module-loader.js"></script>
<script type="module">
    import { foo } from './module.js'
    console.log(foo)
</script>

Node 中應(yīng)用篇

背景

Node 中對(duì) ES modules 語(yǔ)法特性的支持還在實(shí)驗(yàn)階段诫隅。node 版本大于 8.5腐魂,腳本執(zhí)行命令添加 --experimental-modules 即可運(yùn)行 ES modules 代碼。
Node 對(duì) ES modules 特性支持的源碼

與 CommonJS 交互

1.ES modules 中可以導(dǎo)入 CommonJS 模塊逐纬。
2.CommonJS 中不能導(dǎo)入 ES modules 模塊蛔屹。
3.CommonJS 始終只會(huì)導(dǎo)出一個(gè)默認(rèn)成員。
4.import 不是解構(gòu)對(duì)象

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末豁生,一起剝皮案震驚了整個(gè)濱河市兔毒,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌甸箱,老刑警劉巖育叁,帶你破解...
    沈念sama閱讀 216,372評(píng)論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異芍殖,居然都是意外死亡豪嗽,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門(mén)豌骏,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)龟梦,“玉大人,你說(shuō)我怎么就攤上這事窃躲〖品。” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 162,415評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵蒂窒,是天一觀的道長(zhǎng)躁倒。 經(jīng)常有香客問(wèn)我赎婚,道長(zhǎng),這世上最難降的妖魔是什么樱溉? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,157評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮纬凤,結(jié)果婚禮上福贞,老公的妹妹穿的比我還像新娘。我一直安慰自己停士,他們只是感情好挖帘,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,171評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著恋技,像睡著了一般拇舀。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上蜻底,一...
    開(kāi)封第一講書(shū)人閱讀 51,125評(píng)論 1 297
  • 那天骄崩,我揣著相機(jī)與錄音,去河邊找鬼薄辅。 笑死要拂,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的站楚。 我是一名探鬼主播脱惰,決...
    沈念sama閱讀 40,028評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼窿春!你這毒婦竟也來(lái)了拉一?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 38,887評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤旧乞,失蹤者是張志新(化名)和其女友劉穎蔚润,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體良蛮,經(jīng)...
    沈念sama閱讀 45,310評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡抽碌,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,533評(píng)論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了决瞳。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片货徙。...
    茶點(diǎn)故事閱讀 39,690評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖皮胡,靈堂內(nèi)的尸體忽然破棺而出痴颊,到底是詐尸還是另有隱情,我是刑警寧澤屡贺,帶...
    沈念sama閱讀 35,411評(píng)論 5 343
  • 正文 年R本政府宣布蠢棱,位于F島的核電站锌杀,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏泻仙。R本人自食惡果不足惜糕再,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,004評(píng)論 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望玉转。 院中可真熱鬧突想,春花似錦、人聲如沸究抓。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,659評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)刺下。三九已至绑嘹,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間橘茉,已是汗流浹背工腋。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,812評(píng)論 1 268
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留畅卓,地道東北人夷蚊。 一個(gè)月前我還...
    沈念sama閱讀 47,693評(píng)論 2 368
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像髓介,于是被迫代替她去往敵國(guó)和親惕鼓。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,577評(píng)論 2 353

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