1.初体验-vite的bundless原理

94 阅读2分钟

1.bundle和 bundless [vite-my]

image.png

bundle打包: webpack 基于模块化规范,依赖分析完毕后构建依赖图,再转换打包成一个或多个文件。

2. vite如何做到bundless?

前置条件:模块化规范有 CommonJS , AMD, UMD,CMD ,ESM

正是有了基于现代浏览器的ESM 模块化支持,才有了bundless方案; 不用构建依赖图,实现按需加载依赖。

浏览器三大件 浏览器只认识html,js,css, 而jsx,ts,tsx,vue等文件浏览器不认识,如何处理 交由开发服务器处理:

产物构建过程:不依赖打包工具,而是依赖于编译工具 在webpack中编译最常使用工具为babel。 在vite中

1.开发环境:使用 esbuild[基于go语音] 处理 jsx,ts,tsx,vue

2.生成环境: 使用rollup [基于rust] 作为编译打包工具

Vite 目前的插件 API 与使用 esbuild 作为打包器并不兼容。尽管 esbuild 速度更快,但生产环境下 Vite 采用了 Rollup 灵活的插件 API 和基础建设.未来会接入Rolldown

3.实践部分:compiler server 实现
3.1.可以支持在home页以 type='module',让浏览器接管 模块化的加载【以http请求的方式】

image.png

image.png 依赖引用关系 index.html ->index.js->utils.js->math.ts; 可以看到 浏览器是根据import的情况依次发送请求的,也就不用像以前必须先构建依赖图打包完成后再启动务。浏览已经接管了模块依赖加载的部分工作。

3.2.语法转换,esm 是发送请求动态加载模块,因此可以提供本地sever拦截请求,根据不同文件类型使用不同的转换过程【这个过程类似于vite插件】这个是一个非常简单的vite实现,但最本质的原理已然显露

const express = require('express');
const app = express();
const port = 5000;
const esbuild=require('esbuild');
const fs=require('fs');
//可以定义存放插件容器
const plginContainner =[]
//绑定端口
app.listen(port, () => console.log(`Example app listening on port ${port}!`))
// 定义一个中间件函数,用于拦截所有请求
const interceptAllRequests = (req, res, next) => {
    console.log(` intercepted request for ${req.url}`);
   
    // 可以在这里对请求进行一些预处理,比如验证、日志记录等
    const path=req.path;
    if(path=="/"){
        res.type="text/html";
        res.sendFile(__dirname+"/src/index.html");
    }
    //依次调用插件方法todo
     // plginContainner.forEach(plugin=>{
       // plugin?.transformer()
      //})
    if(path.endsWith(".js")){
        res.type="text/javascript";
        res.sendFile(__dirname+"/src"+req.path);
    }
    if(path.endsWith(".ts")){
        const fileCode=fs.readFileSync(__dirname+"/src"+req.path,'utf-8')
        // 使用esbuild进行编译转换
        const result=esbuild.transformSync(fileCode,{loader:'ts',target:'es6',format:'esm'})
        res.setHeader('Content-Type', 'application/javascript');
        res.end(result.code, 'utf-8');
    }  
    //....其他如jsx /vue 使用不通的转换过程每个转换过程类似一个插件,如vite-plugin-vue 
    //...构建过程还需加入 tree shaking,和代码分割等优化代码体积和数量
    // next();发送响应即调用了一次,不要重复调用
};

app.use(interceptAllRequests);