写在前面,目前浏览器对ES6的import支持还不是很好,须要用bable转译。vue
ES6引入外部模块分两种状况:浏览器
1.导入外部的变量或函数等;函数
import {firstName, lastName, year} from './profile';
2.导入外部的模块,并当即执行spa
import './test' //执行test.js,但不导入任何变量
第2种状况就不用讲了,就是执行从头至尾执行引入的js文件,固然,会忽略js文件里export。3d
下面详细讲第1种状况。code
两个js文件,counter.js与my.jsblog
// counter.js import {a} from './my'; console.log('333333'); console.log(a);
// my.js console.log('111111'); export var a = 'aaaaaaa'; console.log('222222');
运行的结果是什么呢?io
貌似没什么问题,再看看转译后的counter.jsconsole
//#----------------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内部不少东西没有暴露,因此都须要引用。