• 前端模块化的演变过程


    随着前端的发展,无模块化存在的问题日益显露。但在这个过程中,模块化也是有一定的发展。

    stage1-文件划分方式

    根据业务或功能封装某一类变量或者函数;

    约定每一个文件都是一个模块;

    当使用到这个模块的时候,通过script标签引入到html页面中,直接使用模块中的成员(变量|函数);

    但当代码体积达到一定量的时候,这种方法的缺点就很明显了。 

    //module-a.js 
    
    var name = 'module-a'
    
    function method1 () {
      console.log(name + '#method1')
    }
    
    function method2 () {
      console.log(name + '#method2')
    }
    
    //module-b.js 
    
    var name = 'module-b'
    
    function method1 () {
      console.log(name + '#method1')
    }
    
    function method2 () {
      console.log(name + '#method2')
    }
    
    //index.html
      <script src="module-a.js"></script>
      <script src="module-b.js"></script>
      <script>
        // 命名冲突
        method1()
        // 模块成员可以被修改
        name = 'foo'
      </script>
    

    缺点:

    1. 全部变量都暴露在全局作用域中,没有私有空间,所有成员都可被外部访问或者修改
    2. 当模块达到一定数量,通过约定的方式很难避免变量冲突
    3. 无法管理模块与模块之间的依赖关系

    stage2-命名空间的方式

    每个模块只暴露一个全局对象,所有的成员都挂载到这个全局对象上

    //module-a.js
    var moduleA = {
      name: 'module-a',
    
      method1: function () {
        console.log(this.name + '#method1')
      },
    
      method2: function () {
        console.log(this.name + '#method2')
      }
    }
    
    //module-b.js
    var moduleB = {
      name: 'module-b',
    
      method1: function () {
        console.log(this.name + '#method1')
      },
    
      method2: function () {
        console.log(this.name + '#method2')
      }
    }
    
    //index.html
      <script src="module-a.js"></script>
      <script src="module-b.js"></script>
      <script>
        moduleA.method1()
        moduleB.method1()
        // 模块成员可以被修改
        moduleA.name = 'foo'
      </script>
    

    优点:

    通过“命名空间”减小了命名冲突的可能

    缺点:

    模块内部的成员依然在外部可以被访问和修改

    模块之间的依赖关系依然不明确

    stage3-通过立即执行函数(IIFE)为模块提供私有空间

    具体做法就是将模块内的代码放在一个立即执行函数中

    若想把某个成员暴露出去,就把该成员挂载到window中

    //module-a.js
    ;(function () {
      var name = 'module-a'
      
      function method1 () {
        console.log(name + '#method1')
      }
      
      function method2 () {
        console.log(name + '#method2')
      }
    
      window.moduleA = {
        method1: method1,
        method2: method2
      }
    })()
    
    //module-b.js
    ;(function ($) {
      var name = 'module-b'
      
      function method1 () {
        console.log(name + '#method1')
      }
      
      function method2 () {
        console.log(name + '#method2')
      }
    
      window.moduleB = {
        method1: method1,
        method2: method2
      }
      console.log($('#a').html());
    })(jQuery)
    
    //index.html
     <script src="module-a.js"></script>
      <script src="module-b.js"></script>
      <script>
        moduleA.method1()
        moduleB.method1()
        // 模块私有成员无法访问
        console.log(moduleA.name) // => undefined
      </script>
    

    优点:

    实现了成员私有化,模块内的变量外界不能随意访问

    通过立即执行函数,可以传递该模块所依赖的模块,使模块对外部的依赖更加清晰

    小结:综上所述,随着模块化的发展,之前所提到的问题也逐一被解决,但还是存在一部分没有解决的问题。先前所有模块都是通过script标签引入的。若我们需要某个模块时,通过script标签引入了该模块,但可能会忘记引入该模块所依赖的模块。或者当我们删除某个模块时,我们也可能会忘记该模块所依赖的模块。

    stage4-模块化规范的出现

    1.CommonJS

    ​ 特点:

    1.一个文件就是一个模块

    ​ 2.每个模块都有一个单独的作用域

       3.每个模块暴露出去的成员都由module.exports导出

    ​ 4.使用其他模块的成员时使用require函数导入

    ​ CommonJS规范主要引用在Node项目中,该规范加载模块时同步加载,倘若用在浏览器中,会有大量的同步请求导致应用比较慢,但在Node中不会有问题(因为Node是启动时加载模块)

    2.AMD规范(Asynchronous Module Definition

    ​ 代表库:require.js

    ​ 特点:

    ​ 不同于CommonJS的同步加载,该模块可以异步加载模块,提高程序在浏览器的执行效率

    ​ 但使用起来相对复杂

    3.CMD规范( Common Module Definition )

    ​ 代表库:Sea.js

    ​ 特点:

    ​ 使用上类似于require.js,写法类似于CommonJS,算是个重复的轮子

    4.ES Modules(ES2015的新语法)

    ​ 特点:

    ​ 语言层面推出的新语法,比较完善

    ​ 满足在web端开发使用模块化的需求

    综上所述:目前前端模块化基本统一成了CommonJS(Node.js)和ES Modules(浏览器端开发),我们只需掌握这两种规范开发即可,后续会对着两个模块重点展开讨论

    End of the article,share a word with you!
    所谓的焦虑和迷茫,其实是身体懒惰和脑子勤奋的矛盾。I'm on my way!
  • 相关阅读:
    现代算法(一) 基因算法
    01-02周 学习总结
    Linux命令之touch详解
    Linux命令之umask详解
    Linux命令之wc详解
    Linux命令之stat详解
    Linux命令之tail详解
    Linux命令之head详解
    Linux命令之less详解
    Linux命令
  • 原文地址:https://www.cnblogs.com/zhaojian-08/p/14368990.html
Copyright © 2020-2023  润新知