Web

CommonJS vs ECMAScript

Posted by Kerwen Blog on June 6, 2024

CommonJs

CommonJS(简称cjs),为node.js打包javaScript的原始方法,使用require和imports(module.exports)语句定义模块
在node.js中,每个文件都被视为一个单独的模块。模块的局部变量是私有的,只有exports出去的变量,才能被外界访问。

默认情况下,node.js会将以下情形视为 cjs模块:

  • 扩展名为.cjs的文件;
  • 扩展名为.js的文件,且离自己最近的package.json文件包含一个顶级字段“type”,其值为“commonjs”;
  • 扩展名为.js的文件,且离自己最近的package.json文件不包含一个顶级字段“type”

    (建议明确指定 type值,而不是不定义);

  • 扩展名不为.mjs, .cjs, .json, .node, .js的文件,且离自己最近的package.json文件包含一个顶级字段“type”,其值为“module”,但是这些文件通过require引入。

下面的CommonJs module导出两个函数

1
2
3
4
5
6
7
    module.exports.add = function(a, b) {
            return a + b;
    } 

    module.exports.subtract = function(a, b) {
            return a - b;
    }

也可以这么写

1
2
3
4
5
6
7
8
9
    function add(a, b) {
            return a + b;
    }

    function subtract(a, b) {
            return a - b;
    }
    
    module.exports = {add, subtract}; 

使用require引入这个module

1
2
3
4
    const {add, subtract} = require('./util')

    console.log(add(5, 5)) // 10
    console.log(subtract(10, 5)) // 5

ESMAScript

ECMAScript模块(简称esm),是ecma262标准下封装的JavaScript代码重用的官方标准格式。使用import和export语句定义模块

默认情况下,node.js会将以下情形视为 esm 模块:

  • 扩展名为 .mjs 的文件;
  • 扩展名为.js的文件,且离自己最近的package.json文件包含一个顶级字段“type”,其值为“module”;

ES module导出两个函数:

1
2
3
4
5
6
7
    export function add(a, b) {
            return a + b;
    }

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

通过import导入

1
2
3
4
    import {add, subtract} from './util.mjs'

    console.log(add(5, 5)) // 10
    console.log(subtract(10, 5)) // 5

两者不同

-cjs只有在node.js环境使用。
-esm在node.js和浏览器环境都可以使用

  • esm使用import/export, 而cjs使用require/exports
  • cjs可以使用 __filename 或者 __dirname,process, 而esm不行,esm只能使用 import.meta.url
  • esm不支持本机模块。 但是可以改为通过 module.createRequire() or process.dlopen.加载
  • cjs使用 require.resolve, 而esm使用new URL(), import.meta.resolve
  • cjs可以通过环境变量指定的路径,去查找本机上对应位置的模块,而esm不行,
  • cjs 是在运行时确定,而esm则在静态编译时确定。
  • cjs可以同步执行,esm不行

Reference

CommonJS模块和ECMAScript模块
CommonJS 与 Node.js 中的 ES 模块
Nodejs official CommonJs
Nodejs official ECMAScript Modules