vite 官网读后摘录

216 阅读5分钟

Vite 天然支持引入 .ts 文件。

Vite 仅执行 .ts 文件的转译工作,并不执行 任何类型检查。并假定类型检查已经被你的 IDE 或构建过程处理了。

Vite 使用 esbuild 将 TypeScript 转译到 JavaScript,约是 tsc 速度的 20~30 倍,同时 HMR 更新反映到浏览器的时间小于 50ms。

isolatedModules 是一个 TypeScript 编译器选项,用于确保 TypeScript 代码在单文件编译模式下能够正确运行。通过启用该选项,您可以确保使用只支持单文件编译模式的构建工具或转译器时,代码能够正确运行,并减少运行时问题的风险。然而,请注意,启用该选项可能会增加编译时间,并可能限制某些 TypeScript 功能的使用。

{  
  "compilerOptions": {  
    "isolatedModules": true,  
    // ... 其他编译器选项  
  }  
}

lightningcss:rust开发的一款css处理工具 类似 postcss 但是更快

JSON 可以被直接导入 —— 同样支持具名导入:

// 导入整个对象
import json from './example.json'
// 对一个根字段使用具名导入 —— 有效帮助 treeshaking!
import { field } from './example.json'

CSS 代码分割

Vite 会自动地将一个异步 chunk 模块中使用到的 CSS 代码抽取出来并为其生成一个单独的文件。这个 CSS 文件将在该异步 chunk 加载完成时自动通过一个 标签载入,该异步 chunk 会保证只在 CSS 加载完毕后再执行,避免发生 FOUC 。

如果你更倾向于将所有的 CSS 抽取到一个文件中,你可以通过设置 build.cssCodeSplit 为 false 来禁用 CSS 代码分割。

optimizeDeps

optimizeDeps.include 或 optimizeDeps.exclude 的一个典型使用场景,是当 Vite 在源码中无法直接发现 import 的时候。例如,import 可能是插件转换的结果。这意味着 Vite 无法在初始扫描时发现 import —— 只能在文件被浏览器请求并转换后才能发现。这将导致服务器在启动后立即重新打包。 include 和 exclude 都可以用来处理这个问题。如果依赖项很大(包含很多内部模块)或者是 CommonJS,那么你应该包含它;如果依赖项很小,并且已经是有效的 ESM,则可以排除它,让浏览器直接加载它。

处理加载报错(升级)

当 Vite 加载动态导入失败时,会触发 vite:preloadError 事件。event.payload 包含原始的导入错误信息。如果调用 event.preventDefault(),则不会抛出错误

window.addEventListener('vite:preloadError', (event) => {
  window.location.reload() // 例如,刷新页面
})

当重新部署时,托管服务可能会删除之前部署的资源。因此,之前访问过您站点的用户可能会遇到导入错误。这种错误发生的原因是用户设备上运行的资源过时,并尝试导入相应的旧代码块,而这些代码块已经被删除。这个事件对于解决这种情况会很有帮助。

多页面应用模式

├── package.json
├── vite.config.js
├── index.html
├── main.js
└── nested
    ├── index.html
    └── nested.js

在开发过程中,简单地导航或链接到 /nested/ - 将会按预期工作,与正常的静态文件服务器表现一致。

在构建过程中,你只需指定多个 .html 文件作为入口点即可:

// vite.config.js
import { resolve } from 'path'
import { defineConfig } from 'vite'

export default defineConfig({
  build: {
    rollupOptions: {
      input: {
        main: resolve(__dirname, 'index.html'),
        nested: resolve(__dirname, 'nested/index.html'),
      },
    },
  },
})

如果你指定了另一个根目录,请记住,在解析输入路径时,__dirname 的值将仍然是 vite.config.js 文件所在的目录。因此,你需要把对应入口文件的 root 的路径添加到 resolve 的参数中。

请注意,在 HTML 文件中,Vite 忽略了 rollupOptions.input 对象中给定的入口名称,而是在生成 dist 文件夹中的 HTML 资源文件时,使用了文件已解析的路径 ID。这确保了与开发服务器的工作方式保持一致的结构。

开发js 库模式

当你开发面向浏览器的库时,你可能会将大部分时间花在该库的测试/演示页面上。在 Vite 中你可以使用 index.html 获得如丝般顺滑的开发体验。

当这个库要进行发布构建时,请使用 build.lib 配置项,以确保将那些你不想打包进库的依赖进行外部化处理,例如 vue 或 react:

// vite.config.js
import { resolve } from 'path'
import { defineConfig } from 'vite'

export default defineConfig({
  build: {
    lib: {
      // Could also be a dictionary or array of multiple entry points
      entry: resolve(__dirname, 'lib/main.js'),
      name: 'MyLib',
      // the proper extensions will be added
      fileName: 'my-lib',
    },
    rollupOptions: {
      // 确保外部化处理那些你不想打包进库的依赖
      external: ['vue'],
      output: {
        // 在 UMD 构建模式下为这些外部化的依赖提供一个全局变量
        globals: {
          vue: 'Vue',
        },
      },
    },
  },
})

入口文件将包含可以由你的包的用户导入的导出:

// lib/main.js
import Foo from './Foo.vue'
import Bar from './Bar.vue'
export { Foo, Bar }

使用如上配置运行 vite build 时,将会使用一套面向库的 Rollup 预设,并且将为该库提供两种构建格式:es 和 umd (可在 build.lib 中配置):

$ vite build
building for production...
dist/my-lib.js      0.08 kB / gzip: 0.07 kB
dist/my-lib.umd.cjs 0.30 kB / gzip: 0.16 kB

推荐在你库的 package.json 中使用如下格式:

{
  "name": "my-lib",
  "type": "module",
  "files": ["dist"],
  "main": "./dist/my-lib.umd.cjs",
  "module": "./dist/my-lib.js",
  "exports": {
    ".": {
      "import": "./dist/my-lib.js",
      "require": "./dist/my-lib.umd.cjs"
    }
  }
}

或者,如果暴露了多个入口起点:

{
  "name": "my-lib",
  "type": "module",
  "files": ["dist"],
  "main": "./dist/my-lib.cjs",
  "module": "./dist/my-lib.js",
  "exports": {
    ".": {
      "import": "./dist/my-lib.js",
      "require": "./dist/my-lib.cjs"
    },
    "./secondary": {
      "import": "./dist/secondary.js",
      "require": "./dist/secondary.cjs"
    }
  }
}

避免使用桶文件

// src/utils/index.js
export * from './color.js'
export * from './dom.js'
export * from './slash.js'

当你只导入一个单独的 API,例如 import { slash } from './utils',需要获取和转换桶文件中的所有文件,因为它们可能包含 slash API,也可能包含在初始化时运行的其他副作用。这意味着在初始页面加载时,你加载的文件比所需的要更多,导致页面加载速度变慢。

如果可能的话,你应该尽量避免使用桶文件(barrel files),直接导入单独的 API,例如 import { slash } from './utils/slash.js'。