Detailed explanation of how Node.js handles ES6 modules

Detailed explanation of how Node.js handles ES6 modules

1. Differences between the two modules

There are significant differences between ES6 modules and CommonJS modules.

In terms of syntax, CommonJS modules are loaded using require() and exported using module.exports, while ES6 modules use import and export.

In terms of usage, require() is a synchronous load, and the subsequent code must wait for this command to be executed before it will be executed. The import command is asynchronous loading, or more precisely, the ES6 module has an independent static parsing phase, the dependency analysis is completed at that stage, and the lowest-level module is executed first.

2. The difference between Node.js

Node.js requires ES6 modules to use the .mjs suffix file name. In other words, as long as the import or export command is used in the script file, the .mjs suffix must be used. When Node.js encounters a .mjs file, it considers it an ES6 module and enables strict mode by default. You don't need to specify "use strict" at the top of each module file.

If you do not want to change the suffix to .mjs, you can specify the type field as module in the project's package.json file.

{
   "type": "module"
}

Once set, the JS scripts in this directory will be interpreted as ES6 modules.

# Interpret as ES6 module

$ node my-app.js

If you still want to use CommonJS modules at this time, you need to change the suffix of CommonJS scripts to .cjs. If there is no type field, or the type field is commonjs, the .js script will be interpreted as a CommonJS module.

To sum it up in one sentence: .mjs files are always loaded as ES6 modules, .cjs files are always loaded as CommonJS modules, and the loading of .js files depends on the setting of the type field in package.json.

Note that ES6 modules and CommonJS modules should not be mixed. The require command cannot load .mjs files and will report an error. Only the import command can load .mjs files. Conversely, the require command cannot be used in .mjs files, and import must be used.

3. CommonJS module loading ES6 module

The require() command of CommonJS cannot load ES6 modules and will report an error. You can only use the import() method to load them.

(async () => {
  await import('./my-app.mjs');
})();

The above code can be run in a CommonJS module.

One reason why require() does not support ES6 modules is that it is loaded synchronously, and the top-level await command can be used inside ES6 modules, which makes it impossible to load synchronously.

4. ES6 modules load CommonJS modules

The import command of ES6 modules can load CommonJS modules, but only as a whole, not just a single output item.

// Correct import packageMain from 'commonjs-package';

// Error import { method } from 'commonjs-package';

This is because ES6 modules need to support static code analysis, and the output interface of CommonJS modules is module.exports, which is an object and cannot be statically analyzed, so it can only be loaded as a whole.

Loading a single output item can be written as follows.

import packageMain from 'commonjs-package';
const { method } = packageMain;

5. Modules that support both formats

It is also easy to support both CommonJS and ES6 formats for a module.

If the original module is in ES6 format, an overall output interface needs to be given, such as export default obj, so that CommonJS can load it using import().

If the original module is in CommonJS format, then a wrapper layer can be added.

import cjsModule from '../index.js';
export const foo = cjsModule.foo;

The above code first imports the CommonJS module as a whole, and then outputs the named interface as needed.

You can change the file extension to .mjs, or put it in a subdirectory and put a separate package.json file in that subdirectory, specifying { type: "module" }.

Another approach is to specify the loading entry points of the two formats of modules in the exports field of the package.json file.

"exports": { 
    "require": "./index.js",
    "import": "./esm/wrapper.js" 
}

The above code specifies require() and import, and loading the module will automatically switch to a different entry file.

The above is a detailed explanation of how Node.js handles ES6 modules. For more information about how Node.js handles ES6 modules, please pay attention to other related articles on 123WORDPRESS.COM!

You may also be interested in:
  • Understanding and application of JavaScript ES6 destructuring operator
  • JavaScript to implement the most complete code analysis of simple carousel (ES6 object-oriented)
  • JavaScript to implement the most complete code analysis of a simple shopping cart (ES6 object-oriented)
  • Detailed explanation of the differences between var, let and const in JavaScript es6
  • Differences between ES6 inheritance and ES5 inheritance in js
  • Detailed explanation of JS ES6 coding standards
  • JS quickly master ES6 class usage
  • Detailed explanation of JS ES6 variable destructuring assignment
  • Several magical uses of JS ES6 spread operator
  • About front-end JavaScript ES6 details

<<:  Nginx http health check configuration process analysis

>>:  Solve the problem of blocking positioning DDL in MySQL 5.7

Recommend

Graphic tutorial on installing Ubuntu 18.04 on VMware 15 virtual machine

In the past few years, I have been moving back an...

Detailed explanation of the new array methods in JavaScript es6

Table of contents 1. forEach() 2. arr.filter() 3....

Vue.js front-end web page pop-up asynchronous behavior example analysis

Table of contents 1. Preface 2. Find two pop-up c...

How does MySQL ensure master-slave consistency?

Table of contents The basic principle of MySQL ma...

Nginx+FastDFS to build an image server

Installation Environment Centos Environment Depen...

Summary of javascript date tools

let Utils = { /** * Is it the year of death? * @r...

Steps to configure IIS10 under Win10 and support debugging ASP programs

Microsoft IIS IIS (Internet Information Server) i...

CentOS 7.9 installation and configuration process of zabbix5.0.14

Table of contents 1. Basic environment configurat...

Detailed explanation of how to copy and backup docker container data

Here we take the Jenkins container as an example ...

base target="" controls the link's target open frame

<base target=_blank> changes the target fram...

A collection of possible problems when migrating sqlite3 to mysql

Brief description Suitable for readers: Mobile de...

Basic usage examples of Vue named slots

Preface Named slots are bound to elements using t...

Use of Linux bzip2 command

1. Command Introduction bzip2 is used to compress...