evantianx / Bloooooooog

Place to record what I thought and learned
0 stars 0 forks source link

ES6 Modules #71

Open evantianx opened 6 years ago

evantianx commented 6 years ago

ECMAScript 6 入门 - module 语法 CommonJS规范

ES modules: A cartoon deep-dive

evantianx commented 6 years ago

历史回顾

历史上 JS 模块有 CommonJS 和 AMD 两种。

CommonJS 规范加载模块是同步的,也就是说,只有加载完成,才能执行后面的操作。AMD 规范则是非同步加载模块,允许指定回调函数。由于 Node.js 主要用于服务器编程,模块文件一般都已经存在于本地硬盘,所以加载起来比较快,不用考虑非同步加载的方式,所以 CommonJS 规范比较适用。但是,如果是浏览器环境,要从服务器端加载模块,这时就必须采用非同步模式,因此浏览器端一般采用 AMD 规范。

所以说服务端瓶颈在于 CPU 和内存,而客户端瓶颈在于带宽

CommonJS(服务器端):

var a = require('b');

AMD(客户端):

// dep1 dep2 为本模块的依赖
define(['dep1', 'dep2'], function(dep1, dep2) {
  // do something
});
// 在工厂函数中使用 require 和 exports
define("alpha", ["require", "exports", "beta"], function (require, exports, beta) {
  exports.verb = function() {
    return beta.verb();
    //Or:
    //return require("beta").verb();
  }
});
evantianx commented 6 years ago

ES6 的模块

ES6 模块是静态加载,而 CommonJS 和 AMD 是动态加载(即运行时加载)。

静态加载有什么好处?举个栗子:

在 CommonJS 中:

// CommonJS
let { user, isLogin } = require('userInfo');

等同于:

let _userInfo = require('userInfo');
let user = _userInfo.user;
let isLogin = userInfo.isLogin;

而在 ES6 中:

// ES6
import { user, isLogin } from 'userInfo';

在 CommonJS 中必须在运行时才会加载,就无法进行静态优化,导致必须将 userInfo 这个模块全部加载,才能获取到所需方法;而 ES6 在编译时进行静态优化,可以只加载所需方法。

evantianx commented 6 years ago

API

export

export var userName = 'Jack'
export var userAge = 18

等价于:

var userName = 'Jack'
var userAge = 18

export { userName, userAge }

一般情况下 export 输出的变量名就是可以引用的变量名,但是也可以通过关键字 as 来修改:

export userName as nickName;

import

具有提升效果,会提升到头部。 多次引入,只会执行一次。

import { userName, userAge } from 'user';

也可以用关键字 as 进行重命名。

整体加载

// math.js
export function addOne(num) {
  return num + 1
}

export function mulitiplyThree(num) {
  return num * 3
}
import * as mathFunc from 'math'

var a = mathFunc.addOne(1)  // 2

输出默认值

使用关键字 default 制定默认输出

// foo.js
export default function() {
  // do something
}
// 这里在引入模块时为匿名函数指定了名字
import bar from 'foo'