Giter VIP home page Giter VIP logo

vite-study's Introduction

Vite 1.x 部分核心原理学习

本项目为学习 Vite 1.x 原理时手写的几个核心功能的简化版实现,旨在了解 Vite 是如何做到随引随加载,无需每次打包的无感开发体验。

使用 Vite 1.x 版本学习出于以下原因:

  • 有比较成熟和完善的资料参考
  • 与 2.x 版本的实现**本质一样

有些模块,如预优化、hmr 模块较为复杂,故没有手写实现。

1. 项目启动

# 安装 vite 本身所需依赖
npm i 
# yarn

# 安装 vite-mini 所需依赖
cd (当前项目路径)/vite-mini

npm i 
# 或者 yarn

# 运行 vite 自身启动项目,查看它的请求过程,
# 对比验证自己写的 vite-mini 功能
# 项目根目录
npm run dev 
# 或者 yarn dev


# 运行手写的核心功能调试
# 项目根目录
npm run mini 
# 或者 yarn mini
# 如果有安装 nodemon,可实时响应 vite-mini/ 下的文件更改
# nodemon

vite-mini会在4000端口开启一个服务供预览对比。

2. 实践过程

未特殊说明,vite 都指 vite 1.x 版本。

vite 的工作方式是通过浏览器原生支持 ESM 并且会发起网络请求获取包内容,所以 vite 会开启一个 koa 服务,拦截这些请求,做自己的处理后再返回给浏览器。

它的整个工作流程为:

  1. 进行依赖预打包(项目引用到的node_modules/中的第三方包会进行预打包,将cmdumd的格式都转换为esm)。
  2. 拦截请求,重写文件并返回内容
  3. 监控文件变更,然后通知浏览器更新(hmr)
2.1 过程简述
  • 依赖预打包:

    • 由于 vite 运行的基础就是基于 esm,如果依赖包不支持,那只有经过转换后才能实现。
    • 其次,由于一次esm的引入(import xxx from 'xx')就会发一次网络请求,为了防止网络请求瀑布问题,预打包会将一些小的 esm包进行合并优化。
    • 存放在node_modules/.vite目录,供拦截请求加载第三方模块时读取。
  • 拦截请求重写文件并返回内容:

    • 由于esm不支持裸模块的加载(类型:import { createApp } from 'vue'中的vue),所以需要重写成/@modules/vue这种类型,使得浏览器识别。
    • 单文件组件.vue浏览器是不识别的,所以需要重写内容。
    • 其他一些方面的问题或考虑
  • hmr

    • 热替换功能,和热重载不同。
    • 文件内容更新后马上通知浏览器更新对应内容。

vue-mini/主要是过程二中的一些重点步骤实现,关于为什么需要文件重写,以及如何重写等。

2.2 部分功能解析
// vite-mini/src/index.js

// 以中间件的形式注册各个插件,结合洋葱模型,需要注意调用顺序
  const resolvePlugins = [
    moduleRewritePlugin,  // 模块路径的重写,vue -> /@modules/vue
    moduleResolvePlugin,  // 模块的解析加载,主要是如 vue 的这种第三方裸模块路径改为了 /@modules/xxx,需要解析加载对应内容
    vueCompilerPlugin,  // 解析 .vue 的 sfc 组件
    serveStaticPlugin  // 静态服务插件
  ]
  
  resolvePlugins.forEach(plugin => plugin && plugin(context))

这里插件注册的顺序机制比较重要,虽然是从上到下依次注册,但是由于``koa`洋葱模型的特点,部分功能的执行顺序反而是从下到上的。

这是为了解决一些模块的嵌套引用,比如 a 引用 b, b 引用 c ,它们的路径都要被该正确改写。

2.3 学习与功能编写顺序

下图为 vite 请求的过程:

step-1

由此可知,编写插件过程应该为:

  1. serveStaticPlugin:让浏览器能成功访问到main.js文件
  2. moduleRewritePlugin:红框中的内容和实际main.js对比,发现裸模块vue的路径加了/@modules,所以要对文件内容进行重写
  3. moduleResolvePlugin:重写路径的模块需要被正确找到并返回,所以需要模块解析插件

step-2

step-3 后面的请求发现,App.vue的内容也进行了重写,实际内容是通过App.vue?type=template获取的,并且内容也转换成了js内容。

所以我们在前面三个插件的基础上还需要:

  1. vueCompilerPlugin:来解析.vue的单文件组件(sfc)

每个插件的作用顺序,也不难确定:

  • 首先是serveStaticPlugin让文件顺利访问
  • 紧接着本应该是moduleRewritePlugin重写路径,然后给moduleResolvePlugin插件解析获取的,但由于解析出的文件内容可能还存在引用,又需要进行路径重写。所以索性就先尝试解析文件,如果碰到a模块路径需要改写,则改写路径,下一次请求再获取a模块内容
  • vueCompilerPlugin.vue文件进行解析的时候,它可能会引入第三方模块要进行路径改写,或者说引入的文件有改写好的模块需要解析,所以该插件的作用应该在moduleResolvePluginmoduleRewritePlugin之前

最终,插件的作用顺序为:

serveStaticPlugin -> vueCompilerPlugin -> moduleResolvePlugin -> moduleRewritePlugin

这与插件的注册顺序看上去并不一致,是因为插件在编写时是在await next()之后执行代码的,也就是在洋葱模型的从内层穿透到外层的过程中。

3. 学习资料

1.Vite Design

2.Vite 1.x 源码

3.Vite 官网

4.b站视频

注:Vite Design 有介绍 vite 2.0 的一些变化点,vite-mini/的内容有根据第4点的 b站视频 调整,所以如果代码看不懂,也可以查看视频(有效总时长约 1:40:00)

vite-study's People

Contributors

gk-shi avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.