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 这个工具来完成),在打包前提早暴露出类型相关的问题,保证代码的健壮性

相关推荐
y先森3 小时前
CSS3中的伸缩盒模型(弹性盒子、弹性布局)之伸缩容器、伸缩项目、主轴方向、主轴换行方式、复合属性flex-flow
前端·css·css3
前端Hardy3 小时前
纯HTML&CSS实现3D旋转地球
前端·javascript·css·3d·html
susu10830189113 小时前
vue3中父div设置display flex,2个子div重叠
前端·javascript·vue.js
IT女孩儿4 小时前
CSS查缺补漏(补充上一条)
前端·css
吃杠碰小鸡5 小时前
commitlint校验git提交信息
前端
虾球xz5 小时前
游戏引擎学习第20天
前端·学习·游戏引擎
我爱李星璇5 小时前
HTML常用表格与标签
前端·html
疯狂的沙粒6 小时前
如何在Vue项目中应用TypeScript?应该注意那些点?
前端·vue.js·typescript
小镇程序员6 小时前
vue2 src_Todolist全局总线事件版本
前端·javascript·vue.js
野槐6 小时前
前端图像处理(一)
前端