1、es6模块特性
- ********
- ****
特性1:输出值的引用
也就是说,在commonjs中,在不同的模块中引入同一个值,是不会相互影响的。而在es6中,是会相互影响的。
javascript
// a.js
import { foo } from './b';
console.log(foo);
setTimeout(() => {
console.log(foo);
import('./b').then(({ foo }) => {
console.log(foo);
});
}, 1000);
// b.js
export let foo = 1;
setTimeout(() => {
foo = 2;
}, 500);
// 执行:babel-node a.js
// 执行结果:
// 1
// 2
// 2
特性2:静态编译
********
特性3:模块不会重复执行
javascript
// a.js
import './b';
import './b';
// b.js
console.log('只会执行一次');
// 执行结果:
// 只会执行一次
特性4:循环依赖
javascript
// a.js
console.log('a starting')
import {foo} from './b';
console.log('in b, foo:', foo);
export const bar = 2;
console.log('a done');
// b.js
console.log('b starting');
import {bar} from './a';
export const foo = 'foo';
console.log('in a, bar:', bar);
setTimeout(() => {
console.log('in a, setTimeout bar:', bar);
})
console.log('b done');
// babel-node a.js
// 执行结果:
// b starting
// in a, bar: undefined
// b done
// a starting
// in b, foo: foo
// a done
// in a, setTimeout bar: 2
特性5:动态import
javascript
`****```if(some condition) {
import a from './a';
}else {
import b from './b';
}
// or
import a from (str + 'b');
- ``
- ``
<font style="color:rgb(18, 18, 18);">import() </font>
javascript
// a.js
const str = './b';
const flag = true;
if(flag) {
import('./b').then(({foo}) => {
console.log(foo);
})
}
import(str).then(({foo}) => {
console.log(foo);
})
// b.js
export const foo = 'foo';
// babel-node a.js
// 执行结果
// foo
// foo
2、模块常见用法
export
export 导出方式有两种,命名导出
和默认导出
。
- 命名导出还是默认导出都是导出模块中内容的一种方式,可以混合使用。
- 个人理解:默认导出其实是导出了
default
别名变量。 - 一个模块只能有一个默认导出
- 不同的导出方式也对应了不同的导入方式
javascript
// 命名行内导出
export const baz = 'baz';
export const foo = 'foo', bar = 'bar';
export function foo() {}
export function* foo() {}
export class Foo {}
// 命名子句导出
export { foo };
export { foo, bar };
export { foo as myFoo, bar };
// 默认导出
export default 'foo';
export default 123;
export default /[a-z]*/;
export default { foo: 'foo' };
export { foo, bar as default };
export default foo
export default function() {}
export default function foo() {}
export default function*() {}
export default class {}
import
- 导入对模块而言是只读的,相当于const 变量
- import导入的值是无法直接修改的,但可以修改导入对象的属性。
javascript
import foo, * as Foo './foo.js';
foo = 'foo'; // 错误
Foo.foo = 'foo'; // 错误
foo.bar = 'bar'; // 允许
- 对应不同的导出方式,需要使用不同的导入方式:
javascript
// export.js
const foo = 'foo', bar = 'bar', baz = 'baz';
export { foo, bar, baz }
export default foo
// import .js
import * as Foo from './foo.js'; // 导入命名导出内容
import { foo, bar, baz as myBaz } from './foo.js'; // 导入命名导出内
// 导入默认导出的内容
import { default as foo } from './foo.js';//导入默认导出,与下边等效
import foo from './foo.js';//导入默认导出,与上边边等效
- 如果模块同时使用了命名导出和默认导出,可以这样来在import中同时导入
javascript
import foo, { bar, baz } from './foo.js';
import { default as foo, bar, baz } from './foo.js';
import foo, * as Foo from './foo.js';
模块转移导出
javascript
// 导出foo.js所有命名导出
export * from './foo.js';
// 将foo.js中默认导出修改为命名导出
export {default as foo} from './foo.js'
在组件库或函数库中,我们经常能看到模块转移导出,将需要导出到外部的内容有一个统一的出口,这时要注意导出名称是否会重名等问题