揭秘 Vite 的原理

前言

Vite现在正在疯狂的更新,目前在 Beta中,可能很快就会发布 1.0。

Vite 是什么

  • 快速冷启动服务器
  • 即时热模块更换(HMR)
  • 真正的按需编译

天生的懒加载呀!

Javascript 模块

首先,你需要把 type="module"放到 <script>标签中, 来声明这个脚本是一个模块:

<script type="module" src="main.js"></script>

script.typemodule时,通过 srcimport导入的文件会发送 http请求。

拦截请求

Vite会拦截这些请求,并对请求的文件进行特殊的处理。

import Vue from 'vue'

当通过 import试图导入 node_modules内的文件时,Vite会对路径进行替换,因为在浏览器中只有 相对路径绝对路径

import Vue from '/@modules/vue'

代码实现

// server.js
  const Koa = require('koa');
  const fs = require('fs');
  const path = require('path');

  const app = new Koa();

  app.use(async (ctx) => {
    const {
      request: { url, query }
    } = ctx;

    if (url == '/') {
      // 返回静态资源
      ctx.type = 'text/html';
      ctx.body = fs.readFileSync('./index.html', 'utf-8');
    } 

    if (url.endsWith('.js')) {
      // 处理 js 文件
      const p = path.resolve(__dirname, url.slice(1));
      const res = fs.readFileSync(p, 'utf-8');
      ctx.type = 'application/javascript';
      // 返回替换路径后的文件
      ctx.body = rewriteImports(res);
    }
  });

  function rewriteImports(content) {
    return content.replace(/from ['|"]([^'"]+)['|"]/g, function ($0, $1) {
      // 要访问 node_modules 里的文件
      if ($1[0] !== '.' && $1[1] !== '/') {
        return `from '/@modules/${$1}'`;
      } else {
        return $0;
      }
    });
  }

  app.listen(3000, function () {
    console.log('success listen 3000');
  });

解析 /@modules

接下来就是要把 /@modules开头的路径解析为真正的文件地址,并且返回给浏览器。之前是 webpack帮我们做了这件事。

通过 import导入的文件 webpack会去 package.json文件内找 model属性。

{
  "license": "MIT",
    "main": "index.js",
    "module": "dist/vue.runtime.esm-bundler.js",
    "name": "vue",
    "repository": {
      "type": "git",
      "url": "git+https://github.com/vuejs/vue-next.git"
    },
    "types": "dist/vue.d.ts",
    "unpkg": "dist/vue.global.js",
    "version": "3.0.0-beta.15"
  }

我们只需要把这个 dist/vue.runtime.esm-bundler.js地址的文件返回就好。

代码实现

if (url.startsWith('/@modules/')) {
    // 找到 node_modules 内的文件夹
    const prefix = path.resolve(
      __dirname,
      'node_modules',
      url.replace('/@modules/', '')
    );
    // 获取 package.json 内的 module 属性
    const module = require(prefix + '/package.json').module;
    const p = path.resolve(prefix, module);
    // 读取文件
    const res = fs.readFileSync(p, 'utf-8');
    ctx.type = 'application/javascript';
    // 读取的文件内还通过 import 导入了其他的依赖,继续把路径替换为 /@modules/
    ctx.body = rewriteImports(res);
 }
解析单文件组件

大家都知道 vue文件包含了三个部分,分别是 templatescriptstyle

Vite对这几个部分分别进行了处理。

接下来我们就要实现对这几个部分的处理。

处理 script

@vue/compiler-sfc是用来解析单文件组件的,就像是 vue-loader做的事情。

它解析的结果就像是下面这样。

原文链接:juejin.im

上一篇:create-react-app 架构的项目打包生产环境的代码如何关闭 sourcemap?
下一篇:JS-执行环境(Execution Context)和作用域(Scope)

相关推荐

  • 🚩四年前端带你理解路由懒加载的原理

    前言 说起路由懒加载,大家很快就知道怎么实现它,但是问到路由懒加载的原理,怕有一部分小伙伴是一头雾水了吧。下面带大家一起去理解路由懒加载的原理。 路由懒加载也可以叫做路由组件懒加载,最常用的是通过im...

    1 个月前
  • 🔥 Promise|async|Generator 实现&amp;原理大解析 | 9k字

    笔者刚接触async/await时,就被其暂停执行的特性吸引了,心想在没有原生API支持的情况下,await居然能挂起当前方法,实现暂停执行,我感到十分好奇。好奇心驱使我一层一层剥开有关JS异步编程的...

    4 个月前
  • 面试专用:Http和Https之间的区别,及原理分析

    关于HTTP和HTTPS文章原理及分析,我相信已经有很多了,深入的原理我就不一一写出来了。 写这篇文章的目的主要是为了解决面试过程关于HTTP和HTTPS常见问题及怎样用自己话更好的描述出来了。

    3 个月前
  • 零基础学习前端开发不可不知的CSS原理

    从事Web前端开发的人都与CSS打交道很多,有的人也许不知道CSS是怎么去工作的,写出来的CSS浏览器是怎么样去解析的呢?学习前端开发必不可少一定要先了解CSS的原理的。

    1 年前
  • 金三银四,前端同学快来补补React原理吧

    这是我几个月前写的文章,在前端面试中原理相关的问题是问的最多的,所以重新推荐下这几篇文章 深入学习一个框架最直接的方式,就是弄明白框架的原理。React无疑是一个非常值得学习其原理的框架,它设计简单...

    1 年前
  • 重学前端学习笔记(二十八)--通过四则运算的解释器快速理解编译原理

    笔记说明 重学前端是程劭非(winter)【前手机淘宝前端负责人】在极客时间开的一个专栏,每天10分钟,重构你的前端知识体系(https://time.geekbang.org/column/i...

    1 年前
  • 通过实现一个简易打包工具,分析打包的核心原理

    概述 眼下wepack似乎已经成了前端开发中不可缺少的工具之一,而他的一切皆模块的思想随着webpack版本不断的迭代(webpack 4)使其打包速度更快,效率更高的为我们的前端工程化服务 图片...

    1 年前
  • 通熟易懂的Vue异步更新策略及 nextTick 原理

    最近在学习一些底层方面的知识。所以想做个系列尝试去聊聊这些比较复杂又很重要的知识点。学习就好比是座大山,只有自己去登山,才能看到不一样的风景,体会更加深刻。今天我们就来聊聊Vue中比较重要的异步更新策...

    2 个月前
  • 通熟易懂的Vue响应式原理以及依赖收集

    最近在看一些底层方面的知识。所以想做个系列尝试去聊聊这些比较复杂又很重要的知识点。学习就好比是座大山,只有自己去登山,才能看到不一样的风景,体会更加深刻。今天我们就来聊聊Vue中比较重要的响应式原理以...

    13 天前
  • 这一次,彻底理解https原理

    我的github/blog,若star,无比感谢 建议电脑观看,图有点挤,手机屏幕太小可能看不清楚。 放轻松 作为一个前端er,你总会在学习或工作中,听到这样的声音:什么是https?你对http...

    6 个月前

官方社区

扫码加入 JavaScript 社区