Differences between commonjs and ES module

Time:2021-9-19

testing environment

node v13.12.0

First come to a conclusion

commonJS ES Module
value 1. Basic type: value copy, not shared
2. Reference type: shallow copy, shared
3. The imported value can be modified in the workspace
1. Read only import, dynamic read
2. The reference cannot be modified externally, but the methods contained in the reference can be called
Execution sequence 1. Check whether there is a cache of the module
2. If yes, use cache
3. If not, execute the module code and cache it
1. Check whether the module has been introduced?
2. Yes, temporarily recognize the module as {}
3. No, enter the module and execute its code (no caching)
⚠️ Import will be promoted to execute first
Differences between commonjs module and ES6 module – Case Keith – blog Park Circular reference pit in ES6 – Yang Guang’s notes

1. Validation of imported values

commonJS

// mod.js
let count = 1;
Let friends = ['Charlotte'];

function plusCount() {
    count++
};

function plusYuanhua() {
    Friends. Push ('yuan Hua ');
}

setInterval(() => {
    Console.log ('mod.js print - count ', count per second);
    Console.log ('mod. JS prints per second - friends', friends);
}, 1000);

module.exports = {
    count,
    friends,
    plusCount,
    plusYuanhua,
}


// index.js
const mod = require('./mod.js');

Console. Log ('index. JS initial import - mod. Count ', mod. Count);
Console.log ('index. JS first import - mod. Friends', mod. Friends);

mod.plusCount();
mod.plusYuanhua();

Console.log ('index.js - mod. Count ', mod. Count after executing mod.pluscount/plusyuanhua);
Console.log ('index.js - mod. Friends', after executing mod.pluscount/plusyuanhua);

setTimeout(() => {
    mod.count = 3;
    Console.log ('index.js delay 2S - mod. Count ', mod. Count);
    Console.log ('index.js delay 2S - mod. Friends', mod. Friends);
}, 2000)

/*
Index.js initial import - mod.count 1
Index.js initial import - mod.friends ['Charlotte']

Index.js after executing mod.pluscount/plusyuanhua - mod.count 1
Index.js after executing mod.pluscount/plusyuanhua - mod.friends ['Charlotte', 'Yuan Hua']

Mod.js print per second - count 2
Mod.js print per second - Friends ['Charlotte', 'Yuan Hua']

Mod.js print per second - count 2
Mod.js print per second - Friends ['Charlotte', 'Yuan Hua']

Index.js delay 2S - mod.count 3
Index.js delay 2S - mod.friends ['Charlotte', 'Yuan Hua']

Mod.js print per second - count 2
Mod.js print per second - Friends ['Charlotte', 'Yuan Hua']
*/

ES Module

Node 13.2 adds support for ES module. To enable node to recognize es module, you need to do one of the following

  1. change.jsby.mjs, and usenode index.mjs
  2. package.jsonAdd field"type": "module", so all.jsAre identified as ES module
// index.mjs
import { counter } from './mod.mjs'
counter = {}; // TypeError: Assignment to constant variable.
console.log('a.js-1', counter)

// mod.mjs
export let counter = {
    count: 1
}
setInterval(() => {
    console.log('modB.js-1', counter.count)
}, 1000)

It can be seen that import is read-only. In this way, the change of count in mod.mjs will be reflected in index.mjs in time

2. Module import, what do they do?

commonJS

// index.js
let a = require('./modA.js')
let b = require('./modB.js')
Console.log ('index. JS-1 ',' execution completed ', a.done, b.done)

// modA.js
exports.done = false
let b = require('./modB.js')
console.log('modA.js-1', b.done)
exports.done = true
Console. Log ('modb. JS-2 ',' execution completed ')

// modB.js
exports.done = false
let a = require('./modA.js')
console.log('modB.js-1', a.done)
exports.done = true
Console. Log ('modb. JS-2 ',' execution completed ')

/*
modB.js-1 false
Modb.js-2 execution completed
modA.js-1 true
Modb.js-2 execution completed
Index.js-1 finished executing true
*/

The execution sequence is as follows:

  1. Node executes the index.js file and finds thatrequire('./modA.js'), pause the index.js code execution and enter the Moda module
  2. Found in Modarequire('./modB.js'), pause Moda code execution,Cache part of the executed Moda code, then enter the MODB module
  3. Found in MODBrequire('./modA.js')Extract cached partial Moda(because all Moda codes have been executed), execute all MODB codes, and,Cache MODB execution results, the execution stack returns to Moda
  4. Execute the remaining code of Moda. After that,Cache Moda, the execution stack returns index.js
  5. Found in index.jsrequire('./modBjs')Extract existing MODB cache, execute the remaining code

ES Module

// index.mjs
console.log("before import mod")
import { b } from "./mod.mjs"
console.log("b is " + b)
export let a = b + 1;

// mod.mjs
console.log("before import index")
import { b } from "./index.mjs"
console.log("b is " + b)
export let a = b + 1;

/*
before import a
a is undefined
before import b
b is NAN
*/

The order here is also very simple,

  1. Enter index.mjs,Promote the import (‘. / MODB. MJS’) statement to the top and execute it first, enter MODB
  2. promotePromote the import (‘. / index. MJS’) statement to the top, it is found that index.mjs has been executed hereTreat content imported from index as {}, execute the remaining code. After that, the execution stack returns index.mjs
  3. Execute remaining code