ES6 中 import/export 和 require/exports 对比

  • 约814字
  • 技术
  • 2016年12月3日

Javascript 最早用于浏览器,处理的逻辑比较简单,没有语言层面的模块化处理方法。 随着 JS 应用的逐渐复杂,人们提出多重模块化规范,其中最著名的当属 CommonJS 和 AMD 了。随着 nodejs 的推出和流行,CommonJS 已经被大家所熟知。最早实践前端模块化的框架 requirejs 使用的则是 AMD 规范。相对 AMD 规范来说,commonjs 在定义和使用上都要简单不少。所以后来推出的 browserify 就是用 commonjs 规范来组织前端 JS 代码。而这两年流行的 webpack 则兼容了以上两个规范。先来回顾一下这两个规范:

AMD (Asynchromous Module Definition)

// 定义模块
define("sum", function () {
  return function (a, b) {
    a + b;
  };
});

// 使用模块
define(["sum"], function (sum) {});

CommonJS

// 定义模块 math.js
exports.sum = function (a, b) {
  a + b;
};

// 使用模块
var sum = require("math").sum;

随着 es6/es2015 规范的推出,JS 模块化终于有了语言层面上的模块化支持。在开发实践中,对于 export/import 和 CommonJS 中的 exports/require 的差异,我和同事都有过迷惑,今天抽时间彻底的整理一下。

ES6/es2015

按名字导出和导入

// 定义模块 math.js
export function sum(a, b) {
  a + b;
}

// 使用模块
import { sum } from "math";

全部导出和导入,注意关键字 default

// 定义模块 sum.js
export default function sum(a, b) {
  a + b;
}

// 使用模块
import sum from "sum";

es6:exports 和 commonjs:export 的关系

按名字导出

// es6 使用 export 语法
export function sum(a, b) {
  return a + b;
}

// 等价于 commonjs 写法如下 (Babel 6.18.2 生成)
Object.defineProperty(exports, "__esModule", {
  value: true,
});
exports.sum = sum;
function sum(a, b) {
  return a + b;
}

导出整体

// es6 使用 export 语法
export default function sum(a, b) {
  return a + b;
}

// 等价于 commonjs 写法如下 (Babel 6.18.2 生成)
Object.defineProperty(exports, "__esModule", {
  value: true,
});
exports.default = sum;
function sum(a, b) {
  return a + b;
}

可以看出 es6 中 export default sum 相当于 CommonJS 中 exports.default = sum

es6:import 和 commonjs:require 的关系

按名字导入

// es6 使用 import 语法
import { sum } from "math";
console.log(sum);
sum(1, 2);

// 等价于 commonjs 写法如下  (Babel 6.18.2 生成)
var _math = require("math");
console.log(_math.sum);
(0, _math.sum)(1, 2); // (0, _math.sum) 相当于一个赋值语句,改变了 sum 函数 this 指向

整体导入

// es6 使用 import 语法
import sum from "sum";
console.log(sum);
sum(1, 2);

// 等价于 commonjs 写法如下  (Babel 6.18.2 生成)
var _sum = require("sum");
var _sum2 = _interopRequireDefault(_sum);
function _interopRequireDefault(obj) {
  return obj && obj.__esModule ? obj : { default: obj };
}
console.log(_sum2.default);
(0, _sum2.default)(1, 2);

导入所有

// es6 使用 import 语法
import * as math from "math";
math.sum(1, 2);

// 等价于 commonjs 写法如下  (Babel 6.18.2 生成)
var _math = require("math");
var math = _interopRequireWildcard(_math);
function _interopRequireWildcard(obj) {
  if (obj && obj.__esModule) {
    return obj;
  } else {
    var newObj = {};
    if (obj != null) {
      for (var key in obj) {
        if (Object.prototype.hasOwnProperty.call(obj, key))
          newObj[key] = obj[key];
      }
    }
    newObj.default = obj;
    return newObj;
  }
}

math.sum(1, 2);

结论:

  • export function sum() {} 相当于 exports.sum = function() {}
  • export default sum 相当于 exports.default = sum
  • import {sum} from 'math' 相当于 var sum = require('math').sum
  • import sum from 'sum' 相当于 var sum = require('sum').default
  • import * as math from 'math' 相当于 var math = require('math')

相关文章

后海滑冰知识准备

从小在长江边上长大,有20年以上的游泳史,却一直因为不会正确呼吸而仰着头游泳,游得既累又慢。直到前段时间看了一段游泳教学视频,详细了解了换气的方法和要领。再经过两小时的水下实践,终于可以在游泳时正确的呼吸了。

查看更多

时间管理的奇迹:开发者的高效工作秘诀

作为开发者,我们常面临繁重任务和高强度工作。本文结合《时间管理的奇迹》和实际经验,探讨如何合理规划时间,提升工作效率。

查看更多

Standard JS 代码规范和提交代码时检查

公司的 JavaScript 项目最开始有一个代码规范,也用 jsHint 写了检查脚本。但是随着团队人员的逐渐增加和项目的时间紧迫,有一段时间没有特别强调要去做代码规范的检查。

查看更多