侧边栏壁纸
  • 累计撰写 12 篇文章
  • 累计创建 6 个标签
  • 累计收到 1 条评论

目 录CONTENT

文章目录
Vue

从模块化到vite工程化

Administrator
2025-01-10 / 0 评论 / 0 点赞 / 16 阅读 / 11132 字

什么是模块化

将一个复杂的程序依照一定的规则封装成几个文件,并进行组合在一起。每个模块的内部数据是私有的,只是向外暴露一些接口(方法)与外部其它模块通信。

模块化优点

1. 避免名称空间的冲突
2. 更好的分离,实现按需加载
3. 提高代码的复用性,维护性

模块化历史进程

image-20230509110546562

  • CJS

    CJS是 CommonJs 缩写, nodejs 指定的标准,服务端的模块化规范。

    优点: 所有模块同步加载。

    缺点: 服务器端运行可以,浏览器端就会造成js解析阻塞,页面加载速度缓慢。

    let a = require('包名称')
    module.exports = {a}
    // exports.a = a
  • AMD

    Asynchronous Module Definition / 异步模块定义; 经典实现框架: require.js

    优点: 支持模块异步加载,加载速度快。

    缺点:

    1. 会有引入成本,没有考虑按需加载; AMD 是预加载,加载某个模块前,这个模块的依赖模块需要先加载完成。

    2. 因为是异步加载,加载顺序不一定,可能遇到某个依赖中用到的另一个依赖还没加载到

    // 通过define定义模块
    define('amdModule', ['deps1', 'deps2'], (deps1, deps2) => {
        // 业务逻辑
        let count = 0
        const increase = function(){++count}
        deps1()
        deps2()
        return { increase }
     
    })
    // 引用模块
    reuire(['amdModule'], amdModule => {
        amdModule.increase()
    })

  • CMD

    Common Module Definition / 通用模块定义; 主要应用框架 sea.js

    // program.js
    define(function(require, exports, module) {
      var inc = require('increment').increment;
      var a = 1;
      inc(a); // 2
     
      module.id == "program";
    });

    优点: 按需执行,依赖就近,用到的依赖都是确定加载并执行完成的

    缺点:

    执行等待时间会叠加。因为每个文件执行时是同步执行 , 因此时间是所有文件解析执行时间之和,尤其在文件较多较大时,这 种缺点尤为明显。

    AMD 和 CMD 区别:

    AMD 通过 require.js实现

    CMD 通过 sea.js实现

    1. 对于依赖的模块,AMD 是提前执行,CMD 是延迟执行。不过 RequireJS 从 2.0 开始,也改成可以延迟执行(根据写法不同,处理方式不同)。CMD 推崇 as lazy as possible.

    1. CMD 推崇依赖就近,AMD 推崇依赖前置。看代码:

      // CMD
      define(function(require, exports, module) {
          var a = require('./a')
          a.doSomething()
          // 此处略去 100 行
          var b = require('./b') // 依赖可以就近书写
          b.doSomething()
          // ... 
      })
      ​
      // AMD 默认推荐的是
      define(['./a', './b'], function(a, b) { // 依赖必须一开始就写好
          a.doSomething()
          // 此处略去 100 行
          b.doSomething()
          ...
      })

  • ESM

    ES Modules ; esma 模块化标准

    优点: 通过一种最统一的形态整合了所有JS的模块化

    import {ref} from 'vue'
    export {}

为什么选 vite

现实问题

在游览器支持 ESM 前, javascript 并没有提供原生机制让开发者以模块化的方式进行开发。

所以市场上出现了 webapck , rollup, patcel 等打包工具, 处理我们的项目源码模块串联成可以在游览器中运行的文件。

然而,当构建的项目越来越大时,这些 JavaScript 开发的工具也出现了性能瓶颈;通常需要很长时间才能启动开发服务器,即使使用 HMR 热加载,

文件修改后的效果也需要等待几秒才能反映出来,这种迟钝的反馈对开发效率大打折扣。

  • vite的宗旨就是处理以上问题。利用逐渐发展的es新特性解决问题:游览器开始原生支持 ES 模块,且越来越多 js工具使用编译型语言编写。

缓慢的服务器启动

webpack 之类冷启动打包工具,基于打包器的方式启动必须优先抓取并构建你的整个应用,然后才能提供服务。简而言之,需要webpack 内置服务器将应用整体代码打包编译后,形成一个或多个 bundles,或者说是 静态资源 ,才能提供服务。

即使采用了代码拆分,也需要一次生成所有路由下的编译后文件(这也是为什么代码拆分对开发模式没有帮助)。这也导致服务启动时间随着项目复杂度而指数增长。

  • vite 是基于原生的 ES module,浏览器厂商的不懈努力,现代游览器已经支持 import/export 模块化形式; vite 启动服务器时,不需要整个应用提交编译文件,游览器已经原生支持模块化了,游览器请求对应的路由URL时,提供对应的编译后文件,实现了真正的路由懒加载,这个比起 webpack 就要节省不少时间;

  • vite 将应用中的模块分为 依赖源码 两类,在这两块做了些事件,改进了服务器的启动时间

    • 依赖 大多为在开发时不会变动的纯javascript。 一些较大的依赖处理代价也高,这些依赖代码可能存在多种模块化格式(如 ESM, CommonJs AMD, UMD 等等。这个时候 vite 会进行 esbuild 预构建依赖 ,将其转为ESM 模块,以支持 vite 。对于

      有许多内部模块的 ESM 依赖转换为单个模块,减少HTTP 请求,以提高后续页面加载性能 。

    • 源码 通常包含一些并非直接是 javascript 的文件(例如: TS, JSX, CSS, 或者 Vue/Svelte组件),也需要使用 esbuild 编译,不同与 webpack 整体编译, vite 是在游览器请求路由 URL 时,才对改文件编译,然后提供给游览器。因为 esbulid编译够快,这种每次页面加载后即刻编译的其实是不会影响页面渲染的。

vite 是如何实现的

参考资料


###

vite 简介

  • 使用原生 ESM 文件,无需打包 (启动快!

  • 无论程序大小如何,都始终极快的热加载 HMR (轻量快速的热加载!

  • 开箱即用,生态丰富

构建工具

  • 当我们习惯了在node 中编写代码的方式后,在回到前端编写 html, css, js 这些东西会感觉到各种的不便。比如:不能放心的使用模块化规范 (游览器兼容问题),即使可以使用模块化规范也会面临模块过多时的加载问题。

  • 我们就迫切的希望有一款工具可以对代码进行打包,将多个模块打包成一个文件,这样一来即解决了兼容性问题(esm 代码转为旧代码),又解决了模块过多的问题。

  • 构建工具就起到这样一个作用,通过构建工具可以使用 ESM 规范编写的代码转换为旧的 JS语法,这样可以使得所有的游览器都可以支持代码。

    - 构建工具优点类似代码的编译,执行的代码是编译后的代码


0

评论区