ES6模块是编译时加载,在编译时就能确定模块的依赖关系。
ES6模块不是对象,而是通过export命令显式指定输出的代码,再通过import命令输入。

//ES6模块
import { stat, exists, readFile } from 'fs';

上面代码实质是从fs模块加载3个方法,其他方法不加载。这种加载称为“编译时加载”或者静态加载,即ES6可以在编译时就完成模块加载。

import()

ES2020提案引入import()函数,支持动态加载模块。

import(specifier)

上面代码中,import函数的参数specifier,指定所要加载的模块的位置。
import()返回一个Promise对象。下面是一个例子。

const main = document.querySelector('main');
import(`./section-modules/${someVariable}.js`)
.then(module => {
	module.loadPageInto(main);
})
.catch(err => {
	main.textContent = err.message;
});

export命令

一个模块就是一个独立的文件。该文件内部的所有变量,外部无法获取。如果你希望外部能够读取模块内部的某个变量,就必须使用export关键字输出该变量。下面是一个 JS 文件,里面使用export命令输出变量。

  • 写法一:
export var firstName = 'Michael';
export var lastName = 'Jackson';
export var year = 1958;

export function multiply(x, y) {
	return x * y;
};
  • 写法二:
var firstName = 'Michael';
var lastName = 'Jackson';
var year = 1958;

export {firstName, lastName, year};
function v1() { ...}
function v2() {...}

export {
v1 as streamV1,
v2 as streamV2,
v2 as streamLatestVerstion
  • 报错写法:
//报错
export 1;

//报错
var m = 1;
export m;

上面两种写法都会报错,因为没有提供对外的接口。第一种写法直接输出1,第二种写法通过变量m,还是直接输出1。1只是一个值,不是接口。正确的写法如下:

//写法一
export var m = 1;

//写法二
var m = 1;
export {m};

//写法三
var n = 1;
export {n as m};

import 命令

import {firstName, lastName, year} from './profile.js';
function setName(element) {
 	element.textContent = firstName + ' '+ lastName;
 }

//重命名
import {lastName as surname } from  './profile.js';

import后面的 from指定模块文件的位置,可以是相对路径,也可以是绝对路径,.js后缀可以省略。如果只是模块名,不带有路径,那么必须有配置文件,告诉JavaScript引擎该模块的位置。

import {myMethod} from  'util';

上面代码中,util是模块文件名,由于不带有路径,必须通过配置,告诉引擎怎么取到这个模块。

模块的整体加载

import * as circle from './circle';
console.log('圆面积:'+circle.area(4));
console.log('圆周长:'+circle.circumference(14));

export default 命令

默认输出

// export-default.js
export default function () {
	console.log('foo');
}

其他模块加载该模块时,import命令可以为该匿名函数指定任意名字。

// import-default.js
import customName from './export-default';
customName(); // 'foo'

export default命令其实只是输出一个叫default的变量,所以它后面不能跟变量声明语句。

// 正确
export var a = 1;
// 正确
var a = 1;
export default a;
// 错误
export default var a = 1;

上面代码中,export default a的含义是将变量a的值赋给变量default。所以,最后一种写法会报错。
export default也可以用来输出类。

// MyClass.js
export default class {...}

//main.js
import MyClass from 'MyClass';
let o = new MyClass();