关于模块化,在之前有过AMD和CMD,require.js以及后面的sea.js,实际上都是借助于第三方的插件。那么在ES6里面它官方引入了模块化编程,它的不同之处在于:
ES6的Module它的运行环境实际上是编译时的,也就是说在编译时它就会把所有的依赖导入导出,每一个模块有自己独立的命名空间,然后这些关系都明确了。
1:基本概念
- 编译时模块(module)体系
2:export - 规定模块的对外接口
export在ES5之前或者是在sea.js和require.js里面我们用的都是export.default,但是在ES6我们实际上只需要用一个export关键字就可以了,它是规定模块化的对外接口,也就是说导出的是什么。
情况一:下面的代码这两个如果放在一个模块化的尾部(或者是一个js尾部、一段代码尾部),那么它的意思就是说导出了两个变量,一个叫做name,一个叫做age,这是最基本的用法。
也就是说在一个js一段代码下我们导出了两个模块,两个变量可以供外部使用或者说两个方法。
export const name = 'Eric';
export const age = 28;
情况二:default,默认引入。
当别人使用我们写的模块的时候,可能会不知道我们导出的关键字是什么,但是当使用了default之后,不管外来是以什么引入,以什么变量把它命名为什么都没有关系,因为这时候导出的是整个的对象。因此,别人在引用这个对象时,可以随意命名,对象下面就可以看到变量的名称。
const name = 'Eric';
const age = 28;
export default { name, age };
情况三:导出方法
const name = 'Eric';
const age = 28;
export default function getProperty() {
return `name: ${name} age: ${age}`
};
情况四:自身导出
const name = 'Eric';
const age = 28;
export default {
name as customName,
age as customAge
};
3:import - 加载模块
这里{ name, age }用到的是一个解构,对应上面的第一种导出写法。
import { name, age } from '../xxx.js';
重命名:
import { name as customName } from '../xxx.js';
下面的没有{}没有解构的它得到的是一个默认导出的,可以不用解构就直接导出。
import getProperty from '../xxx.js';
lodash是一个很有用的函数是编程的工具库。
在ES6里面,当我们引入两个同样的内容的时候,比如下面的写两遍import,但实际上它只会引入一次。甚至说当我们引用了同一个文件两次,每次取它不同的方法,但是实际上也只引入一次。这是ES6 Module内部的特有处理。
import 'lodash';
import 'lodash';
import { name } from '../xxx.js';
import { age } from '../xxx.js';
整个文件全部引入:* 代表所有,如下把../xxx.js文件下所有的都导出来然后把它命名到这个utils 。
import * as utils from '../xxx.js';
4:export 与 import 复合
在某些场景下,我们可能需要把export和import结合。比如我们引入了很多其他的库,然后封装一下供我们使用,在封装时我们需要引入其他的库,也就是import,然后抛出来给我们自己的模块,这个时候我们就要用到export。
// 先引进来再导出去
import { foo, bar } from '../xxx.js';
export { foo, bar };
/* 等同于 */
export { foo, bar } from '../xxx.js';
把../xxx.js中的全部导出来然后再把它导出去:
export * from '../xxx.js';
把../xxx.js里面default导出的再把它导出来,这样省去了一些中间变量:
export { default } from '../xxx.js';
从../xxx.js中只引入其中一个es6,但是我们把它默认的default成为了一个es6:
import { es6 } from '../xxx.js';
export default es6;
// 等同于 也就是说从../xxx.js把es6引进来然后再把它export默认导出
export { es6 as default } from '../xxx.js';
// 默认导出也可以重命名
export { default as es6 } from '../xxx.js';
5:import() - 动态加载
import除了引入模块,一般来说我们通常是把它放在文件的顶部来引入依赖,但是这个import它可以动态加载。比如说我们有一些文件不需要用到,比如点击某一个按钮才可能去实现一些功能,那么实现这个功能的时候我们就需要一些额外的文件,这个时候就需要用到import动态加载了。
- 按需加载
button.addEventListener('click', event => { import('./xxx.js') .then(value => { console.log(value); }) .catch(error => { /* Error */ }) });
- 条件加载
if (condition === 1) { import('./xxx.js').then(module => { console.log(module.default); }); } else if (condition === 2) { import('./xxx.js').then(({ name, age }) => { console.log(name, age); }); } else { import('./xxx.js').then(({ name: customName, age }) => { console.log(customName, age); }); }
更多学习参考:https://www.9xkd.com/