Home > Web Front-end > JS Tutorial > Detailed analysis of front-end modularization in JS and comparison of its differences

Detailed analysis of front-end modularization in JS and comparison of its differences

不言
Release: 2018-08-13 17:34:32
Original
1818 people have browsed it

This article brings you a detailed analysis and comparison of front-end modularization in JS. It has certain reference value. Friends in need can refer to it. I hope it will be helpful to you.

Throwing questions:

  • require and import are often used when importing modules during development;

  • When exporting a module, use module.exports/exports or export/export default;

  • Sometimes To reference a module, require is used. Strangely, import can also be used? ? ? ? What's the difference between them?

So there is a search process for rookies to solve their doubts. . . . .

Trace back to the root cause and come to the Js modular specification

1, CommonJS specification (synchronous loading of modules)

  • Allow modules to pass the require methodSynchronically load other modules that depend on, and then export the interfaces that need to be exposed through exports or module.exports.

  • Usage:

// 导入
require("module");
require("../app.js");
// 导出
exports.getStoreInfo = function() {};
module.exports = someValue;
Copy after login
    • Because the modules are placed on the server side, for the server side When loading the module

    • As for the browser side, because the modules are placed on the server side, the loading time also depends on factors such as the speed of the network. If it takes a long time, the entire The application will be blocked.

    • Therefore, browser-side modules cannot use "synchronous loading" (CommonJs), but can only use "asynchronous loading" (AMD).

    • Advantages Disadvantages:

    • ?
    • Why can’t the browser use synchronous loading, but the server can?
    Synchronous loading
    The method is not suitable for use in a browser environment. Synchronization means blocking loading, and browser resources are loaded asynchronously
  1. Cannot load multiple modules in parallel without blocking

  2. Simple and easy to use
  1. Server-side modules are easy to reuse

  2. Refer to the CommonJs module to represent the module system of node.js
  • AMD (Asynchronous loading module)

The module is loaded asynchronously. The loading of the module does not affect the running of subsequent statements. All statements that depend on modules are defined in a callback function. The callback function is not executed until the loading is completed.

  • Usage example:

  • // 定义
    define("module", ["dep1", "dep2"], function(d1, d2) {...});
    // 加载模块
    require(["module", "../app"], function(module, app) {...});
    Copy after login

  • Load module
require([module], callback);
    The first parameter [module] is an array, and the members inside are the modules to be loaded; the second parameter callback is the callback function after the loading is successful.
  • Advantages:

  • Suitable for asynchronous loading of modules in a browser environment
  1. Multiple modules can be loaded in parallel

  2. Disadvantages:
  • Increases development costs and makes it difficult to read and write code , the semantics of the module definition method are not smooth
    1. does not conform to the general modular way of thinking, and is a compromised implementation

    2. Implementing the AMD specification represents
    3. require.js
  • RequireJS's attitude towards modules is pre-execution. Since RequireJS is an executed AMD specification, all dependent modules are executed first; that is, RequireJS executes the dependent modules in advance, which is equivalent to advancing the require

  • RequireJS execution process:
    • The require function checks the dependent modules and obtains the actual path of the js file according to the configuration file
    1. According to the js file Actual path, insert the script node in the dom, and bind the onload event to get notification that the module is loaded.

    2. After all dependent scripts are loaded, call the callback function

    3. CMD specification (asynchronous loading module)

    The CMD specification is very similar to AMD, simple, and maintains great compatibility with the Modules specification of CommonJS and Node.js; in the CMD specification, a module is a file.

    • The definition module uses the global function define, which receives the factory parameter. Factory can be a function, an object or a string;

    • factory is a function with three parameters, function(require, exports, module):

    • require is a method that accepts the module ID as the only parameter to obtain other The interface provided by the module: require(id)
    1. exports is an object, used to provide the module interface to the outside world

    2. module is an object, The above stores some properties and methods associated with the current module

    3. Example:
    4. define(function(require, exports, module) {
        var a = require('./a');
        a.doSomething();
        // 依赖就近书写,什么时候用到什么时候引入
        var b = require('./b');
        b.doSomething();
      });
      Copy after login
    • 优点:

    1. 依赖就近,延迟执行

    2. 可以很容易在 Node.js 中运行

    • 缺点:

    1. 依赖 SPM 打包,模块的加载逻辑偏重

    • 实现代表库sea.js:SeaJS对模块的态度是懒执行, SeaJS只会在真正需要使用(依赖)模块时才执行该模块

    AMD 与 CMD 的区别

    1. 对于依赖的模块,AMD 是提前执行,CMD 是延迟执行。不过 RequireJS 从2.0开始,也改成了可以延迟执行(根据写法不同,处理方式不同)。CMD 推崇 as lazy as possible.

    2. AMD推崇依赖前置;CMD推崇依赖就近,只有在用到某个模块的时候再去require。

    // AMD
    define(['./a', './b'], function(a, b) {  // 依赖必须一开始就写好  
       a.doSomething()    
       // 此处略去 100 行    
       b.doSomething()    
       ...
    });
    // CMD
    define(function(require, exports, module) {
       var a = require('./a')   
       a.doSomething()   
       // 此处略去 100 行   
       var b = require('./b') 
       // 依赖可以就近书写   
       b.doSomething()
       // ... 
    });
    Copy after login

    UMD

    • UMD是AMD和CommonJS的糅合

    • AMD 以浏览器第一原则发展异步加载模块。

    • CommonJS 模块以服务器第一原则发展,选择同步加载,它的模块无需包装。

    • UMD先判断是否支持Node.js的模块(exports)是否存在,存在则使用Node.js模块模式;在判断是否支持AMD(define是否存在),存在则使用AMD方式加载模块。

    (function (window, factory) {
        if (typeof exports === 'object') {
        
            module.exports = factory();
        } else if (typeof define === 'function' && define.amd) {
        
            define(factory);
        } else {
        
            window.eventUtil = factory();
        }
    })(this, function () {
        //module ...
    });
    Copy after login

    ES6模块化

    • ES6 在语言标准的层面上,实现了模块功能,而且实现得相当简单,完全可以取代 CommonJS 和 AMD 规范,成为浏览器和服务器通用的模块解决方案。

    • ES6 模块设计思想:尽量的静态化、使得编译时就能确定模块的依赖关系,以及输入和输出的变量(CommonJS和AMD模块,都只能在运行时确定这些东西)。

      • 使用方式:

    // 导入
    import "/app";
    import React from “react”;
    import { Component } from “react”;
    // 导出
    export function multiply() {...};
    export var year = 2018;
    export default ...
    ...
    Copy after login
    • 优点:

    1. 容易进行静态分析

    2. 面向未来的 EcmaScript 标准

    • 缺点:

    1. 原生浏览器端还没有实现该标准

    2. 全新的命令字,新版的 Node.js才支持。

    回到问题“require与import的区别”

    • require使用与CommonJs规范,import使用于Es6模块规范;所以两者的区别实质是两种规范的区别;

    • CommonJS:

    1. 对于基本数据类型,属于复制。即会被模块缓存;同时,在另一个模块可以对该模块输出的变量重新赋值。

    2. 对于复杂数据类型,属于浅拷贝。由于两个模块引用的对象指向同一个内存空间,因此对该模块的值做修改时会影响另一个模块。

    3. 当使用require命令加载某个模块时,就会运行整个模块的代码。

    4. 当使用require命令加载同一个模块时,不会再执行该模块,而是取到缓存之中的值。也就是说,CommonJS模块无论加载多少次,都只会在第一次加载时运行一次,以后再加载,就返回第一次运行的结果,除非手动清除系统缓存。

    5. 循环加载时,属于加载时执行。即脚本代码在require的时候,就会全部执行。一旦出现某个模块被"循环加载",就只输出已经执行的部分,还未执行的部分不会输出。

    • ES6模块

    1. ES6模块中的值属于【动态只读引用】。

    2. 对于只读来说,即不允许修改引入变量的值,import的变量是只读的,不论是基本数据类型还是复杂数据类型。当模块遇到import命令时,就会生成一个只读引用。等到脚本真正执行时,再根据这个只读引用,到被加载的那个模块里面去取值。

    3. 对于动态来说,原始值发生变化,import加载的值也会发生变化。不论是基本数据类型还是复杂数据类型。

    4. 循环加载时,ES6模块是动态引用。只要两个模块之间存在某个引用,代码就能够执行。

    • Finally: require/exports is necessary, universal and necessary; because in fact, the import/exports you write so far are eventually compiled into require/exports for execution.

    Related recommendations:

    js code to implement data transfer between pages

    JS Tutorial--Dynamic Planning Algorithm backpack capacity problem

    Explanation of knowledge about scope and closure in javaScript

    The above is the detailed content of Detailed analysis of front-end modularization in JS and comparison of its differences. For more information, please follow other related articles on the PHP Chinese website!

    Related labels:
    source:php.cn
    Statement of this Website
    The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
    Popular Tutorials
    More>
    Latest Downloads
    More>
    Web Effects
    Website Source Code
    Website Materials
    Front End Template