es6 模块化与 node 的模块化

在平常的工作中,我们经常使用到模块化开发,那么具体这两者之间有什么区别呢?我们接下来一起探索一下。

概述

在 ES6 之前,主要的模块化方案是 CommonJS(服务器) 和 AMD 规范(浏览器),ES6 模块化的出现成为了浏览器和服务器通用的模块解决方案。

ES6 的设计思想是尽量的静态化,这样在编译的时候就能够确定模块间的依赖关系,并进行优化。而 CommonJS 和 AMD 都只能在运行时确定这些东西。

差异

  1. 模块的加载方式

    // CommonJS 是将整个模块加载进来
    const { a, b, c } = require('./m.js');
    // 相当于
    const _m = require('./m.js');
    const a = _m.a;
    const b = _m.b;
    const c = _m.c;
    
    // ES6 是静态加载,在编译时已经完成了模块的加载,也就是说它只加载了这三个变量,其他的都没有加载
    const { a, b, c } = require('./m.js');
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
  2. 模块的加载结果

    // CommonJS 输出的是值的拷贝,也就是说,一旦输入一个值,模块再变化也不会影响
    // ES6 模块输出的是值的引用
    
    1
    2

ES6 模块化

import 命令会被 JavaScript 引擎静态分析,先于模块内的其他语句执行,比如我们这样写就会报错。

if (flag) {
  import X from './x.js';
}
1
2
3

报错的原因就是,import 执行是在编译时,这时候不会去执行 if,所以把 import 放在里面毫无意义。这样做虽然看起来效率高,但是我们不能够做到按需加载,这就是一个很大的问题,但是 require 就能够做到。

if (path) {
  const module = require('./m.js');
}
1
2
3

所以说如果 ES6 模块化要替代 CommonJS,就需要提供这么一种机制,因为这是一种非常常见的需求。

所以,在后来的标准中有一个提案,import() 函数,他就能做到动态加载,他返回的是一个 Promise 对象。

Last Updated: 8/19/2019, 10:45:46 AM