vite查漏补缺

一、静态资源处理

//png txt后缀的文件不会检测是否存在,js json vue文件会检测是否存在
import test from "@/assets/imgs/test1.png"
console.log(test);  //   /src/assets/imgs/test1.png返回图片的绝对路径
// 显式加载资源为一个 URL
import test from "@/assets/imgs/test1.png?url"  //等效于上面那种方式,默认选项
//会检测所有类型的文件是否存在,毕竟要转换为二进制
import test from "@/assets/imgs/test.png?raw"
console.log(test); // 转换为二进制
// 加载为 Web Worker
import Worker from './worker.js?worker'

二、JSON具名导入

{
  "name": "John Doe",
  "age": 30,
  "address": {
    "street": "123 Main St",
    "city": "Anytown"
  }
}
import { name, age } from '@/assets/imgs/test.json';
console.log(name); // 输出 "John Doe"
console.log(age);  // 输出 30
//这个是具名导入,json文件的编译结果,可以看出只能具名导出第一层
//原生esmodule导入导出只能是js,在vite中能导入json,png等格式是因为vite做了处理,将其变成了js文件
//这里说的js文件,不是指后缀名为.js的文件,浏览器也不是通过后缀名来判断文件的类型
//是通过响应头里面的Content-Type的类型来判断的
export const name = "John Doe";
export const age = 30;
export const address = {
	street: "123 Main St",
	city: "Anytown"
};
export default {
	name: name,
	age: age,
	address: address
};

三、glob导入

const modules = import.meta.glob('./dir/*.js')

以上代码会被转换为下面的代码,通过变量modules可以获取到相应模块
这个功能可以用于做约定式路由,也可以用于做动态路由,若依框架动态路由就是用的这个

// vite 生成的代码
const modules = {
  './dir/foo.js': () => import('./dir/foo.js'),
  './dir/bar.js': () => import('./dir/bar.js'),
}

上面的模块是懒加载,如果需要直接导入,可以添加额外参数

const modules = import.meta.glob('./dir/*.js', { eager: true })
// vite 生成的代码
import * as __glob__0_0 from './dir/foo.js'
import * as __glob__0_1 from './dir/bar.js'
const modules = {
  './dir/foo.js': __glob__0_0,
  './dir/bar.js': __glob__0_1,
}

多个匹配模式

const modules = import.meta.glob(['./dir/*.js', './another/*.js'])

反面匹配模式

//以!开头的路径将被忽略
const modules = import.meta.glob(['./dir/*.js', '!**/bar.js'])

如果只想要导入模块中的部分内容,那么可以利用 import 选项

const modules = import.meta.glob('./dir/*.js', { import: 'setup' })
// vite 生成的代码
const modules = {
  './dir/foo.js': () => import('./dir/foo.js').then((m) => m.setup),
  './dir/bar.js': () => import('./dir/bar.js').then((m) => m.setup),
}

Glob 导入注意事项

  • 这只是一个 Vite 独有的功能而不是一个 Web 或 ES 标准
  • 该 Glob 模式会被当成导入标识符:必须是相对路径(以 ./ 开头)或绝对路径(以 / 开头,相对于项目根目录解析)或一个别名路径
  • 所有 import.meta.glob 的参数都必须以字面量传入。你 不 可以在其中使用变量或表达式

四、使用插件

强制插件顺序
为了与某些 Rollup 插件兼容,可能需要强制修改插件的执行顺序,或者只在构建时使用。这应该是 Vite 插件的实现细节。可以使用 enforce修饰符来强制插件的位置:

  • pre:在 Vite 核心插件之前调用该插件
  • 默认:在 Vite 核心插件之后调用该插件
  • post:在 Vite 构建插件之后调用该插件
// vite.config.js
import image from '@rollup/plugin-image'
import { defineConfig } from 'vite'
export default defineConfig({
  plugins: [
    {
      ...image(),
      enforce: 'pre'
    },
  ],
})

默认情况下插件在开发 (serve) 和生产 (build) 模式中都会调用。如果插件在服务或构建期间按需使用,请使用 apply 属性指明它们仅在 buildserve模式时调用

// vite.config.js
import typescript2 from 'rollup-plugin-typescript2'
import { defineConfig } from 'vite'

export default defineConfig({
  plugins: [
    {
      ...typescript2(),
      apply: 'build',
    },
  ],
})

五、文件系统缓存

Vite 将预构建的依赖项缓存到 node_modules/.vite 中。它会基于以下几个来源来决定是否需要重新运行预构建步骤:

  • 包管理器的锁文件内容,例如 package-lock.jsonyarn.lockpnpm-lock.yaml,或者 bun.lockb
  • 补丁文件夹的修改时间;
  • vite.config.js 中的相关字段;
  • NODE_ENV 的值
    只有在上述其中一项发生更改时,才需要重新运行预构建。
    如果出于某些原因你想要强制 Vite 重新构建依赖项,你可以在启动开发服务器时指定 --force 选项,或手动删除 node_modules/.vite缓存目录。

六、处理加载报错

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

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

七、文件变化时重新构建

你可以使用 vite build --watch 来启用 rollup 的监听器。或者,你可以直接通过 build.watch 调整底层的 WatcherOptions 选项

// vite.config.js
export default defineConfig({
  build: {
    watch: {
      // https://rollupjs.org/configuration-options/#watch
    },
  },
})

当启用 --watch 标志时,对 vite.config.js的改动,以及任何要打包的文件,都将触发重新构建

八、环境变量

Vite 在一个特殊的 import.meta.env 对象上暴露环境变量,这些变量在构建时会被静态地替换掉。这里有一些在所有情况下都可以使用的内建变量:

  • import.meta.env.MODE: {string} 应用运行的模式 命令行 --mode后面的值
  • import.meta.env.BASE_URL: {string} 部署应用时的基本 URL。由base配置项决定。
  • import.meta.env.PROD: {boolean} 应用是否运行在生产环境(使用 NODE_ENV=‘production’ 运行开发服务器或构建应用时使用 NODE_ENV=‘production’ )
  • import.meta.env.DEV: {boolean} 应用是否运行在开发环境 (永远与 import.meta.env.PROD相反)。
  • import.meta.env.SSR: {boolean} 应用是否运行在 server 上。

九、HTML 环境变量替换

Vite 还支持在 HTML 文件中替换环境变量。import.meta.env 中的任何属性都可以通过特殊的 %ENV_NAME% 语法在 HTML 文件中使用:

<h1>Vite is running in %MODE%</h1>
<p>Using data from %VITE_API_URL%</p>

如果环境变量在import.meta.env中不存在,比如不存在的 %NON_EXISTENT%,则会将被忽略而不被替换,这与 JS 中的 import.meta.env.NON_EXISTENT 不同,JS 中会被替换为 undefined

十、配置

1.情景配置

如果配置文件需要基于(dev/servebuild)命令或者不同的 模式 来决定选项,亦或者是一个 SSR 构建(isSsrBuild)、一个正在预览的构建产物(isPreview),则可以选择导出这样一个函数:

export default defineConfig(({ command, mode, isSsrBuild, isPreview }) => {
  if (command === 'serve') {
    return {
      // dev 独有配置
    }
  } else {
    // command === 'build'
    return {
      // build 独有配置
    }
  }
})
2.异步配置
export default defineConfig(async ({ command, mode }) => {
  const data = await asyncFunction()
  return {
    // vite 配置
  }
})
3.在配置中使用环境变量

环境变量通常可以从 process.env获得。
注意 Vite 默认是不加载 .env 文件的,因为这些文件需要在执行完 Vite 配置后才能确定加载哪一个,举个例子,rootenvDir 选项会影响加载行为。不过当你的确需要时,你可以使用 Vite 导出的 loadEnv 函数来加载指定的 .env 文件。

import { defineConfig, loadEnv } from 'vite'

export default defineConfig(({ command, mode }) => {
  // 根据当前工作目录中的 `mode` 加载 .env 文件
  // 设置第三个参数为 '' 来加载所有环境变量,而不管是否有 `VITE_` 前缀。
  const env = loadEnv(mode, process.cwd(), '')
  return {
    // vite 配置
    define: {
      __APP_ENV__: JSON.stringify(env.APP_ENV),
    },
  }
})

十一、共享选项

1. define

定义全局常量替换方式。其中每项在开发环境下会被定义在全局,而在构建时被静态替换

export default defineConfig({
  define: {
    __APP_VERSION__: JSON.stringify('v1.0.0'),
    __API_URL__: 'window.__backend_api_url',
  },
})
console.log(__APP_VERSION__)  //v1.0.0

如果使用的是ts,需要添加类型声明才不会提示错误

// vite-env.d.ts
declare const __APP_VERSION__: string
2. resolve.extensions

导入时想要省略的扩展名列表。注意,不 建议忽略自定义导入类型的扩展名(例如:.vue),因为它会影响 IDE 和类型支持。

export default defineConfig({
   resolve: {
    alias: {
      "@": resolve(__dirname, "./src"),
    },
    extensions:[".ts", ".js", ".vue", ".json"]
  },
})
3. css.postcss

内联的 PostCSS 配置(格式同 postcss.config.js),或者一个(默认基于项目根目录的)自定义的 PostCSS 配置路径。

对内联的 POSTCSS 配置,它期望接收与 postcss.config.js 一致的格式。但对于 plugins 属性有些特别,只接收使用 数组格式。
注意:如果提供了该内联配置,Vite 将不会搜索其他 PostCSS 配置源。

4. css.preprocessorOptions

指定传递给 CSS 预处理器的选项。文件扩展名用作选项的键。每个预处理器支持的选项可以在它们各自的文档中找到:

export default defineConfig({
  css: {
    preprocessorOptions: {
      less: {
        math: 'parens-division',
      },
      styl: {
        define: {
          $specialColor: new stylus.nodes.RGBA(51, 197, 255, 1),
        },
      },
    },
  },
})
5. css.preprocessorOptions[extension].additionalData

该选项可以用来为每一段样式内容添加额外的代码。但是要注意,如果你添加的是实际的样式而不仅仅是变量,那这些样式在最终的产物中会重复。

export default defineConfig({
  css: {
    preprocessorOptions: {
      scss: {
        additionalData: `$injectedColor: orange;`,   //$injectedColor: orange;会添加到每一个scss文件中
      },
    },
  },
})
6. css.preprocessorMaxWorkers

如果启用了这个选项,那么 CSS 预处理器会尽可能在 worker 线程中运行。默认是0,可以设置为number | true,true 表示 CPU 数量减 1。

7. css.devSourcemap

在开发过程中是否启用 sourcemap。

8. envDir

用于加载 .env 文件的目录。可以是一个绝对路径,也可以是相对于项目根的路径。

9. envPrefix

以 envPrefix 开头的环境变量会通过 import.meta.env暴露在你的客户端源码中。默认是VITE_

十二、服务器选项

1. server.strictPort

设为 true 时若端口已被占用则会直接退出,而不是尝试下一个可用端口

2. server.warmup

提前转换和缓存文件以进行预热。可以在服务器启动时提高初始页面加载速度,并防止转换瀑布
请确保只添加经常使用的文件,以免在启动时过载 Vite 开发服务器

export default defineConfig({
  server: {
    warmup: {
      clientFiles: ['./src/components/*.vue', './src/utils/big-utils.js'],
      ssrFiles: ['./src/server/modules/*.js'],
    },
  },
})

十三、构建选项

1. build.target

设置最终构建的浏览器兼容目标

2. build.outDir

指定输出路径

3. build.assetsDir

指定生成静态资源的存放路径(相对于 build.outDir

4. build.assetsInlineLimit

小于此阈值的导入或引用资源将内联为 base64 编码,以避免额外的 http 请求。设置为 0 可以完全禁用此项。
如果传入了一个回调函数,可以通过返回一个布尔值来选择是否加入。如果没有返回任何内容,那么就会应用默认的逻辑。

5. build.cssCodeSplit

启用/禁用 CSS 代码拆分。当启用时,在异步 chunk 中导入的 CSS 将内联到异步 chunk 本身,并在其被加载时一并获取。
如果禁用,整个项目中的所有 CSS 将被提取到一个 CSS 文件中。

6. build.minify

设置为 false 可以禁用最小化混淆,或是用来指定使用哪种混淆器

7. build.write

设置为 false 来禁用将构建后的文件写入磁盘

十四、依赖优化选项
1. optimizeDeps.entries

设置依赖预构建的入口

2. optimizeDeps.exclude

在预构建中强制排除的依赖项

3. optimizeDeps.include

默认情况下,不在 node_modules 中的,链接的包不会被预构建。使用此选项可强制预构建链接的包。

4. optimizeDeps.force

设置为 true 可以强制依赖预构建,而忽略之前已经缓存过的、已经优化过的依赖。

十四、插件API

1. 虚拟模块

虚拟模块是一种很实用的模式,使你可以对使用 ESM 语法的源文件传入一些编译时信息

export default function myPlugin() {
  const virtualModuleId = 'virtual:my-module'
  const resolvedVirtualModuleId = '\0' + virtualModuleId

  return {
    name: 'my-plugin', // 必须的,将会在 warning 和 error 中显示
    resolveId(id) {
      if (id === virtualModuleId) {
        return resolvedVirtualModuleId
      }
    },
    load(id) {
      if (id === resolvedVirtualModuleId) {
        return `export const msg = "from virtual module"`
      }
    },
  }
}
import { msg } from 'virtual:my-module'
console.log(msg)
2. resolveId

拦截自定义的模块,不能是node_modules里面的,也不能/./,../

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值