指尖上的记忆指尖上的记忆
首页
  • 基础
  • Laravel框架
  • Symfony框架
  • 基础
  • Gin框架
  • 基础
  • Spring框架
  • 命令
  • Nginx
  • Ai
  • Deploy
  • Docker
  • K8s
  • Micro
  • RabbitMQ
  • Mysql
  • PostgreSsql
  • Redis
  • MongoDb
  • Html
  • Js
  • 前端
  • 后端
  • Git
  • 知识扫盲
  • Golang
🌟 gitHub
首页
  • 基础
  • Laravel框架
  • Symfony框架
  • 基础
  • Gin框架
  • 基础
  • Spring框架
  • 命令
  • Nginx
  • Ai
  • Deploy
  • Docker
  • K8s
  • Micro
  • RabbitMQ
  • Mysql
  • PostgreSsql
  • Redis
  • MongoDb
  • Html
  • Js
  • 前端
  • 后端
  • Git
  • 知识扫盲
  • Golang
🌟 gitHub
vue3使用vite打包的原理

缘起: Vue3 + Vite 为什么 npm run dev 一跑就能看到访问连接:

1. Vite 的核心原理

Vite 的名字来自法语 "vite" = 快速。它的核心理念就是利用浏览器原生 ES Module 能力,避免传统构建工具(Webpack/Rollup)那种“先打包再启动”的流程。

  • 传统打包工具(Webpack):

    • 启动时会把整个项目打包成一个 bundle 文件(或多个 chunk)。
    • 大项目启动时要等很久才能看到页面。
  • Vite:

    • 启动时不打包,只是起一个开发服务器。
    • 浏览器请求哪个文件,就按需即时编译(on-demand transformation),用 ES Module 直接返回。
    • 这样启动速度非常快。
2. 为什么 npm run dev 就能看到链接

通常在 package.json 里会有这样一行:

"scripts": {
  "dev": "vite"
}

当你执行 npm run dev 时,本质上是调用了 vite CLI(开发服务器)。它的执行流程是这样的:

  1. 读取配置

    • Vite 会读取 vite.config.ts 或 vite.config.js(如果有)。
    • 同时识别项目入口(默认是 index.html)。
  2. 启动开发服务器

    • Vite 内置了一个基于 connect 的 dev server。
    • 监听一个端口(默认 5173)。
    • 输出类似 http://localhost:5173/ 的访问链接。
  3. 拦截浏览器请求

    • 浏览器访问 http://localhost:5173/ 时,Vite 会返回 index.html。
    • 当 index.html 里引用了 src/main.ts,Vite 就会动态编译这个文件,并以 ESM 模块的形式返回给浏览器。
    • 如果 main.ts 又 import 了 Vue 组件,Vite 会继续即时编译这些 .vue 文件(通过 @vitejs/plugin-vue 插件)。
  4. 热更新 (HMR)

    • Vite 内置 WebSocket 连接。
    • 当文件修改时,Vite 只会重新编译变动的文件,并通过 HMR 更新浏览器里的模块,而不是整个页面刷新。
    • 这就是为什么改一个组件页面能秒级看到变化。
3. 为什么能直接访问 Vue3 代码

因为 Vite 把 Vue 文件和 TypeScript 等等转译成浏览器可运行的 ESM:

  • .vue 文件 → 转成 JS 模块(render function + script)
  • .ts 文件 → 用 esbuild 转成 JS
  • 依赖包(比如 vue)→ 预构建成单个 ESM(用 esbuild 优化)

所以浏览器收到的都是标准的 JS 模块,能直接运行。

✅ 总结:

  • npm run dev 启动的是 Vite 的开发服务器。
  • Vite 的原理是 利用浏览器原生 ES Modules,做到即开即用、按需编译。
  • 浏览器访问链接后,Vite 会按需编译并返回文件,同时通过 HMR 实现热更新。

什么是ES Moudle?

关键点:ESM 模块。

npm run dev 之所以能让 Vue3 + Vite 立即跑起来,核心就在 ESM(ES Modules,原生模块化标准)。我给你拆一下:

1. 什么是 ESM 模块

ESM 是 浏览器和 Node.js 官方支持的模块化规范,用 import / export 来组织代码。 例如:

// math.js
export function add(a, b) {
  return a + b
}

// main.js
import { add } from './math.js'
console.log(add(2, 3))

📌 关键点:

  • 浏览器可以 原生识别 import(不用打包工具)
  • 每个模块文件就是一个 独立作用域
  • 按需加载,避免一次性打包成大文件
2. Vite 为什么要用 ESM

Vite 在开发模式下,完全依赖浏览器的 ESM 特性:

  1. 你访问 http://localhost:5173/ 时,index.html 里会写:

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

    浏览器看到 type="module",就会去请求 /src/main.ts。

  2. Vite 拦截这个请求:

    • 如果是 .ts → 用 esbuild 转译成 JS
    • 如果是 .vue → 用插件转成 JS 模块(render + script)
    • 如果是依赖(如 vue)→ 提前 预构建 成 ESM(避免 node_modules 太多小文件导致请求过多)
  3. 浏览器再按需加载这些 JS 模块,形成一个 模块依赖树。

    • 改一个文件,Vite 只需要重新编译这个文件,并通过 HMR 替换模块,而不是整个页面刷新。
3. 为什么 ESM = Vite 极速开发体验
  • 不用一次性打包 → 启动极快
  • 模块天然分割 → 修改一个模块时,只更新这个模块(HMR)
  • 浏览器直接支持 → 少了一层构建的中间步骤

✅ 总结: Vite 的核心就是基于浏览器原生 ESM 模块,把每个 .vue、.ts、依赖都当作独立的 ESM 来处理。 这也是它比 Webpack/Gulp 那些工具快得多的根本原因。


ES Modules 分类

在 Vite 的 开发模式 下,最后所有代码都会变成 ES Modules (ESM),再交给浏览器去执行。 不过这里要分三类情况来看:

1. 你的源码(.vue、.ts、.js)
  • .vue 文件 → 通过 @vitejs/plugin-vue 编译成 JS 模块:

    // App.vue → 编译后
    export default {
      render() { ... },
      setup() { ... }
    }
    
  • .ts 文件 → 用 esbuild 转成 JS,再包装成 ESM:

    // main.ts
    import { createApp } from 'vue'
    

    → 转译后仍然是 import 语法,浏览器直接识别。

👉 最终:每个源码文件就是一个 独立的 ESM 模块。

2. 依赖包(node_modules 里的第三方库)

这里是 Vite 的一个 优化点:

  • node_modules 里的库(例如 vue, lodash-es)有的不是 ESM 格式,而是 CommonJS 或 UMD。
  • Vite 会在启动时做依赖预构建(dependency pre-bundling),把这些库用 esbuild 转换成 ESM 格式。

比如 vue 最终会被处理成一个 ESM 文件放在:

node_modules/.vite/deps/vue.js

👉 所以即便原始库不是 ESM,Vite 也会先帮你“转译成 ESM”,保证浏览器能用。

3. 最终效果
  • 开发模式下: 所有请求的文件(Vue/TS/依赖包)最后都是 ES Modules,浏览器原生加载。

  • 生产模式下(vite build): Vite 会调用 Rollup,把所有模块打包、拆分优化(代码分块、Tree Shaking、压缩)。 最终线上跑的不是一堆 ESM 文件,而是构建后的 bundle,这样减少网络请求数、提升性能。

📌 总结一句话:

  • 开发模式:所有 .vue、.ts、依赖包 → 全部转成 ESM,浏览器直接按需加载。
  • 生产模式:Vite 会再把这些 ESM 模块交给 Rollup 打包优化,生成少量高效的产物。

type="module"的作用

好问题 👍,<script type="module"> 正是 Vite 能在浏览器里直接跑的关键。

1. 背景

在最早的浏览器里,JavaScript 只有 全局脚本:

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

所有变量、函数都挂在 window 上,容易冲突,也没办法分模块管理。

后来有了各种 模块化方案:

  • CommonJS(Node.js 用的 require())
  • AMD/UMD(浏览器异步模块加载) 但这些都是“约定俗成”,浏览器并不原生支持。

直到 ESM(ECMAScript Modules) 标准推出,浏览器原生支持 import/export,才有了今天的 <script type="module">。

2. type="module" 的作用

当你写:

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

它和普通 <script> 有这些区别:

✅ 支持 ESM 语法

可以在浏览器里直接写:

import { createApp } from 'vue'
import App from './App.vue'

createApp(App).mount('#app')

浏览器会自动去请求并执行这些模块。

✅ 默认是 延迟加载 (defer)

等 DOM 解析完再执行,避免阻塞页面加载。 (普通 <script> 会阻塞解析)

✅ 每个模块有自己的作用域

不会像普通 <script> 那样污染全局变量。 模块之间通过 import/export 明确依赖关系。

✅ 自动开启严格模式 (use strict)

提升代码安全性,比如不能随便用未声明的变量。

✅ 可以加载远程模块

甚至可以直接写 CDN 地址:

<script type="module">
  import _ from "https://cdn.skypack.dev/lodash-es"
  console.log(_.join(["Hello", "Vite"], " "))
</script>

(这也是 Vite 为什么可以直接利用浏览器的能力。)

3. 在 Vite 里的意义

当 Vite 返回 index.html 时,它会自动插入:

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

👉 浏览器一看到 type="module" 就会触发 原生 ESM 加载流程:

  • 请求 /src/main.ts
  • 里面 import App from './App.vue'
  • 浏览器继续请求 /src/App.vue(Vite 会在后台把它编译成 ESM)

最终整个 Vue 项目就跑起来了。

✅ 一句话总结: type="module" 的作用是告诉浏览器:

这个脚本是一个 ESM 模块,请按模块化规则加载(支持 import/export、作用域隔离、延迟执行)。


关于connect

https://github.com/senchalabs/connect

connect是一个 Node.js 里的 HTTP 中间件框架。


1. 什么是 connect
  • connect 是一个非常轻量的 Node.js 库,用来快速创建 HTTP 服务器。
  • 它本质上是基于 Node.js 的 http 模块,在其上增加了 中间件机制。
  • Express(很流行的 Node 框架)就是在 connect 的基础上扩展出来的。

简单示例:

import connect from 'connect'
import http from 'http'

const app = connect()

// 注册中间件
app.use((req, res, next) => {
  console.log('Request URL:', req.url)
  next()
})

app.use((req, res) => {
  res.end('Hello from Connect server')
})

// 启动 HTTP 服务
http.createServer(app).listen(3000, () => {
  console.log('Server running at http://localhost:3000')
})

运行后,你就有了一个 http://localhost:3000 的服务。

2. Vite 为什么用 connect

当你执行 npm run dev 启动 Vite 开发服务器时:

  • Vite 底层会创建一个 connect 应用

  • 然后注册各种中间件,例如:

    • 处理静态文件请求(返回 index.html、图片、CSS 等)
    • 处理 ESM 请求(拦截 .vue、.ts 转译成 JS)
    • HMR WebSocket 通信
  • 最终由 Node.js 内置的 http 模块把这个服务跑起来

所以你能在浏览器访问 http://localhost:5173,但真正的服务是 Node.js + connect 起的。

3. 总结
  • connect 是 Node.js 里的 HTTP 框架,不是浏览器的。
  • 它给 Vite 提供了一个可扩展的 中间件体系。
  • 浏览器只是作为客户端,请求 Vite 用 connect 起的本地服务。这个是重点,只负责启动一个本地服务。