美文网首页
js 模块化 commonJs AMD CMD ES Modul

js 模块化 commonJs AMD CMD ES Modul

作者: seaflyj | 来源:发表于2021-01-22 16:35 被阅读0次

    什么是模块化呢?

    事实上模块化开发最终的目的是将程序划分成一个个小的结构;
    这个结构中编写属于自己的逻辑代码,有自己的作用域,不会影响到其他的结构;
    这个结构可以将自己希望暴露的变量、函数、对象等导出给其结构使用;
    也可以通过某种方式,导入另外结构中的变量、函数、对象等;

    上面说提到的结构,就是模块;按照这种结构划分开发程序的过程,就是模块化开发的过程

    无论你多么喜欢JavaScript,以及它现在发展的有多好,我们都需要承认在Brendan Eich用了10天写出JavaScript的时候,
    它都有很多的缺陷:
    比如var定义的变量作用域问题;
    比如JavaScript的面向对象并不能像常规面向对象语言一样使用class;
    比如JavaScript没有模块化的问题;

    所以 js 并不是一个完美的语言,他需要被优化,需要模块化来帮助开发者解决问题

    于是利用函数调用表达式实现简单的模块化,即:

    IIFE (Immediately Invoked Function Expression)

    // aaa.js
    var aaa = (function(){
       var name = "123"
       return {
           name
       }
    })
    
    // bbb.js
    console.log(aaa.name)  // 123
    

    通过这种方式实现了简单的模块化,但是依然存在着诸多问题,比如模块变量名冲突,比如需要在入口文件将所有的js文件全部引入,不能做到按需引入,所以就需要一个规范,JavaScript社区为了解决上面的问题,涌现出一系列好用的规范,如 commonJs

    commonJs

    我们需要知道CommonJS是一个规范,最初提出来是在浏览器以外的地方使用,并且当时被命名为ServerJS,后来为了体现它的广泛性,修改为CommonJS,平时我们也会简称为CJS。

    • Node是CommonJS在服务器端一个具有代表性的实现;
    • Browserify是CommonJS在浏览器中的一种实现;
    • webpack打包工具具备对CommonJS的支持和转换;

    所以,Node中对CommonJS进行了支持和实现,让我们在开发node的过程中可以方便的进行模块化开发

    • 在Node中每一个js文件都是一个单独的模块;
    • 这个模块中包括CommonJS规范的核心变量:exports、module.exports、require;
    • CommonJS仅支持在服务端使用;

    require("") 是同步加载,代码执行中需要先加载require中的包,再去执行后面的代码,因为服务端读取的是本地的资源,所以同步加载的影响并不明显,如果在前端使用的话,加载异步模块就会耗费大量加载时间,造成后面代码无法执行,进而系统卡死;所以为了解能在前端也使用这个规范,AMD 应运而生,

    AMD

    CommonJS是主要为了JS在后端的表现制定的,他是不适合前端的,AMD(异步模块定义)出现了,它就主要为前端JS的表现制定规范

    AMD是"Asynchronous Module Definition"的缩写,意思就是"异步模块定义"。它采用异步方式加载模块,模块的加载不影响它后面语句的运行。所有依赖这个模块的语句,都定义在一个回调函数中,等到加载完成之后,这个回调函数才会运行。

    AMD也采用require()语句加载模块,但是不同于CommonJS,这里加载是异步的,不会阻塞后面的代码执行,加载成功之后的回调函数中执行相应的逻辑,这样,浏览器不会发生假死。所以很显然,AMD比较适合浏览器环境。目前,主要有两个Javascript库实现了AMD规范,require.js和curl.js。

    • 实现js文件的异步加载,避免网页失去响应;
    • 管理模块之间的依赖性,便于代码的编写和维护。
    define(['aaa','bbb'],function(aaa,bbb){...});
    

    AMD 特点

    对于依赖的模块,AMD推崇依赖前置,提前执行。也就是说,在define方法里传入的依赖模块(数组),会在一开始就下载并执行,也称之为运行时执行;

    CMD

    CMD规范,全称”Common Module Definition”,称为 通用模块加载规范 。一般也是用在浏览器端。浏览器端异步加载库 Sea.js 实现的就是CMD规范。

    AMD/CMD区别,虽然都是并行加载js文件,但还是有所区别,AMD是预加载,在并行加载js文件同时,还会解析执行该模块(因为还需要执行,所以在加载某个模块前,这个模块的依赖模块需要先加载完成);而CMD是懒加载,虽然会一开始就并行加载js文件,但是不会执行,而是在需要的时候才执行。

    CMD 特点

    对于依赖的模块,CMD推崇依赖就近,延迟执行。也就是说,只有到require时依赖模块才执行。

    ES Module

    JavaScript没有模块化一直是它的痛点,所以才会产生我们前面学习的社区规范:CommonJS、AMD、CMD等,所以在ES推出了自己的模块化系统ES Module。

    ES Module和CommonJS的模块化有一些不同之处:一方面它使用了import和export关键字;另一方面它采用编译期的静态分析,并且也加入了动态引用的方式;

    • ES Module模块采用export和import关键字来实现模块化:
    • export负责将模块内的内容导出;
    • import负责从其他模块导入内容;
    • 采用ES Module将自动采用严格模式:use strict;

    如果你不熟悉严格模式可以简单看一下MDN上的解析;
    https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Strict_mode

    /** 定义模块 math.js **/
    var basicNum = 0;
    var add = function (a, b) {
        return a + b;
    };
    export { basicNum, add };
            
    /** 引用模块 **/
    import { basicNum, add } from './math';
    function test(ele) {
        ele.textContent = add(99 + basicNum);
    }
    
    

    ES Module 与 CommonJS特点比较

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

    CommonJS加载的是整个模块,将所有的接口全部加载进来,ES6 Module可以单独加载其中的某个接口;

    CommonJS输出是值的拷贝,ES6 Module输出的是值的引用,被输出模块的内部的改变会影响引用的改变;

    CommonJS this指向当前模块,ES6 Module this指向undefined;

    相关文章

      网友评论

          本文标题:js 模块化 commonJs AMD CMD ES Modul

          本文链接:https://www.haomeiwen.com/subject/uqzszktx.html