寫在前面,目前瀏覽器對ES6的import支持還不是很好,需要用bable轉譯。
ES6引入外部模塊分兩種情況:
1.導入外部的變量或函數等;
import {firstName, lastName, year} from './profile';
2.導入外部的模塊,並立即執行
import './test' //執行test.js,但不導入任何變量
第2種情況就不用講了,就是執行從頭到尾執行引入的js文件,當然,會忽略js文件里export。
下面詳細講第1種情況。
兩個js文件,counter.js與my.js
// counter.js import {a} from './my'; console.log('333333'); console.log(a);
// my.js console.log('111111'); export var a = 'aaaaaaa'; console.log('222222');
運行的結果是什么呢?

貌似沒什么問題,再看看轉譯后的counter.js
//#----------------mod start---------------- void function (module, exports){ window["60ae5ba7"] = {}; "use strict"; // my.js console.log('111111'); window["60ae5ba7"].a = 'aaaaaaa'; console.log('222222'); }({exports:{}}, {}) //#----------------mod end---------------- //#----------------mod start---------------- void function (module, exports){ window["3d4fdd69"] = {}; "use strict"; // counter.js var my_1 = window["60ae5ba7"]; console.log('333333'); console.log(my_1.a);
好,暫時不用管那么多。下面來問題了,咱們把console.log(a)這句去掉,看看運行結果
// counter.js import {a} from './my'; console.log('333333'); // console.log(a);

咦,只輸出這一句了?我們明明引入了my模塊了,為何模塊里的代碼沒有執行呢。
這要從ES6模塊加載的實質談起。在阮一峰的ES6入門一書里講到:ES6模塊的運行機制與CommonJS不一樣,它遇到模塊加載命令import時,不會去執行模塊,而是只生成一個動態的只讀引用。等到真的需要用到時,再到模塊里面去取值,換句話說,ES6的輸入有點像Unix系統的“符號連接”,原始值變了,import輸入的值也會跟着變。
可是按照上面說的,那有console.log(a)的時候,應該是輸出3333,1111,2222的順序,而不是1111,2222,333的順序呀。我猜測是上面講的不細致的原因,應該分為編譯時和運行時來說。ES6的這種加載稱為“編譯時加載”或者靜態加載,即 ES6 可以在編譯時就完成模塊加載,在編譯的時候,發現了后面有使用到a的地方,就在運行時遇到import的地方直接執行了模塊的代碼。當然只是自己的猜測。
有一點別忘了:模塊內部的變量不向外暴露的話,外界是無法使用這些內部變量的。所有有時候會看到,這個模塊引用了一個vue.js,另外一個模塊也要引用vue.js,這是因為vue.js內部很多東西沒有暴露,所以都需要引用。
