“This is the 17th day of my participation in the First Challenge 2022.

CommonJs specification and Node implementation

Exports: exported objects

Module. exports: Exported objects

Require () : Imports objects

Module. exports=exports node implements module.exports=exports(exports are an object)

CommonJs loads synchronously: synchronously means that the contents of the current module cannot be run until the corresponding module is loaded.

Module loading process

1. When a module is first introduced, the JS code in the module will be run once

2. When modules are introduced several times, they will be cached and only loaded (run) once

3. If loops are introduced, Node uses a depth-first algorithm to run the introduced module.

The require details

There are three common rules for require imports:

  1. If the imported X is a node core module, such as PATH, HTTP, the system directly returns to the core module to stop the search.

  2. The imported X starts with./ or.. / or/(root directory),

    One: look it up as a file, if there is a suffix, directly find the corresponding file.

    If there are no suffixes, search in this order:

    1. Find the x.js file
    2. Find the x.json file
    3. Find the X. ode file

    2: If no corresponding file is found, use X as a folder and look for the following files under it:

    1. X/index.js
    2. X/index.json
    3. X/index.node

    If still not found, return not Found

  3. Import an X directly, which is not a core module, and look for it in node_module of the current folder. If it doesn’t find it, look for it in node_module of the upper directory. If not found, not found is returned.

CommonJS loading process

CommonJS is loaded at runtime and synchronously.

  1. Runtime loading means that the JS engine loads the module when it executes js code.
  2. Synchronization means that when a module is loaded, subsequent code cannot run.

ES module

After ES6, JS has ES Module modularization. ES Module uses the import and export keywords to import and export. ES Moudule is loaded asynchronously.

Using ES Module will automatically adopt strict mode.

use

Browser:

In the browser, to open the page by establishing a service, directly through the local file form will package CORS error.

Module <script SRC ="./ exception. Js "type="module"></script>Copy the code
Node environment:

In the Node environment, if there is no package file, we need to write the js file suffix as MJS before Node uses it as a module.

Import Import mode

  1. : import {list of identifiers} from ‘module’

     import {name,age} from './foo.js'
    Copy the code
  2. Identifiers are aliased at import time

     import {name as fname,age as fage} from './foo.js' 
    Copy the code
  3. Put module functionality on a module object by *

     import * as baz from './foo.js'
    Copy the code

Export Export mode

  1. : Directly precede the statement declaration with the export keyword

     export const name='wang'
    Copy the code
  2. : Place all identifiers to be exported in {} after export

    Note: {} is not an enhanced representation of ES6 object literals, nor is {} an object

     export {
         name,
         age,
         foo
     }
    Copy the code
  3. Give the identifier an alias when exporting

    // change name,age,foo to Fname,Fage,Ffoo export {name as Fname, age as Fage, foo as Ffoo}Copy the code

The combination of export and IMPOT

Export {d,c} from './aaa.js';Copy the code

Application scenario: When we are encapsulating our own files, each file has an export interface, so that users must know which file exported to which interface, which is very convenient for users. Users can use the library by importing all interfaces in one file and exporting them directly, so that they only need to know that one interface file.

default

//foo.js export default foo; Import baz from './foo.js' import baz from './foo.Copy the code

The import load

Import loading is used to determine the import and export relationships between modules during code parsing, so it cannot be used in logical code.

Es provides an import () function that dynamically loads modules.

let tag = true; if (tag) { import ('./foo.js').then((res) => { console.log(res.foo.name); })}Copy the code

The ES Module load is asynchronous and does not block the loading of other files.

ESmodule parsing in the browser

Parsing is divided into three stages:

  1. The Construction finds the JS file by address, downloads it, and parses it into a Module Record.
  2. Instantiation: instantiates module records, allocates memory space, parses module import and export statements, and points the module to the corresponding memory address.
  3. Evaluation runs the code, evaluates the value, and populates the value into the memory address.
Phase 1: Construction phase

Construction: Download the main.js Module file, and the browser gets the main.js file. The browser statically parses the main.js file (without running the code) to generate a Module Record data structure. RequestedModules in Module Record records dependent files. Then download the main.js dependent JS file and generate the corresponding Module Record data structure. If counter.js and display.js depend on other files, continue to load the corresponding dependency file and perform static parsing. Terminates until no more files are relied upon. (There is a Map in the browser that keeps track of downloaded and downloaded files, ensuring that the same file is not downloaded twice.)

Phases two and three: instantiation phase – evaluation phase

Instantiation stage: The Module Record will be instantiated as a Module Environment Record, save the exported value in memory, and then bind the exported value of the Module Record, main.js is to bind the imported value. The value of the variable in memory is undefined.

Evaluation stage: Run the downloaded file, calculate the value of the variable in memory, replace the value of the variable saved in memory.

Note: Exported modules can change the value of variables, imported modules cannot change the value of variables.

ES Module loading process

When export exports a variable, js engine will parse this syntax and create module environment record. Module environment record will bind the variable, and this binding is real-time, and we can get the latest value of the binding in real time at the place of import.

//foo.js var name = 'wang'; var age = 23; Var foo = {name: 'fawef'} // Braces are not objects setTimeout(() => {name = 'list'; }, 1000); export { name, age }; //index.js import { name, age } from './foo.js' console.log(name); //wang console.log(age); //23 setTimeout(() => { console.log(name); //list }, 2000);Copy the code

AMD

AMD is the asynchronous loading specification, used on the browser side. The requirejs library is used for loading.

Import:

The require. Config ({baseUrl: "SRC", paths: {/ / definition module a: ". / a, "b:". / b ",},}); // require(["a"], function (foo) {console.log(foo); });Copy the code

Export:

 define(function () {
   const name = "why";
   const age = 18;
   function sum(num1, num2) {
     return num1 + num2;
   }
   return {
     name,
     age,
     sum,
   };
 });
Copy the code

CMD

Use SEAJS for asynchronous loading.

The callback takes three arguments:

  1. The require() function imports the file
  2. Exports exports variables and objects
  3. Moudle.exports exports variables and objects
 define(function (require, exports, moudle) {
    
   const re = require("./foo.js");
   console.log(re);
 });
Copy the code

CommonJs and ES Module interaction

  1. CommonJs and ES Modules cannot be imported and exported from each other in the browser.

  2. In the node:

    1. Commonjs is not allowed to load esModule

      Reason: Because CommonJS is loaded synchronously, but ES Module must be statically analyzed, etc., JavaScript code cannot be executed at this time;

    2. Esmodule can load CommonJS

      ES Module uses its module.exports export as default when loading CommonJS

  3. In normal development, commonJS and ES Modules can be loaded to each other in a Webpack-based environment.