概述
在ES6之前,JavaScript一直沒(méi)有模塊(module)體系,無(wú)法將一個(gè)大程序拆分成互相依賴的小文件,再用簡(jiǎn)單的方法拼裝起來(lái)。這對(duì)開(kāi)發(fā)大型的、復(fù)雜的項(xiàng)目形成了障礙。
為了解決這個(gè)問(wèn)題,創(chuàng)造了一些模塊加載方案(如用于服務(wù)器的CommonJS,用于瀏覽器的AMD、CMD),各個(gè)方案各有自己的特點(diǎn),并且語(yǔ)法還不一樣,如果是要同時(shí)做前后端,那真的是會(huì)“精分”了。
好消息是ES6給我們帶來(lái)了模塊化的設(shè)計(jì)!這完全可以取代CommonJS、AMD等規(guī)范,成為瀏覽器和服務(wù)器通用的模塊解決方案。
語(yǔ)法
模塊功能主要由兩個(gè)命令構(gòu)成:export 和 import。export 命令用于規(guī)定模塊的對(duì)外接口,import 命令用于輸入其他模塊提供的功能。
export
一個(gè)模塊就是一個(gè)獨(dú)立的文件。該文件內(nèi)部的所有變量,外部無(wú)法獲取。如果你希望外部能夠讀取模塊內(nèi)部的某個(gè)變量,就必須使用 export 關(guān)鍵字輸出該變量。
對(duì)外輸出變量
// 寫(xiě)法一
export var m = 1;
// 寫(xiě)法二
var m = 1;
export {m};
// 寫(xiě)法三
var n = 1;
export {n as m};
需要注意的是,使用先聲明再輸出的寫(xiě)法時(shí),即使只有一個(gè)變量,也不能省略 { ... },否則會(huì)報(bào)錯(cuò)。
// 報(bào)錯(cuò)
var m = 1;
export m;
記住,使用 export 命令時(shí),要提供對(duì)外的接口,而不是提供一個(gè)值!
對(duì)外輸出函數(shù)
當(dāng)然也可以使用類(lèi)似的語(yǔ)法,對(duì)外輸出函數(shù)。需要注意的點(diǎn)還是一樣的,對(duì)外輸出的是接口,不是函數(shù)本身。
說(shuō)白了,就是 記得加上 { ... }!
// 寫(xiě)法一
export function f() {};
// 寫(xiě)法二
function f() {}
export {f};
// 報(bào)錯(cuò)
function f() {}
export f;
import
加載變量、函數(shù)
import { m, n } from "./export.js";
需要注意的是,import 命令輸入的變量都是只讀的,修改會(huì)報(bào)錯(cuò)。這很合理,當(dāng)然不能在加載模塊的腳本里改寫(xiě)接口。
不過(guò)如果加載的變量是一個(gè)對(duì)象,修改這個(gè)對(duì)象的屬性是允許的。
模塊的整體加載
除了指定加載某個(gè)值,還可以使用整體加載的方法,加載整個(gè)模塊的所有輸出值。
語(yǔ)法很簡(jiǎn)單,用 * 指代“所有”即可。
import * from "./export.js";
了解了
import和export的語(yǔ)法之后,我迫不及待地想要去嘗試了,然后……
在瀏覽器中加載ES6模塊
由于粗心,沒(méi)認(rèn)真了解規(guī)則,廢了好多時(shí)間,下面來(lái)說(shuō)說(shuō)經(jīng)驗(yàn)之談。
加載規(guī)則
瀏覽器加載ES6模塊,也是使用 <script> 標(biāo)簽,但注意,需要加上 type="module" 屬性。
有兩種方法:
1. 通過(guò) <script src=""> 加載js腳本
<script type="module" src="./import.js"></script>
2. 直接使用 <script> 標(biāo)簽內(nèi)嵌js代碼
<script type="module">
import { a } from "./export.js";
console.log(a);
</script>
面對(duì)瀏覽器的試煉...
了解了以上知識(shí),想要在瀏覽器中實(shí)現(xiàn)ES6模塊的加載,還是有坑...
首先要說(shuō)的是,如今(8102年),各大主流瀏覽器都(早)已經(jīng)支持了ES6的模塊了。千萬(wàn)別再說(shuō)Chrome瀏覽器沒(méi)有支持ES6的Module之類(lèi)的話了。
火狐瀏覽器
火狐瀏覽器沒(méi)問(wèn)題,直接打開(kāi)html文件,就可以完成模塊的加載。
Chrome瀏覽器
而對(duì)于Chrome瀏覽器,則會(huì)有一點(diǎn)問(wèn)題。
直接打開(kāi)html文件時(shí),Chrome瀏覽器會(huì)報(bào)錯(cuò):
Access to script at 'file:///masaike' from origin 'null' has been blocked by CORS policy: The response is invalid.
這并不是Chrome不支持加載模塊,而是ES6模塊遵循同源策略。解決方法就是打開(kāi)本地服務(wù)器,讓各個(gè)文件同源就可以了。
參考資料
http://es6.ruanyifeng.com/#docs/module