1、ES6 模块不是对象,而是通过export命令显式指定输出的代码,再通过import命令输入。这种加载称为“编译时加载”或者静态加载,即 ES6 可以在编译时就完成模块加载,效率要比 CommonJS 模块的加载方式高。当然,这也导致了没法引用 ES6 模块本身,因为它不是对象。
2、import命令会被 JavaScript 引擎静态分析,先于模块内的其他语句执行
也就是说,import和export命令只能在模块的顶层,不能在代码块之中
3、动态加载提案 import(), 为取代 node 的运行时加载 require 铺路
4、可以侦测当前代码是否在 ES6 模块之中 const isNotModuleScript=this!==undefined;
二、 es6 与 node 模块差别
CommonJS 模块输出的是一个值的拷贝,ES6 模块输出的是值的引用。
CommonJS 模块是运行时加载,ES6 模块是编译时输出接口。
三、浏览器加载 es6 type="module"
四、node 中加载 es6 模块
Node 对 ES6 模块的处理比较麻烦,因为它有自己的 CommonJS 模块格式,与 ES6 模块格式是不兼容的。目前的解决方案是,将两者分开,ES6 模块和 CommonJS 采用各自的加载方案。
Node 要求 ES6 模块采用.mjs后缀文件名。也就是说,只要脚本文件里面使用import或者export命令,那么就必须采用.mjs后缀名。require命令不能加载.mjs文件,会报错,只有import命令才可以加载.mjs文件。反过来,.mjs文件里面也不能使用require命令,必须使用import。
ES6 模块应该是通用的,同一个模块不用修改,就可以用在浏览器环境和服务器环境。为了达到这个目标,Node 规定 ES6 模块之中不能使用 CommonJS 模块的特有的一些内部变量。
五、 es6 加载 commonjs 模块
// b.js
module.exports=null;
// es.js
import foo from'./b'; // foo = null;
import*as bar from'./b'; // bar = { default:null };
六、CommonJS 模块加载 ES6 模块
// es.jsexportletfoo={bar:'my-default'};export{foo as bar};exportfunctionf(){};export classc{};// cjs.jsconst es_namespace=awaitimport('./es');
七、循环加载
a)commonjs 加载原理
require命令第一次加载该脚本,就会执行整个脚本,然后在内存生成一个对象。
CommonJS 模块无论加载多少次,都只会在第一次加载时运行一次,以后再加载,就返回第一次运行的结果,除非手动清除系统缓存。
b)CommonJS 模块的循环加载
CommonJS 模块的重要特性是加载时执行,即脚本代码在require的时候,就会全部执行。一旦出现某个模块被"循环加载",就只输出已经执行的部分,还未执行的部分不会输出。
c)ES6 模块的循环加载
ES6 处理“循环加载”与 CommonJS 有本质的不同。ES6 模块是动态引用,如果使用import从一个模块加载变量(即import foo from 'foo'),那些变量不会被缓存,而是成为一个指向被加载模块的引用,需要开发者自己保证,真正取值的时候能够取到值。
常会出现一些 变量未定义的情况,可以利用函数具有提升作用解决变量未定义问题。
网友评论