1, an overview of the

  1. Problems to be solved by modularization:

    • How to package the code of a module so that it does not pollute the code outside the module;
    • How to uniquely identify a module;
    • How to expose the module’s API without adding global variables;

    Browser-side modularity to solve the following problems:

    • Referenced JS modules are pre-downloaded, but only executed when used;

    • The referenced JS module is downloaded directly and then executed;

  2. Modular solutions previously used

    • CommonJS: for server side (implementation: Node.js);
    • Asynchronous Module Definition AMD(Asynchronous Module Definition) : at the browser end (implementation: require.js, sea-.js);
    • UMD (Universal Module Defination) : integrate CommonJS and AMD, both server side and browser side can use (implementation: require.js, sea-.js);

    However, they can only be loaded dynamically and cannot be optimized at static compile time.

  3. Modular solutions now

    The export and import

    ES6 provides modularization functions from the language level. The idea is to be as static as possible, so that the dependencies of modules can be determined at compile time.


2. Modular Solution for Node.js for servers (CommonJS)

Node.js uses module.exports to expose modules and require() to refer to modules;

1. Code demonstration

Exposure module:

// ./info.js
const students = {};
const teachers = {};
module.exports = {
    students,
    teachers
}
Copy the code

Reference module:

// ./index.js
const { teachers } = require('./info.js'); // The entire referenced Module is initialized as a Module object;

Copy the code

2. The principle of Node.js modularity

Before executing the module code, Node.js will wrap it with a function wrapper like this:

(function(exports.require.module, __filename, __dirname) {
// The module code actually exists here
});
Copy the code

Module, exports, module.exports, require();

  • A module is a reference within a module to the module object itself;

  • Module. exports is a module property; The attribute value contains the output of the module.

  • Exports is a variable pointing to module.exports;

  • Require () is a function used to load modules; Module. exports of loaded modules is returned;

    The principle behind using require() to reference modules is as follows:

    • The require command first loads the script file, executes the entire script file, and then generates an object in memory.
    • When the module is used again in the future, the object generated the first time will be found in the cache;

    When the script code is required, it’s all executed, which is called “runtime loading.”

    Cyclic loading of modules: once a module is “cyclic loaded”, only the parts that have been executed are output, and the parts that have not been executed are not output;


3. Explain the browser-side modular solution based on sea-.js

Module references using require(), exposed using module.exports; And all modules are defined by define;

define(function(require.exports.module) {

    const { getAwards } = require('./sea-modules/serversApi');

	module.exports = { getAwards };
     
})
Copy the code

Note that if you want to use sea-.js, add the following code to the HTML file:

<! Sea-.js -->
<script src=". / seajs - 2.2.0 / sea. Js. ""></script>
<script>
    / / configuration
    seajs.config({
        base:". /"
    })
    // Specify the entry file for the module. The actual path is the URL in the base field + seajs.use() in the configuration, i.e./index
    seajs.use("index");
</script>
Copy the code

I wrote an example using the sea-.js module that can be cloned to try it out: gitee.com/hotpotliuyu…

This is an issue of sea.js: github.com/seajs/seajs… Sea. Js;


4. Modular solutions in ES6

ES6 provides a modular solution at the language level. Export is used to specify the code to be exported and import is used to input the code.

Eg:

Exposure module:

// ./info.js
const students = {};
const teachers = {};
export {
    students,
    teachers
}
Copy the code

Introduction module:

// ./index.js
import { students as stus } from '.info.js' 
Copy the code

Using import to load modules works like this:

Only teachers are loaded. Other unused content is not loaded. This is called “compile time loading”.

Benefits of loading at compile time:

  • The module can be static analysis (macro, type detection);
  • Don’t needUMDModule specification;

ES6 modules automatically adopt strict mode, with the top layer this pointing to undefined;

1, the export

Export specifies the exposed interface;

const students = {};
const teachers = {};
export {
    students,
    teachers,
    teachers as teachers1
}
Copy the code
  • You can use the AS keyword to rename the exposed interface so that the same interface can be exposed multiple times.

  • Note that the value of a variable should not be exposed directly, but should be exposed;

    export var a = 1; / / is not an error
    
    / / an error
    var a = 1;
    exportA;/ / is not an error
    var a = 1;
    export {
    	a
    }
    Copy the code
  • The variables output by export correspond to real-time values inside the module, which is different from the copy of values output by Commonjs module.

  • The export statement can be placed anywhere in the outermost scope within the module;

2, the import

Using the import command, you can load the corresponding module:

import { teachers as teachs } from './info.js';

import './info.js'; // Load the module without loading anything into the module
import * as info from './info.js'; // Load all interfaces exposed by the module into the module;
Copy the code
  • The variable name immediately following import must be the same as the interface variable name exposed by the imported module, but can be aliased using AS.

  • Import Input variables are read-only;

  • The from after import specifies the location of the module file, which can be a relative or absolute path. /node_modules, and the JavaScript engine loads the module based on the mian field of the module’s package.json file.

  • The suffix.js of the script path file cannot be omitted. This is different from the original modularity specification which used require() to introduce module files without a suffix;

  • The import command also has code-enhancing effects;

  • If the same import statement is executed more than once, it is executed only once.

  • Balbel transcoding is now possible so that require and import can be used together;

3, the export default

Use export default to specify the default output for the module;

Export default can only be used once in a module, and there is only one default output. Therefore, when importing import, you can name the output arbitrarily instead of using the same variable names as the export command.

// info.js
export default function(){
    // ...
}
Copy the code
// index.js
import getu from 'infof.js'
Copy the code

The export default command essentially uses a variable name named default. Therefore, the export default command cannot be followed by a variable declaration statement, but only one value (contrary to the provisions of export).

4. Composite writing of export and import, module inheritance, cross-module constant solution

A compound of export and import

export { teachers,students } from './info.js';

// Simple equivalent
import { teachers,students } from './info.js';
export { teachers,students };
Copy the code

After writing a line, teachers and students actually do not import the current module, but just equivalent to external forwarding these two interfaces, so that the current module cannot directly use teachers and students.

The compound method does not forward the default method;

Module inheritance

The output of a module is inherited by combining export and import.

// ./circle.js
export * from './info.js';
export var name = 'circle';
export default function() {
    // ...
}
Copy the code

The./ circ.js module inherits all output from./info.js and has its own output;




The resources

Js modularization process

JS module tool RequireJS tutorial

Sea. Js document

ES6 syntax for modules








Give it a thumbs up if it helps. If you want to know more about the blogger:

GitHub:github.com/hotpotliuyu…

Gitee:gitee.com/hotpotliuyu…

Public account: Hotpot National Technology Department