Day4 vite的特点(下)

Glob Import 全局导入

即Vite 支持从文件系统导入多个模块:

  • 说明:vite是通过特殊的 import.meta.glob 函数达到该功能的

  • 用法:

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

    • 上面的内容将会转化为下面的内容:

      • 匹配的文件默认通过动态导入延迟加载,并在构建过程中被分割成单独的块。

      // code produced by vite
      const modules = {
        './dir/foo.js': () => import('./dir/foo.js'),
        './dir/bar.js': () => import('./dir/bar.js'),
      }
      
      • 如果您希望直接导入所有模块(例如,首先依赖于这些模块中的副作用),您可以传递 { eager: true } 作为第二个参数:

      const modules = import.meta.glob('./dir/*.js', { eager: true })
      
      • 上面的内容将会转化为下面的内容:

      // code produced by 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,
      }
      
    • 然后,您可以迭代 modules 对象的键来访问相应的模块:

      for (const path in modules) {
        modules[path]().then((mod) => {
          console.log(path, mod)
        })
      }
      

Glob Import As

将文件导入为字符串或者URl

  • 将文件作为字符串导入

    const modules = import.meta.glob('./dir/*.js', { as: 'raw', eager: true })
    
    
    //上面的内容将会转化为下面的内容:
    // code produced by vite
    const modules = {
      './dir/foo.js': 'export default "foo"\n',
      './dir/bar.js': 'export default "bar"\n',
    }
    
  • 将资源作为url导入

    { as: 'url' }
    

Multiple Patterns

即第一个参数可以是一个混合glob数组

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

Negative Patterns

即使用排除的glob模式(以!为前缀)添加到第一个参数来从结果中排除忽略某些文件

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

// code produced by vite
const modules = {
  './dir/foo.js': () => import('./dir/foo.js'),
}

Named Imports

可以仅使用 import 选项导入部分模块。

const modules = import.meta.glob('./dir/*.js', { import: 'setup' })
// code produced by 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),
}

eager 结合使用时,甚至可以为这些模块启用树摇动。

const modules = import.meta.glob('./dir/*.js', {
  import: 'setup',
  eager: true,
})


// code produced by vite:
import { setup as __glob__0_0 } from './dir/foo.js'
import { setup as __glob__0_1 } from './dir/bar.js'
const modules = {
  './dir/foo.js': __glob__0_0,
  './dir/bar.js': __glob__0_1,
}

import 设置为 default 以导入默认导出。

const modules = import.meta.glob('./dir/*.js', {
  import: 'default',
  eager: true,
})
// code produced by vite:
import __glob__0_0 from './dir/foo.js'
import __glob__0_1 from './dir/bar.js'
const modules = {
  './dir/foo.js': __glob__0_0,
  './dir/bar.js': __glob__0_1,
}

Custom Queries

使用 query 选项为导入提供自定义查询,以供其他插件使用

const modules = import.meta.glob('./dir/*.js', {
  query: { foo: 'bar', bar: true },
})
// code produced by vite:
const modules = {
  './dir/foo.js': () => import('./dir/foo.js?foo=bar&bar=true'),
  './dir/bar.js': () => import('./dir/bar.js?foo=bar&bar=true'),
}

Glob Import 注意事项

  • 以上这是 Vite 独有的功能,不是 Web 或 ES 标准。

  • glob 模式被视为导入说明符:它们必须是相对的(以 ./ 开头)或绝对的(以 / 开头,相对于项目根解析)或别名路径

  • 全局匹配是通过 fast-glob 完成的

  • import.meta.glob 中的所有参数都必须作为文字传递。您不能在其中使用变量或表达式。

动态导入

即Vite 支持带变量的动态导入。

变量仅代表一层深度的文件名。如果 file'foo/bar' ,导入将会失败。

对于更高级的用法,您可以使用 glob 导入功能。

const module = await import(`./dir/${file}.js`)

WebAssembly

预编译的 .wasm 文件可以使用 ?init 导入。默认导出将是一个返回 WebAssembly.Instance 的 Promise 的初始化函数:

import init from './example.wasm?init'

init().then((instance) => {
  instance.exports.test()
})

init 函数还可以将 importObject 传递给 WebAssembly.instantiate 作为其第二个参数:

init({
  imports: {
    someFunc: () => {
      /* ... */
    },
  },
}).then(() => {
  /* ... */
})

在生产版本中,小于 assetInlineLimit.wasm 文件将内联为 base64 字符串。否则,它们将被视为静态资产并按需获取。

目前不支持 WebAssembly 的 ES 模块集成提案。可使用 vite-plugin-wasm 或其他社区插件来处理此问题。

访问 WebAssembly 模块

如果您需要访问 Module 对象,例如要多次实例化它,请使用显式 URL 导入来解析资产,然后执行实例化:

import wasmUrl from 'foo.wasm?url'

const main = async () => {
  const responsePromise = fetch(wasmUrl)
  const { module, instance } =
    await WebAssembly.instantiateStreaming(responsePromise)
  /* ... */
}

main()

在 Node.js 中获取模块

在 SSR 中,作为 ?init 导入的一部分发生的 fetch() 可能会失败并出现 TypeError: Invalid URL

这里有一个替代方案,假设项目库是当前目录:

import wasmUrl from 'foo.wasm?url'
import { readFile } from 'node:fs/promises'

const main = async () => {
  const resolvedUrl = (await import('./test/boot.test.wasm?url')).default
  const buffer = await readFile('.' + resolvedUrl)
  const { instance } = await WebAssembly.instantiate(buffer, {
    /* ... */
  })
  /* ... */
}

main()

Web Workers

使用构造函数导入

可以使用 new Worker()new SharedWorker() 导入 Web Worker 脚本。与worker后缀相比,这种语法更接近标准,是创建worker的推荐方法。

const worker = new Worker(new URL('./worker.js', import.meta.url))

工作构造函数还接受选项,可用于创建“模块”works

const worker = new Worker(new URL('./worker.js', import.meta.url), {
  type: 'module',
})

使用查询后缀导入

可以通过将 ?worker?sharedworker 附加到导入请求来直接导入 Web Worker 脚本。默认导出将是自定义工作构造函数:

import MyWorker from './worker?worker'

const worker = new MyWorker()

worker脚本还可以使用 ESM import 语句代替 importScripts() 。注意:在开发过程中,这依赖于浏览器本机支持,但对于生产版本,它会被编译掉。

默认情况下,worker脚本将作为生产构建中的单独块发出。如果您希望将worker程序内联为 base64 字符串,请添加 inline 查询:

import MyWorker from './worker?worker&inline'

构建优化

下面列出的功能将作为构建过程的一部分自动应用,除非您想禁用它们,否则不需要显式配置。

CSS 代码分割

Vite 自动提取异步块中模块使用的 CSS 并为其生成单独的文件。当加载关联的异步块时,CSS 文件会通过 <link> 标签自动加载,并且保证异步块仅在 CSS 加载后才被评估以避免 FOUC。

果您希望将所有 CSS 提取到一个文件中,可以通过将 build.cssCodeSplit 设置为 false 来禁用 CSS 代码拆分。

预加载指令生成

Vite 自动为条目块生成 <link rel="modulepreload"> 指令,并在构建的 HTML 中直接导入它们。

异步块加载优化

在现实世界的应用程序中,Rollup 通常会生成“公共”块 - 在两个或多个其他块之间共享的代码。结合动态导入,下面的场景是很常见的:

在非优化场景中,当导入异步块 A 时,浏览器必须请求并解析 A 才能发现它还需要公共块 C 。这会导致额外的网络往返:Entry ---> A ---> C

Vite 使用预加载步骤自动重写代码分割动态导入调用,以便在请求 A 时,并行获取 C:Entry ---> (A + C)

C 可能会进行进一步的导入,这将导致在未优化的情况下出现更多的往返次数。 Vite的优化​​将跟踪所有直接导入,以完全消除往返,无论导入深度如何。

  • 31
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值