CommonJS 和 ES6 Module

发布于 2023-07-31 12:46:50 字数 4570 浏览 45 评论 0

CommonJS

主要用在服务器端,Node.js 目前使用的规范,使用 module.exports 或者 exports 导出,require 引入。

为了避免出问题,我们一般使用 module.exports(本质是一个对象)来导出,因为 exports 是对 module.exports 的引用。当你的 exports 的引用对象不再指向 exports 时,导出就会出现问题

基本的用法

export_test.js

let a = 100;
let b = [1, 2, 3];
let c = {
  name: 'lee',
  age: 25
};

function add(a, b) {
  return a + b;
}

module.exports = {
  a,
  b,
  c,
  add
}

import_test.js

const obj = require('./export_test.js');

console.log(obj.add(2, 3));  // 5
console.log(obj.a); // 100

使用 exports

这里使用 exports 的话就要改变一下写法了,前面说过 exports 是对 module.exports 的一个引用,你最终导出的还是 module.exports,而不是说你写 exports 导出的就是 exports。所以建议在使用时尽量使用 module.exports。

下面这种写法会报错

这个基于上面 export_test.js 的内容来说的

// exports 的指向变成了一个包含 a,b,c,add 的对象,但是 CommonJS 默认导出的是 module.exports,所以 require 过后也取不到 a,b,c,add 这些。
exports = {
  a,
  b,
  c,
  add
}

正确的写法

exports.a = a;
exports.b = b;
exports.c = c;
exports.add = add;

三种正确的导出方法

// 三种导出方法,取其中一个即可
/* 第一种导出方法 */
module.exports = {
  a,
  b,
  c,
  add
}

/* 第二种导出方法 */
module.exports.a = a;
module.exports.b = b;
module.exports.c = c;
module.exports.add = add;

/* 第三种导出方法 */
exports.a = a;
exports.b = b;
exports.c = c;
exports.add = add;

其它注意点

  • 混合使用
// 混合使用
exports.a = a;
exports.b = b;
module.exports.c = c;
module.exports.add = add;

这样也是可以的。

特点

CommonJS 加载模块是同步的,所以只有加载完成才能执行后面的操作。像 Node.js 主要用于服务器的编程,加载的模块文件一般都已经存在本地硬盘,所以加载起来比较快,不用考虑异步加载的方式,所以 CommonJS 规范比较适用。

ES6 Module

ES6 Module 是 ES6 提出来的标准,使用 export 或者 export default 来导出,使用 import 来导入。node.js 从 13.2.0 过后开始支持 ES Module 了,不过需要把你的 js 文件命名为 mjs,或者在你的项目的 package.json 中声明 "type": "module" ,我这儿为了方便,更新了 node.js 为 13.5.0,同时文件后缀为 mjs。

基础用法

export_test.mjs

let a = 100;
let b = [1, 2, 3];
let c = {
  name: 'lee',
  age: 25
};

function add(a, b) {
  return a + b;
}

export {a, b, c, add};

import_test.mjs

import { a, b, c, add } from './export_test.mjs';
console.log(a); // 100
console.log(b); // [1, 2, 3]
console.log(c); // {name: 'lee',age: 25}
console.log(add(2, 3));  // 5

注:使用上面的 export 导出对象时,另一个模块的 import 的花括号里面的变量名必须跟导出模块里面的变量名相同,不然会报错,变量的书写次序可以不同。

使用 export default

把 export_test.mjs 的导出语句写成这种

export default {a, b, c, add};

然后呢修改 import_test.mjs 的引入语句

import Test from './export_test.mjs';
console.log(Test.a); // 100
console.log(Test.b); // [1, 2, 3]
console.log(Test.c); // {name: 'lee',age: 25}
console.log(Test.add(2, 3));  // 5

其它用法

注意:一个模块里面 export 语句可以有多个,但是 export default 只能有一个。

多个 export 语句

// 多个 export 语句
export const a = 12;

export function reduce(a, b) {
  return a - b;
}

// 注意这样写是不行的
const c = 'hello';
export c;

// 另一个模块导入
import {a, reduce} from './export_test.mjs';

console.log(a);
console.log(reduce(5, 2));

多个 export 语句在另一个模块导入时可以全部封装为一个对象

// 这样也是可以的
import * as Test from './export_test.mjs';

console.log(Test.a);
console.log(Test.reduce(5, 2));

export default 注意事项

// 这样写莫得问题,相当于导出一个函数对象
export default function add(a, b) {
  return a + b;
}

// 这两种都是错误写法
export default const j = 100;
export default let k = 100;


// 这样写就没问题了
let j = 100;
export default j;

特点

ES6 的模块不是对象,import 命令会被 JavaScript 引擎静态分析,在编译时就引入模块代码,而不是在代码运行时加载,所以无法实现条件加载。也正因为这个,使得静态分析成为可能。

23232.png

参考资料

AMD, CMD, CommonJS 和 UMD
再次梳理 AMD、CMD、CommonJS、ES6 Module 的区别
前端模块化:CommonJS,AMD,CMD,ES6
import、require、export、module.exports 混合使用详解
Javascript 模块化七日谈

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

强者自强

暂无简介

文章
评论
28 人气
更多

推荐作者

mb_XvqQsWhl

文章 0 评论 0

我不在是我

文章 0 评论 0

依 靠

文章 0 评论 0

L.W.

文章 0 评论 0

暗里之光

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文