程序员

模块化的演进过程

2021-01-19  本文已影响0人  翔子丶
现代化项目

模块化的演进过程

  1. 文件划分方式

    web最原始的模块系统,每个功能及相关状态数据单独放在不同js文件中,约定每个文件是一个独立的模块

    ├── module-a.js
    ├── module-b.js
    └── index.html
    

    缺点:

    • 模块直接在全局工作,污染全局作用域
    • 没有私有空间,模块内成员可以在外部被访问或修改
    • 模块增多,容易产生命名冲突
    • 无法管理模块与模块之间依赖关系
    • 维护过程中很难分辨每个成员所属的模块
  2. 命名空间方式

    约定每个模块只暴露一个全局对象,将每个模块包裹到一个全局对象

    window.moduleA = {
     method1() {
         console.log('a')
        }
    }
    

    只解决了命名冲突问题,其他问题依旧存在

  3. IIFE

    立即执行函数为模块提供私有空间,将每个模块放在立即执行函数形成的私有作用域,需暴露的成员,通过全局对象挂载

    (function() {
     const name = 'a'
        function method1 () {
         console.log('a')
        }
        window.moduleA = {
         method1
        }
    })()
    

    解决全局污染和命名冲突问题

  4. IIFE依赖参数

    使用IIFE参数作为依赖声明使用 使模块之间依赖关系更明显

    (function ($) { // 通过参数明显表明这个模块的依赖
      var name = 'module-a'
      function method1 () {
        console.log(name + '#method1')
        $('body').animate({ margin: '200px' })
      }
      window.moduleA = {
        method1: method1
      }
    })(jQuery)
    
模块加载问题

时间久、项目大时难维护

更为理想的页面引入一个JS文件入口,用到的模块通过代码控制、按需加载

模块化标准规范

差异:CommonJs以同步模式加载模块,启动时加载模块,而执行当中不需要再加载,浏览器端使用会导致效率低下;早期浏览器使用AMD(Asynchronous Module Definition)规范,推出Require.js实现AMD规范

AMD缺陷:

ES Module特性

ES Module模块需要使用http serve模式运行,直接运行html文件会导致跨域,browser-sync --files *./.js

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>ES Module - 模块的特性</title>
  </head>
  <body>
    <!-- 通过给 script 添加 type = module 的属性,就可以以 ES Module 的标准执行其中的 JS 代码了 -->
    <script type="module">
      console.log('this is es module') // this is a module
    </script>

    <!-- 1. ESM 自动采用严格模式,忽略 'use strict' -->
    <script type="module">
      console.log(this) // undefined 非严格模式下是Window对象
    </script>

    <!-- 2. 每个 ES Module 都是运行在单独的私有作用域中 -->
    <script type="module">
      var foo = 100
      console.log(foo)
    </script>
    <script type="module">
      console.log(foo) // foo is not defined
    </script>

    <!-- 3. ESM 是通过 CORS 的方式请求外部 JS 模块的,引入的文件必须支持CORS -->
    <script
      type="module"
      src="https://unpkg.com/jquery@3.4.1/dist/jquery.min.js"
    ></script>

    <!-- 4. ESM 的 script 标签会延迟执行脚本,等待网页渲染完成之后再去执行脚本,相当于defer属性 -->
    <script type="module" src="demo.js"></script>
    <p>需要显示的内容</p>
  </body>
</html>
ES Module导入和导出
上一篇 下一篇

猜你喜欢

热点阅读