ES6模块概述
在 ES6 之前,社区制定了一些模块加载方案,最主要的有 CommonJS 和 AMD 两种。前者用于服务器,后者用于浏览器。
ES6 在语言标准的层面上,实现了模块功能,而且实现得相当简单,完全可以取代 CommonJS 和 AMD 规范,
成为浏览器和服务器通用的模块解决方案。
ES6 模块的设计思想是尽量的静态化,使得编译时就能确定模块的依赖关系,以及输入和输出的变量。CommonJS 和 AMD 模块,
都只能在运行时确定这些东西。比如,CommonJS 模块就是对象,输入时必须查找对象属性。
模块标签及定义
<script type="module">
</script>
<script type="module" src="path/to/myModule.js"></script>
带有type="nodule"属性的<script>标签,会告诉浏览器相关代码作为模块执行。
index.js文件
console.log(1)
index.html
<script src="./index.js" type="module"></script>
<script>
console.log(2)
</script>
执行结果 2 1
模块会像<script defer>加载的脚本一样按顺序执行。解析到<script
type="module">标签后会立即下载模块文件,但执行会延迟到文档解析完成。
<script src="./index.js" type="module"></script>
<script src="./index.js" type="module"></script>
<script>
console.log(2)
</script>
执行结果 2 1
同一个模块无论在同一个页面被加载多少次,也不管是怎么加载的,都只执行一次。
export命令
export ...
if (condition) {
export ...
}
export const foo = 'foo'
export {bar}
const bar = 'bar'
export {bar as myBar}
export default {
bar
}
export default const foo = 'bar';
export { 123 as foo }
export const foo = 'foo' as myFoo;
import命令
import {foo,myBar} from './moduleA.js'
console.log('foo',foo)//foo
console.log('myBar',myBar)//bar
import a from './moduleA.js'
console.log(a)
//重命名需要使用as关键字
//import命令输入的变量都是只读的 如果是一个对象,改写对象的属性是允许的
import { firstName as name, lastName, year } from './moduleB.js';
console.log(name, lastName, year)
//模块标识符可以是相对于当前模块的相对路径,也可以是指向模块文件的绝对路径。它必须是纯字符串,不能是动态计算的结果。例如,不能是拼接的字符串。 import是静态执行
// 报错
/* import { 'f' + 'oo' } from 'my_module';
// 报错
let module = 'my_module';
import { foo } from module;
// 报错
if (x === 1) {
import { foo } from 'module1';
} else {
import { foo } from 'module2';
} */
//如果多次重复执行同一句import语句,那么只会执行一次,而不会执行多次。
模块转移导出
模块导入的值可以直接通过管道转移到导出。
如果想把一个模块的所有命名导出集中在一块,可以像下面这样在 bar.js 中使用*导出:
export * from './foo.js';
foo.js
export const baz = 'origin:foo';
bar.js
export * from './foo.js';
export const baz = 'origin:bar';
main.js
import { baz } from './bar.js';
console.log(baz);
类似地,外部模块的默认导出可以重用为当前模块的默认导出:
export { default } from './foo.js';
在重新导出时,还可以在导入模块修改命名或默认导出的角色。比如,可以像下面这样将命名导出
指定为默认导出:
export { foo as default } from './foo.js';