模块化开发

74 阅读5分钟

模块化开发

(1)为何需要模块化开发?

  • 把一类方法放在单独的 js 文件中

    • 为了方便使用的时候,只引入这一类方法的文件
    • a.js 全都是封装 操作 DOM 的方法
    • b.js 全都是封装 格式化 时间对象 的方法
    • c.js 全都是封装 和数字相关的方法
    • 管一个封装好的 js 文件叫做一个模块

(2)什么是模块化开发?

  • 多个 js 文件之间的相互配合来实现效果
  • 一个 js 文件里只封装一类内容

(3)问题

  • 由多个 js 文件出现的问题

    • js 文件引入顺序
    • js 文件之间的相互依赖不清晰
    • s 文件内部的变量会污染全局

最早时没有模块化

  • 按照顺序引入文件,把整合的文件放在最后面

(1)问题

  • ①没有办法维护

    • 一般把整合的 js 起名叫做 main.js,并且不知道依赖了哪一个文件
  • ②全局变量污染

    • 每定义一个变量,就要去查看之前是否使用过
  • ③依赖关系不清

    • 现在只知道 c.js 里用到了 a.jsb.js 文件里面的内容,但是 b.js 里有没有依赖到 a.js 里的内容我们并不知道

IIFE 伪模块化标准- Immediately Invoked Function Expression

  • 自执行函数 (function () {} )()

(1)解决问题

  • ①依赖不清

    • 在自执行函数的参数位置,能看到依赖了哪些模块
  • ②变量全局污染

    • 后面的代码该用什么变量用什么

(2)问题

  • ①文件顺序不能变动
  • ②只能知道依赖的有几个模块,但是模块在哪一个文件中却不知道

CommonJS 模块化标准

  • 2009年, nodejs 出现
  • 使用 js 去做服务端语言
  • 伴生的是 CommonJS 模块化标准
  • 缺点:只能在后端 JS 里面用

AMD 模块化标准 - Async Module Definition

  • 2011年出现的,社区里发起的

  • 因为非官方,没有关键字,大家书写了一套 require.js 的第三方文件来实现 模块化标准

  • 把每一个 js 文件独立出来

    • 使用了导入导出的语法来实现模块化
    • js 文件里引入另一个 js 文件
  • 定义模块

    • 调用 define 的方法

      • 独立模块定义:每一个模块文件开始执行 define(),不依赖其他文件,就是一个单纯的模块,向外暴露的内容,直接 return 就好
      • 依赖其他模块的模块:我也是一个模块文件,但是我依赖的其他模块的内容使用 define() ,定义语法:define([依赖文件1,依赖文件2,...],function(模块A,模块B,...){ })
      • 导入 其他模块:我是一个模块整合文件,直接使用 a.js 文件里的方法,使用这个方法 require(),语法: require([依赖文件1,依赖问卷2,...],function(模块1,模块2){ })

(1)解决问题

  • ①依赖很清晰

    • 因为只有一个文件,那么所有的东西都在一个文件里出现
  • ②变量全局污染

    • 没有全局污染,都在私有作用域中

(2)问题

  • 依赖前置

    • 不管多少行使用的东西,都会在打开页面时加载进来
    • 缺点:首屏加载时间长
    • 优点:后期操作流畅

CMD 模块化标准 - Common Module Definition 通用模块定义

  • 2011年左右,社区里面出现的一个标准

  • 淘宝“玉伯”,开发了一个叫 CMD 的模块化标准

  • 依赖于一个叫 sea.js 的文件来实现的模块化标准

  • 使用:文件引入一个叫 sea.js

    • 独立模块定义:

      • define(function (require, exports, module) { })
      • require() 用来导入其他文件
      • module.exports 是为了本文件导出内容的
      • exportsmodule.exports 的别名,var exports = module.exports
    • 依赖其他模块的模块

      • 需要依赖其他文件模块

      • define( function (require, exports, module) {

        在需要使用的位置使用 require() 方法来导入

        var modA = require('地址')

        })

    • 资源整合

      • 使用 seajs.use()
      • 语法:seajs.use(['你要依赖的模块'], function (模块A) { })

(1)解决问题

  • 依赖前置

    • 按需加载,在你需要时,再加载,也留下了依赖前置的接口

(2)问题

  • 即时依赖

    • 首屏加载快

ES6 Module

  • 2015 年发布, ES6 语法里自带了一个模块化标准

  • 2016 年开始, Vue 出现了,人家出现了一个脚手架(开发的大框架给你搭好)

    • 搭建这个架子的时候,内置了 ES6 模块化标准
  • 2018 年, 各大浏览器厂商开始原生支持 ES6 模块化标准

  • 2018 年中, Chrome 率先原生支持 ES6 模块化

  • 语法:变成了 JS 的语法、关键字,不需要任何第三方文件的引入

  • 特点:页面必须在服务器上打开

    • live server 插件
    • 如果想使用模块化语法,script 标签要加一个属性 type="module"
  • 使用:

    • 每一个文件都可以作为独立模块,页面都可以作为整合文件

    • 导出语法

      • 语法1:export default 导出的内容
      • 语法2:export var num = 200
    • 导入语法

      • 接收 export default 导出

        • import 变量 from '哪一个 JS 文件'
      • 接收 export 导出的内容

        • import { 接收变量 } from '哪一个 JS 文件'
      • import 文件名

        • 此语法导入不接受数据
  • 2020年

    • ES2020 发布新的标准
    • 多了一个 按需加载的模块化
    • 语法:import(你要加载的文件).then(function (res) { })

(1)解决问题

  • ①变成关键字,不需要依赖第三方文件
  • ②每一个文件都可以变成模块文件,也可以是整合文件

(2)问题

  • ①浏览器支持不好

    • 必须在服务器上打开
    • 一旦项目上线,肯定是服务器打开
  • ②依赖前置