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

相关推荐
橙子味冰可乐1 小时前
isprintable()方法——判断字符是否为可打印字符
java·前端·javascript·数据库·python
yunpeng.zhou1 小时前
logging 模块简单使用记录
java·前端·数据库
奋斗吧程序媛3 小时前
使用vue动态给同一个a标签添加内容 并给a标签设置hover,悬浮文字变色,结果鼠标悬浮有的字上面不变色
前端·javascript·vue.js
王天平·Jason Wong5 小时前
vue3弹窗usehook
前端·javascript·vue.js
小跳不会Coding5 小时前
vue开发网站--关于window.print()调取打印
前端·javascript·vue.js
concisedistinct6 小时前
深入浅出:npm常用命令详解与实践
前端·npm·node.js·工具·modules
碎像7 小时前
使用AI工具 Baidu Comate 辅助编码 快速定位修改Bug
java·前端·后端·bug·intellij idea
snow@li7 小时前
工程化:Commitlint / 规范化Git提交消息格式
前端·git
下雪天的夏风7 小时前
React@16.x(43)路由v5.x(8)常见应用场景(5)- 滚动条复位
前端·javascript·react.js
苦逼的猿宝7 小时前
重温react-08(createContext使用方式)
前端·javascript·vue.js·react.js·前端框架