After learning JS and using Node.js, you should have some understanding and use of modularity, so you must have seen the following two methods of module import and export

The first is ES6 Module

// B.js
function show() {
	console.log('Show method executed')}export default show

// A.js
import show from './B.js'
show()  // The show method is executed
Copy the code

Second: CommonJS

// B.js
function show() {
	console.log('Show method executed')}module.exports = {
	show
}

// A.js
const bModule = require('./B.js')

bModule.show()  // The show method is executed
Copy the code

The above two import and export methods involve two Module specifications, ES6 Module and CommonJS

This article will talk about the specific use and difference between the two

1. CommonJS

CommonJS is a standard for modularity introduced by the JavaScript community in 2009 and later adopted and implemented by Node.js. This means that all module imports and exports we use in Node.js are implemented according to the CommonJS standard

1.1 export

We can think of a file as a module, each module is independent of each other, that is, does not affect each other. When you need to use a module, you simply import the target module into a file

To be imported by another module, you first need to export variables or methods that you want to expose. There are two ways to export syntax in CommonJS

// B.js
// Define the function show
function show() {
	console.log('Show method is called')}// The variable count is defined
let count = 3

/*-------------- Export method --------------*/

/ / the first
module.exports = {
	show,
	count
}

/ / the second
exports.show = show
exports.count = count
Copy the code

In the above code, the two export methods are equivalent.

The first is to store functions or variables to be exported in module.exports, where module.exports is an empty object

In the second type of export, exports actually refer to module.exports internally, so we execute exports. Exports. This is the equivalent of storing a variable or function in module.exports

Note: it is important to note that exports cannot be re-assigned when using the second export, otherwise it will directly cover module.exports

1.2 the import

Take a look at the CommonJS import syntax again

// A.js
const bModule = require('./B.js')

console.log(bModule.count)  / / 3

bModule.show()  // The show method is called
Copy the code

The CommonJS module is imported using the require method, which takes the path to the module file. It is important to note that the object we receive after importing the module is the value of module.exports, from which we can obtain the required variables or functions

In particular, the require method can also take an expression as an argument, as shown below

let fileName = 'B.js'
const bModule = require('/' + fileName)
Copy the code

Therefore, we can dynamically change and determine the load and import path of the module

2. ES6 Module

As the title says, the module standard was only proposed in ES6, after which JS has the feature of modularity

2.1 export

In ES6 Module, the keyword export is used to export. There are two ways to export: named export and default export

The first is named export

// B.js
/*-------- Export a single variable or function ----------*/
export function show() { console.log('Show method is called')}export let count = 3

/*-------- Export ----------*/ in batches
function show() { console.log('Show method is called')}let count = 3

export {show, count}
Copy the code

The above code is divided into two cases, and these two ways of writing are equivalent

The first is to export a single variable or function. You only need to use the export keyword at the beginning.

The second scenario is to export multiple variables or functions in bulk, and simply store them in a single object

The second option: export by default

// B.js
function show() { console.log('Show method is called')}// Name the export variable count
export let count = 3

// Default export function show
export default show
Copy the code

The default export is an export keyword followed by a default to indicate that the exported variable or function is anonymous

Note: a module can only be exported once by default, otherwise an error will be reported, for reasons explained later

2.2 the import

The keyword import for the ES6 Module is import. The specific code is as follows

// A.js
import {show, count} from './B.js'

show()   // The show method is called

console.log(count)  / / 3
Copy the code

An ES6 Module import requires a pair of {} braces to accept the method or function we want to import

Note: The variable or function name in the braces must be exactly the same as the exported name

So if we want to change the name of the imported variable or function, we can use the as keyword to name it, as follows

// A.js
import {show as print, count as number} from './B.js'

print()   // The show method is called

console.log(number)  / / 3
Copy the code

If we want to import all the variables or functions, we can import them as a whole using *, as follows

import * as bModule from './B.js'

bModule.show()  // The show method is called

console.log(bModule.count)  / / 3
Copy the code

* means all, we import it all and assign it to the bModule so that we can get the desired variable or object from the bModule

That’s all for named exported variables or functions, so how do you import a default exported variable or function?

// Import the variables exported through export default
import print from './B.js'

print()  // The show method is called
Copy the code

All named exported variables are received by {}, so if you leave out {}, you will receive the default exported variables, because the exported variables are anonymous, so you can choose any variable name you want to receive

Note that, unlike CommonJS, the import file path for ES6 Modules does not support expressions

3. Differences between CommonJS and ES6 Modules

The main differences between the two are as follows:

  1. For Module dependencies, CommonJS is dynamic, while ES6 Modules are static
  2. CommonJS imports a copy of the value. ES6 Module imports a reference to the value

3.1 the difference between a

What is dynamic about dependencies on modules? What is static?

Dynamic means that dependencies on modules are established during code execution; Static means that dependencies on modules are established during code compilation.

As mentioned earlier, when importing CommonJS, require’s path parameter is expression supported, for example

// A.js
let fileName = 'example.js'
const bModule = require('/' + fileName)
Copy the code

Since this path can be changed dynamically during code execution, it would be inaccurate to establish the dependencies of modules during code compilation. The dependencies of modules can only be confirmed after the code is run, so CommonJS is dynamic.

Now you know why the ES6 Module is static

3.2 the difference between the two

To test this, I’m going to use an example

First, verify CommonJS. The code looks like this

// B.js
let count = 3

function change() {
    count ++    // Count + 1
    console.log('原count值为:', count);  // Print the value of count in module B.js
}

module.exports = {
    count,
    change
}

// A.js
let count = require('./B.js').count 
let change = require('./B.js').change

console.log('Before change:', count);   
change()     // Call the change method in module B.js and change the original count + 1
console.log('After change:', count); 

// The result of running the a.js fileBefore the change:3The original count value is:4After the change:3
Copy the code

In the code above, we can see that the variable count and function change from the b. js file are imported into the a.js file, because the imported count is just a copy of the original value. So even if we call change to change the value of the variable count in the b. js file, it will not affect the variable count in the A.js file

From this result, it is concluded that the variables imported by CommonJS are copies of the original values


Let’s verify the ES6 Module again

// B.js
let count = 3

function change() {
    count ++        // Count + 1
    console.log(count);   // Print the value of count in module B.js
}

export {count, change}

// A.js
import {count, change} from './B.js';

console.log('Before change:',count);

change()         // Call the change method in module B.js and change the original count + 1

console.log('After change:', count);

// The result of running the a.js fileBefore the change:3The original count value is:4After the change:4
Copy the code

The ES6 Module imported variable count is changed with the original value compared to the CommonJS result

Based on this result, it is concluded that the variables imported by the ES6 Module are references to the original values

Note: If the ES6 Module is imported by default, it is a copy of the value in the original Module, not a reference

4. The end

That’s the end of this article. There are a few things about CommonJS and ES6 Modules that were not covered in this article, but I hope you’ll learn more about them

Pay attention to the public number: front-end impression, daily share a high-quality front-end technical text, but also to get rich front-end data