ESModule

瀏覽器實(shí)現(xiàn)的模塊化,成為瀏覽器和服務(wù)器通用的模塊解決方案。

nodejs esm

nodejs默認(rèn)把js文件默認(rèn)當(dāng)成commonjs文件加載,可以通過添加.mjs后綴修改。
.mjs文件總是以 ES6 模塊加載,.cjs文件總是以 CommonJS 模塊加載,.js文件的加載取決于package.json里面type字段的設(shè)置。
package.json

{
  "type":"module"
}

瀏覽器

scrpit標(biāo)簽加 type="module"屬性。
利用頂層的this等于undefined這個語法點(diǎn),可以偵測當(dāng)前代碼是否在 ES6 模塊之中。
const isNotModuleScript = this !== undefined;

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

相當(dāng)于

<script defer src="./foo.js"></script>

ES6 esm

ES6 模塊的設(shè)計(jì)思想是盡量的靜態(tài)化,使得編譯時就能確定模塊的依賴關(guān)系,以及輸入和輸出的變量。CommonJS 和 AMD 模塊,都只能在運(yùn)行時確定這些東西。比如,CommonJS 模塊就是對象,輸入時必須查找對象屬性。
// ES6模塊
import { stat, exists, readFile } from 'fs';

上面代碼的實(shí)質(zhì)是從fs模塊加載 3 個方法,其他方法不加載。
這種加載稱為“編譯時加載”或者靜態(tài)加載,即 ES6 可以在編譯時就完成模塊加載,效率要比 CommonJS 模塊的加載方式高

優(yōu)勢

  • 1.不再需要命名空間
  • 2.解決全局變量問題
  • 3.靜態(tài)化,打包工具tree shaking
模塊功能主要由兩個命令構(gòu)成:export和import。export命令用于規(guī)定模塊的對外接口,import命令用于輸入其他模塊提供的功能。

export 命令

export const a = 1
export const b = 1

等同于

const a = 1
const b = 1
export { a, b }
  • export 的值是引用,例如
export var foo = 'bar';
setTimeout(() => foo = 'baz', 500);
  • export的內(nèi)容不能再其它塊級作用域內(nèi)
function a() {
 export {}
}
//報(bào)錯

import命令

  • 1.import命令接受一對大括號,里面指定要從其他模塊導(dǎo)入的變量名。大括號里面的變量名,必須與被導(dǎo)入模塊(profile.js)對外接口的名稱相同。
  • 2.import具有提升效果(這種行為的本質(zhì)是,import命令是編譯階段執(zhí)行的)
foo();
import { foo } from 'my_module';
//不會報(bào)錯
  • 3.export default提供默認(rèn)輸出(相當(dāng)于默認(rèn)匿名的引用)

模塊的繼承

export *命令會忽略繼承模塊的default方法
export * from 'circle';
export var e = 2.71828182846;
export default function(x) {
  return Math.exp(x);
}
  • 4.import不支持放在其它模塊內(nèi),例如
if (x === 2) {
  import MyModual from './myModual';
}

ES2020 提案支持動態(tài)import,import()返回一個 Promise 對象,類似require(import是異步,require是同步)
之所以是異步猜測可能是考慮瀏覽器只執(zhí)行必要的文件,打包工具可以把依賴關(guān)系確定而不需要把整個文件引入,再需要的時候再創(chuàng)建script異步加載,類似于動態(tài)路由的實(shí)現(xiàn)

ESModule的加載

  • 1.傳統(tǒng)script加載會阻塞css tree和dom tree的構(gòu)建
  • 2.async 告訴瀏覽器該腳本不會阻塞頁面構(gòu)建,標(biāo)記腳本內(nèi)不會操作dom
  • 3.defer告訴瀏覽器立即下載 直到解析完畢在執(zhí)行
    有多個defer腳本,會按照它們在頁面出現(xiàn)的順序加載,多個async腳本是不能保證加載順序
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容