Technology Sharing

JS [Detailed Explanation] ES6 module specification vs CommonJS module specification

2024-07-12

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

Each js file is a module, and the CommonJS module specification is adopted by default.

Emerging ES6 modules vs. traditional CommonJS modules

characteristicCommonJSES6 Modules
Exportexports Objectexport Keywords
Importrequire()functionimport Keywords
Loading ModeSynchronizeasynchronous
Execution ModeSingletonSingleton
DependenciesStaticdynamic
Tree Shakenot supportsupport

Loading Mode

  • CommonJS is synchronous, code execution stops until a module is loaded.
  • ES6 modules are asynchronous, code execution can continue while the module will be loaded later.

Execution Mode

Both CommonJS and ES6 module implementations are singletons: a module is loaded only once, and all references to the module refer to the same instance.

Dependencies

  • CommonJS is static, and module dependencies are determined at compile time.
  • ES6 modules are dynamic, and module dependencies are determined at runtime

Tree Shake

An optimization technique for removing unused code from JavaScript bundles.

  • CommonJS does not support tree shaking, and unused code in modules will also be loaded.
  • ES6 modules support tree shaking, which can automatically remove unused code to reduce bundle size.

Three ways to enable ES6 modules

  1. Set in package.json file "type": "module", so that Node.js will treat all .js files as ES6 modules.
  2. Change the file extension to .mjs, so that Node.js will automatically treat it as an ES6 module.
  3. Add in the script tag type="module" Attributes

ES6 module syntax

export default

Each module can only have one default export.

let a = 1
// 默认导出 a
export default a
  • 1
  • 2
  • 3
// 导入默认时,可以命其他名称
import b from './demo.js'

console.log(b)
  • 1
  • 2
  • 3
  • 4

You can use function expressions/anonymous functions directly as default exports

export default function myFunc() {}
  • 1
export default function() {}
  • 1

Export and import multiple export { }

let a = 1
let b = 2

export { a, b }
  • 1
  • 2
  • 3
  • 4
// 导入多项时,必须与导出名对应
import { a, b } from './demo.js'

console.log(a, b)
  • 1
  • 2
  • 3
  • 4

Rename as when exporting

let a = 1
let b = 2

export { a as c, b as d }
  • 1
  • 2
  • 3
  • 4
// 导入时,只能导入新的名称
import { c, d } from './demo.js'

console.log(c, d)
  • 1
  • 2
  • 3
  • 4

Export other module specific items

export { name1, name2, ... } from 'module-name'
  • 1

Import all the content exported by the module import *

export let a = 1;
export let b = 2;
  • 1
  • 2
// 通过 as 重命名为一个变量(值为对象)
import * as myModule from "./demo.mjs";

console.log(myModule.a);
console.log(myModule.b);
  • 1
  • 2
  • 3
  • 4
  • 5

Rename as when importing

import {trunc as StringLib} from "../lib/string.js"
import {trunc as MathLib} from "../lib/math.js"
  • 1
  • 2

Import json format file

import pkg from "./package.json" assert { type: "json" };
  • 1
const { default: jsonObject } = await import('./file.json', {
  assert: {
    type: 'json'
  }
});
  • 1
  • 2
  • 3
  • 4
  • 5

Importing CommonJS modules

import * as 自定义名称  from '模块名称'
  • 1

CommonJS module syntax

  • Each module has a module object, which has the attribute exports (the attribute value is also an object)
  • When importing through require(), the exports property of the module object in the exported module is obtained.
  • Do not mix exports and module.exports to export different things in the same module, as this will lead to confusion and unexpected behavior.

Export and import single item module.exports

Export

module.exports = "朝阳";
  • 1

Import

const demoModule = require("./demo.js");

console.log(demoModule); // 朝阳
  • 1
  • 2
  • 3

Export and import multiple exports

Export

exports.a = 1;
exports.b = 2;
  • 1
  • 2

Import

const demoModule = require("./demo.js");

console.log(demoModule); // { a: 1, b: 2 }
  • 1
  • 2
  • 3