• 前端模块化:CommonJS,AMD,CMD,import/export


    模块化的开发方式可以提高代码复用率,方便进行代码的管理。通常一个文件就是一个模块,有自己的作用域,只向外暴露特定的变量和函数。目前流行的js模块化规范有CommonJS、AMD、CMD(前三者是ES5中提供的)以及ES6的模块系统import/export

    CommonJS

    Node.js是commonJS规范的主要实践者,它有四个重要的环境变量为模块化的实现提供支持:module、exports、require、global

    实际用时,使用module.exports(不推荐使用exports)定义对外输出的API,用require来引用模块。

    CommonJS对模块的定义主要分为:模块引用、模块定义、模块标识3个部分。

    1. 模块引用 ——const fs = require('fs');

    2. 模块定义
      function fn() {} exports.propName = fn; module.exports = fn;

    AMD(Asynchronous Module Definition)

    AMD,异步模块定义。AMD不是javascript原生支持,它是RequireJS在推广的过程中对模块定义的范围化的产出。所以使用AMD规范进行页面开发需要用到对应的库,也就是RequireJS。

    requireJS主要解决两个问题:

    • 多个js文件存在依赖关系时,被依赖的文件需要早于依赖它的文件加载到浏览器
    • js加载的时候浏览器会阻塞渲染线程,加载文件越多,页面失去响应的时间越长

    CMD(Common Module Definition)

    CMD, 通用模块定义。 CMD是在SeaJS推广的过程中产生的,是一个同步模块定义(CMD是依赖就近,在什么地方使用到插件就在什么地方require该插件,即用即返)。在CMD规范中,一个模块就是一个文件。

    AMD/CMD比较

    • 定义module时对依赖的处理

      • AMD推崇依赖前置,在定义的时候就要声明其依赖的模块
      • CMD推崇就近依赖,只有在用到这个module的时候才去require
    • 加载方式

      • AMD: async
      • CMD: sync
    • 执行module的方式

      • AMD加载module完成后就会执行该module,所有module都加载执行完成后会进入require的回调函数,执行主逻辑。依赖的执行顺序和书写的顺序不一定一致,谁先下载完谁先执行,但是主逻辑 一定在所有的依赖加载完成后才执行(有点类似Promise.all)。
      • CMD加载完某个依赖后并不执行,只是下载而已。在所有的module加载完成后进入主逻辑,遇到require语句的时候才会执行对应的module。module的执行顺序和书写的顺序是完全一致的。

    ES6 Module

    ES6 在语言标准的层面上,实现了模块功能,而且实现得相当简单,旨在成为浏览器和服务器通用的模块解决方案。

    其模块功能主要由两个命令构成:export和import。export命令用于规定模块的对外接口,import命令用于输入其他模块提供的功能。

    ES6 Modules不是对象,import命令会被 JavaScript 引擎静态分析,在编译时就引入模块代码,而不是在代码运行时加载,所以无法实现条件加载。也正因为这个,使得静态分析成为可能。

    ES6模块/CommonJS模块比较

    1、CommonJS 模块输出的是一个值的拷贝,ES6 模块输出的是值的引用

    • CommonJS 模块输出的是值的拷贝,也就是说,一旦输出一个值,模块内部的变化就影响不到这个值。
    • ES6 Modules 的运行机制与 CommonJS 不一样。JS 引擎对脚本静态分析的时候,遇到模块加载命令import,就会生成一个只读引用。等到脚本真正执行时,再根据这个只读引用,到被加载的那个模块里面去取值。换句话说,ES6 的 import 有点像 Unix 系统的“符号连接”,原始值变了,import加载的值也会跟着变。因此,ES6 模块是动态引用,并且不会缓存值,模块里面的变量绑定其所在的模块。

    2、CommonJS 模块是运行时加载,ES6 模块是编译时输出接口

    • 运行时加载: CommonJS 模块就是对象;即在输入时是先加载整个模块,生成一个对象,然后再从这个对象上面读取方法,这种加载称为“运行时加载”。
    • 编译时加载: ES6 模块不是对象,而是通过 export 命令显式指定输出的代码,import时采用静态命令的形式。即在import时可以指定加载某个输出值,而不是加载整个模块,这种加载称为“编译时加载”。
  • 相关阅读:
    一台计算机安装两个版本的MySQL
    用php实现显示上个月的最后一天
    SQL 如何去掉字段中千位的逗号(比如set @= '1,320.00' 想得到@= '1320.00' )
    jsp表单提交中的逻辑判断
    将两个字段中的值合并到一个字段中
    vue判断开始日期不能大于截至日期
    mySql中The user specified as a definer ('root'@'%') does not exist
    mysql GROUP_CONCAT给每个值加上单引号后再拼接
    javascript如何获取复选框中的值?
    mybatis中的useGeneratedKeys="true"
  • 原文地址:https://www.cnblogs.com/sunidol/p/11306283.html
Copyright © 2020-2023  润新知