CommonJS规范与ES6规范

为什么会有两个模块规范?

JavaScript 最初只在浏览器运行,没有模块系统

Node.js 出现后需要模块系统 → 于是采用 CommonJS

后来 ES6(2015)正式推出了 ESM → 浏览器和 Node.js 都开始支持

CommonJS规范

  1. CommonJS 是为 JavaScript 在服务器端运行 制定的模块规范.它定义了:如何导出模块:module.exports,如何导入模块:require(), 模块是同步加载的, 每个文件是一个独立作用域.
  2. Node.js 在早期没有 ES 模块,只能用 CommonJS.

CommonJS 的导出与引入 (module.exports / require)

单个导出
引入
// math.js
function add(a, b) {
  return a + b;
}

module.exports = add;
// index.js
const add = require('./math');

console.log(add(2, 3)); // 5
多个导出
引入
// utils.js
function sum(a, b) {
  return a + b;
}

function multiply(a, b) {
  return a * b;
}

module.exports = {
  sum,
  multiply
};
// index.js
const { sum, multiply } = require('./utils');

console.log(sum(1, 2));       // 3
console.log(multiply(2, 3));  // 6
混合导出
导入
// user.js
function getUser() {
  return { name: 'Alice', age: 20 };
}

function getAge(user) {
  return user.age;
}

module.exports = getUser; // 默认导出
module.exports.getAge = getAge; // 命名导出
// index.js
const getUser = require('./user');
const { getAge } = require('./user');

const user = getUser();
console.log(user);          // { name: 'Alice', age: 20 }
console.log(getAge(user));  // 20
导出类
导入
// Person.js
class Person {
  constructor(name) {
    this.name = name;
  }

  sayHi() {
    console.log(`Hi, I'm ${this.name}`);
  }
}

module.exports = Person;
// index.js
const Person = require('./Person');

const p = new Person('Bob');
p.sayHi(); // Hi, I'm Bob
导出常量配置
导入
// config.js
module.exports = {
  port: 3000,
  db: 'mongodb://localhost:27017/test'
};
const config = require('./config');

console.log(config.port);

ES6规范

  1. ECMAScript 是 JavaScript 的 语言标准,由 TC39 制定。它定义了:语法(let、class、箭头函数…),数据类型(Number、String、Symbol…), 内置对象(Array、Promise…), 执行模型(作用域、原型链…),模块系统(ESM).
  2. 现代浏览器和 Node.js 都支持 ES 模块(ESM).

ES6 的导出与引入 (export / import)

  1. 一个文件只能有一个 export default
  2. 引入时可以随意命名
默认导出
导入
// math.js
export default function add(a, b) {
  return a + b;
}
// index.js
import add from './math.js';

console.log(add(2, 3)); // 5
命名导出
导入
// utils.js
export function sum(a, b) {
  return a + b;
}

export function multiply(a, b) {
  return a * b;
}

也可使用

export { sum, multiply };
import { sum, multiply } from './utils.js';

console.log(sum(1, 2));
console.log(multiply(2, 3));
混合导出
导入
// user.js
export default function getUser() {
  return { name: 'Alice', age: 20 };
}

export function getAge(user) {
  return user.age;
}
import getUser, { getAge } from './user.js';

const user = getUser();
console.log(user);
console.log(getAge(user));
导出类
导入
// Person.js
export default class Person {
  constructor(name) {
    this.name = name;
  }

  sayHi() {
    console.log(`Hi, I'm ${this.name}`);
  }
}
import Person from './Person.js';

const p = new Person('Bob');
p.sayHi();
导出常量配置
导入
// config.js
export const port = 3000;
export const db = 'mongodb://localhost:27017/test';
import { port, db } from './config.js';
console.log(port);