前端模块化概述

心已赠人 2021-09-30 05:34 524阅读 0赞

一、为什么需要模块化?

   代码量骤增 => 分治管理的刚性需求

二、模块化方案需解决什么问题?

  1. 模块化要实现两个东西:模块加载与模块封装。面临的具体问题包括:
  2. 1、如何定义模块以确保模块的作用域独立,避免命名冲突?
  3. 2、如何管理模块间的依赖关系,避免重复加载与循环引用?
  4. 3、模块化的代码如何部署,以降低HTTP请求数?
  5. 4、如何实现按需加载?
  6. 5、如何在解决上述问题之后,保证性能且不影响debug

三、原始的解决方案有何局限?

   命名空间 + 立即执行函数 + script标签

   局限性:

   1、全局空间污染

   2、需手动管理依赖,不具备可扩展性

   3、无法实现按需加载

四、新的解决方案

1、CommonJS

  1. CommonJS 起源于一个服务端项目 SeverJS,该项目意在通过模块化的开发模式, 解决 JS 作用域的问题。后来发展成了一个致力于构建 JS 生态圈的组织。
  2. CommonJS 提供了一套**模块加载**的规范,其核心语法是通过 module.exports 暴露接口,通过 require() 加载资源。

925891-20170406134955582-2054500686.png

   CommonJS 规范采用同步加载,适用于服务端,但并不适用于浏览器环境(网络延迟、异步特性),因此在浏览器端出现了各类模块加载器,以解决模块加载的问题。

   各类模块加载器提出了各自的模块封装的规范。其中 Sea.js 提出/实现的封装规范,就是 CMD 规范;RequireJS 提出/实现的封装规范,就是 AMD 规范。

2、Sea.js

  模块封装:

   define (function (require, exports, module) {

    var a = require(‘./a’) // 模块加载

    a.doSomething();

    // ……

    var b = require(‘./b’) // 依赖可以就近书写

    b.doSomething();

    // 通过 exports 对外提供接口

    exports.doSomething = …

    // 或者通过 module.exports 提供整个接口

    module.exports = …

   })

   模块加载:

   var $ = require(‘jquery’);

3、RequireJS

  1. 模块封装:

   define ([‘./a’, ‘./b’], function(a, b) {

    a.doSomething();

    // 此处略去 100 行

    b.doSomething();

    return function () { } //返回模块的值,可以是函数,也可以是对象

  })

  模块加载:

  require ([‘./a’, ‘./b’], function (a, b) {

  1.   // do sth

  })

  1. 区别
  2. RequireJS:依赖前置,提前加载
  3. Sea.js:依赖就近,延迟加载

4、UMD

  1. 一种兼容 CommonJS AMD 的语法糖。事实上 RequireJS Sea.js 就是相互支持的。

925891-20170406135031285-340198586.png

图片来源:https://www.leanpanda.com/blog/2015/06/28/amd-requirejs-commonjs-browserify/


5、打包工具:Browserify&Webpack

  1. 在模块化的开发方式下,模块加载器(Module loader)解决了模块的加载与依赖的自动管理,但是并没有解决 HTTP 请求数的问题。如何将分散的文件合并成一个或几个文件以减少 HTTP 请求,这就是打包工具(Module bundler)的作用。
  2. 打包工具的核心能力是对 js 代码进行合并,扩展能力是对 js 代码进行优化、编译和压缩。webpack 的特色是扩展得比较狠,通过各类插件,可以打包任意类型的文件。
  3. 打包工具的真正价值在哪里呢?仅仅是合并文件从而减少 HTTP 请求数吗?当然不止,打包工具的真正价值是在工程开发中,完成从开发状态到发布状态的**自动化构建**。

925891-20170406135058394-1997204856.png

  减少 HTTP 请求和按需加载其实是相互矛盾的,都打包成一个文件了,自然不需要考虑模块加载的问题。但是把所有文件都打包成一个文件,又显得有些冗余。所以 webpack 也支持 code spliting,把文件打成多个包。

6、终结者:ES6 Module

  1. 原生模块标准得到浏览器全面支持之时,就是所有模块封装方案灭亡之日。但打包工具(自动化构建工具)仍会继续存在。

五、模块打包的技术实现

925891-20170406135159722-1839015767.png

图片来源:https://www.leanpanda.com/blog/2015/06/28/amd-requirejs-commonjs-browserify/

  以上是 browserify 的实现,webpack 的实现也差不多,这里详细说明一下。

  首先,webpack 会将每个 js 文件编译成一个函数:

925891-20170406135215769-82228639.jpg

   webpack 会将文件路径映射为一个数字 id,入口文件默认 id 为 0,在入口文件中遇到的第一个加载的模块,id 为 1……,总之按照加载的顺序依次赋予一个 id。

925891-20170406135224535-1197697045.jpg

   webpack 函数用于整个模块的加载,所有模块函数会按照 id 的顺序组成一个数组,传给 webpack 进行加载。

925891-20170406135235066-1936204262.jpg

  1. 最后运行的结果是:

925891-20170406135401675-591413935.jpg


转载于:https://www.cnblogs.com/kidney/p/6673189.html

发表评论

表情:
评论列表 (有 0 条评论,524人围观)

还没有评论,来说两句吧...

相关阅读

    相关 前端模块了解

    模块化是一种思想, 是将大工程拆成小的模块分治的思想. ES5模块化代码 ES5实现模块化操作在代码层面, 与 c 语言可以使用 include 包含头文件, Java

    相关 前端模块

    1、CommonJS 服务器端的Node.js 遵循CommonJS规范,该规范的核心思想是允许模块通过require方法来同步加载所要依赖的其他模块,然后通过exports

    相关 前端模块编程

    前端模块化 前端技术发展可谓是日新月异,web2.0的到来,Ajax技术的广泛引用,jQuery库的层出不穷,前端代码日益膨胀,javascript的发展领域越来越广泛,

    相关 前端模块概述

    一、为什么需要模块化?    代码量骤增 => 分治管理的刚性需求   二、模块化方案需解决什么问题?        模块化要实现两个东西:模块加载与模块封装。面临的具

    相关 前端模块发展简史

    前端发展日新月异,短短不过 10 年已经从原始走向现代,甚至引领潮流。网站逐渐变成了互联网应用程序,代码量飞速增长,为了支撑这种需求和变化,同时兼顾代码质量、降低开发成本,接入