Vite: 前端环境的基础搭建

Vite初始化前端项目

  • 初始化 $ pnpm create vite

    conff 复制代码
    Library/pnpm/store/v3/tmp/dlx-42133      | Progress: resolved 1, reused 0, downlLibrary/pnpm/store/v3/tmp/dlx-42133      |   +1 +
    Library/pnpm/store/v3/tmp/dlx-42133      | Progress: resolved 1, reused 0, downlLibrary/pnpm/store/v3/tmp/dlx-42133      | Progress: resolved 1, reused 0, downlLibrary/pnpm/store/v3/tmp/dlx-42133      | Progress: resolved 1, reused 0, downloaded 1, added 1, done
    ? Project name: › vite-project
    
    ? Select a framework: › - Use arrow-keys. Return to submit.
        Vanilla
        Vue
    ❯   React
        Preact
        Lit
        Svelte
        Solid
        Qwik
        Others
        
    ? Select a variant: › - Use arrow-keys. Return to submit.
    ❯   TypeScript
        TypeScript + SWC
        JavaScript
        JavaScript + SWC
        Remix ↗
    
    Scaffolding project in /Users/Wang/Desktop/x/vite-project...
    
    Done. Now run:
    
      cd vite-project
      pnpm install
      pnpm run dev
  • 输入自己的项目名称,一路选择 React + TS, 之后执行

    conf 复制代码
    cd vite-project
    pnpm install
    pnpm run dev
  • 之后,运行成功

    conf 复制代码
    VITE v5.3.1  ready in 200 ms
    
      ➜  Local:   http://localhost:5173/
      ➜  Network: use --host to expose
      ➜  press h + enter to show help
  • 打开 http://localhost:5173/

Vite 与 CRA 之间的性能对比

  • CRA (create-react-app) 是 React 官方推荐的脚手架
  • 自行做不太精准的一些测试
Vite CRA
初始化 & 启动时间 44s 3min23s
打包时间 2s 6s
打包产物大小 152kb 565kb
  • 由上面数据可见,vite 完胜,从网上的统计数据中:Vite 已经比 cra 快了接近 6 倍
  • 并且一开始就甩了 cra 一大截,显而易见地提升了初始化速度和开发体验

项目目录

conf 复制代码
├── index.html
├── package.json
├── pnpm-lock.yaml
├── public/
├── src/
│ ├── assets/
│ ├── App.css
│ ├── App.tsx
│ ├── index.css
│ ├── main.tsx
│ └── vite-env.d.ts
├── .eslintrc.cjs
├── .gitignore
├── package.json
├── pnpm-lock.yaml
├── tsconfig.app.json
├── tsconfig.node.json
├── pnpm-lock.yaml
├── tsconfig.json
└── vite.config.ts

探究 dev 环境

  • 当你访问 http://localhost:5173 的时候,Vite 的 Dev Server 会自动返回这个 HTML 文件的内容

    html 复制代码
    <!doctype html>
    <html lang="en">
      <head>
        <meta charset="UTF-8" />
        <link rel="icon" type="image/svg+xml" href="/vite.svg" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Vite + React + TS</title>
      </head>
      <body>
        <div id="root"></div>
        <script type="module" src="/src/main.tsx"></script>
      </body>
    </html>
  • 在这个 HTML 文件中,在 body 标签中除了 id 为 root 的根节点之

    外,还包含了一个声明了 type="module" 的 script 标签:
    <script type="module" src="/src/main.tsx"></script>

  • 由于现代浏览器原生支持了 ES 模块规范,因此原生的 ES 语法也可以直接放到浏览器中执行,只需要在 script 标签中声明 type="module" 即可。

  • 比如上面的 script 标签就声明了 type="module",同时 src 指向了 /src/main.tsx 文件,此时相当于请求了 http://localhost:5173/src/main.tsx 这个资源,Vite 的 Dev Server 此时会接受到这个请求,然后读取对应的文件内容,进行一定的中间处理,最后将处理的结果返回给浏览器

  • 这里的中间处理是:编译文件内容返回给浏览器

  • 好,现在看下 main.tsx 的内容

    ts 复制代码
    import React from 'react'
    import ReactDOM from 'react-dom/client'
    import App from './App.tsx'
    import './index.css'
    
    ReactDOM.createRoot(document.getElementById('root')!).render(
      <React.StrictMode>
        <App />
      </React.StrictMode>,
    )
  • 这里,浏览器并不识别 tsx 语法,也无法直接 import css 文件,上面这段

    代码究竟是如何被浏览器正常执行的,看下浏览器的网络面板,里面返回的是编译后的内容

  • 这涉及 Vite 内部的编译流程,Vite 会将项目的源代码编译成浏览器可以识别的代码,与此同时,一个 import 语句即代表了一个 HTTP 请求,Vite Dev Server 会读取本地文件,返回浏览器可以解析的代码

  • 当浏览器解析到新的 import 语句,又会发出新的请求,以此类推,直到所有的资源都加载完成

  • 可见,Vite 所倡导的 no-bundle 理念: 利用浏览器原生 ES 模块
    的支持,实现开发阶段的 Dev Server,进行模块的按需加载,而不是先整体打包再进行加载

  • 相比 Webpack 这种必须打包再加载的传统构建模式,Vite 在开发阶段省略了繁琐且耗时的打包过程,这也是它为什么快的一个重要原因

  • 默认情况下,index.html 在 src 之外,按照习惯,我们希望将它移动到src目录中,那就需要同步修改 vite.config.ts, 添加 root: path.join(__dirname, 'src')

    ts 复制代码
    import { defineConfig } from 'vite'
    import react from '@vitejs/plugin-react'
    // 引入 path 包注意两点:
    // 1. 为避免类型报错,你需要通过 `pnpm i @types/node -D` 安装类型
    // 2. tsconfig.node.json 中设置 `allowSyntheticDefaultImports: true`,以允许下面的 default 导入
    import path from 'path'
    
    // https://vitejs.dev/config/
    export default defineConfig({
      root: path.join(__dirname, 'src'), // 主要注意这里
      plugins: [react()],
    })
  • 之后,在 index.html 和 App.tsx 中修改相对路径

探究生产环境

  • 在生产环境中,Vite 依然会基于Rollup 进行打包,并采取一系列的打包优化手段。

  • 从脚手架项目的 package.json 中就可见一斑:

    ts 复制代码
    "scripts": {
      "dev": "vite",
      "build": "tsc -b && vite build",
      "lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
      "preview": "vite preview"
    }
  • 关注 build 和 preview, 在 build 之后,可以执行 preview 验证打包后的状态

  • 为什么在 vite build 命令执行之前要先执行 tsc 呢?tsc 作为 TypeScript 的官方编译命令,可以用来编译 TypeScript 代码并进行类型检查

  • 而这里的作用主要是用来做类型检查,我们可以从项目的 tsconfig.app.json 中注意到这样一个配置

    ts 复制代码
    {
     "compilerOptions": {
     // 省略其他配置
     // 1. noEmit 表示只做类型检查,而不会输出产物文件
     // 2. 这行配置与 tsc --noEmit 命令等效
     "noEmit": true,
     },
    }
  • 虽然 Vite 提供了开箱即用的 TypeScript 以及 JSX 的编译能力,但实际上底层并没有实现 TypeScript 的类型校验系统

  • 因此需要借助 tsc 来完成类型校验(在 Vue 项目中使用 vue-tsc 这个工具来完成),在打包前提早暴露出类型相关的问题,保证代码的健壮性

相关推荐
AlienZHOU3 小时前
AI Coding 时代下,我的技术面试实践分享
前端·后端·面试
Captaincc6 小时前
AI用量v0.1.11更新发布 新增 jusage doctor 诊断指令 托盘展示token 和余额 新增 AutoClaw 支持
前端·后端·vibecoding
计算机魔术师7 小时前
德国Wiki被黑后两周,OpenAI终于把模型失控的账本摊开了
前端
kyriewen8 小时前
我让 AI 当面试官面了我一轮:第 3 个追问我就卡住了(附 10 道追问清单)
前端·面试·ai编程
IT_陈寒8 小时前
Python的GIL把我坑惨了,多线程跑得比单线程还慢
前端·人工智能·后端
前端snow8 小时前
ai agent --- 多agent框架之图编排引擎-langgraph
前端
竹林8188 小时前
OmniPic Studio v3.2.1 核心技术架构与全平台发版解析文档
前端·浏览器
JamesZhang800788 小时前
页面内存只涨不跌? 一次泄漏排查, 牵出 WeakMap 的诞生
前端
Z小明8 小时前
第 6 章 组件进阶
前端·vue.js
江华森9 小时前
HTTP请求的完整过程详解:从DNS解析到TCP挥手的微秒级实战分析
前端