在vite创建的vue3项目中,引用图片资源有以下两种方式:
<template>
<div>
<img src="./assets/logo.png">
div>
template>
<script>
import logo from '@/assets/logo.png'
export default {
data() {
return {
logoSrc: logo
}
}
}
script>
<style>
.logo {
background: url(@/assets/logo.png);
}
style>
注意 默认情况下,TypeScript 不会将静态资源导入视为有效的模块。要解决这个问题,需要添加 vite/client
。
Vite 默认的类型定义是写给它的 Node.js API 的。要将其补充到一个 Vite 应用的客户端代码环境中,请添加一个 d.ts 声明文件:
/// <reference types="vite/client" />
或者,你也可以将 vite/client 添加到 tsconfig.json
中的 compilerOptions.types 下:
{
"compilerOptions": {
"types": ["vite/client"]
}
}
在import导入资源路径的时候后面加上’?url’就是vite的显示URL引入方式
import testurl from '@/test/testurl.js?url'
console.log(testurl) // /src/test/testurl.js
在Vite中,加上?url参数可以触发Vite的特殊处理机制。具体作用是Vite会将文件内容作为字符串并添加到导入语句中,并返回一个代理URL(类似/data-vite-xxx.js)。该代理URL指向Vite服务运行时生成的一个临时文件,这个临时文件包含了原始文件的内容。因此,加上?url参数的导入语句实际上是在请求一个临时文件,而不是原始文件。
这种方式的应用场景是需要在运行时动态加载文件,并且不希望在生产环境中将所有文件打包到一个JavaScript文件中。例如,在一些Web应用中,需要在用户进行交互操作时动态加载特定模块的代码,在这种情况下,可以使用这种方式进行模块加载。
对于代码import test from “./src/test.js?url”,打印出来的"/src/test.js"实际上是Vite返回的代理URL中包含的原始路径信息,这并不代表导入的真实文件路径。
这种引入方式可以方便地管理项目中的资源路径和名称,而且还可以实现一些特殊的需求,比如资源的按需加载、CDN加速等。
testurl.js文件内容如下:
import testurl from '@/test/testurl.js?raw'
console.log(testurl)
此时打印出来的内容如下
可以看到这种引入方式vite将源文件的内容以字符串的形式加载了。
应用场景
举个例子,假设我们有一个 css
文件,其中只包含了一段样式字符串,我们并不需要对它进行编译或预处理,只是需要直接拿到这个字符串来进行一些其他的操作。这时候,就可以像下面这样来引入这个文件:
import myCssString from '@/styles/my.css?raw';
这样,我们就可以拿到 my.css
文件中的样式字符串,并进行相应处理。
脚本可以通过 ?worker 或 ?sharedworker 后缀导入为 web worker。
// 在生产构建中将会分离出 chunk
import Worker from './shader.js?worker'
const worker = new Worker()
// sharedworker
import SharedWorker from './shader.js?sharedworker'
const sharedWorker = new SharedWorker()
// 内联为 base64 字符串
import InlineWorker from './shader.js?worker&inline'
众所周知,js是单线程的,而vite对于加载静态资源时使用 import 资源路径 + ?worker 的方式,其实就是告诉 Vite 这份代码是一个 Worker,需要特殊处理。在 Vite 中,Worker 也是一种模块,通常是在主线程之外执行,并且可以利用多个 CPU 核心来进行计算和渲染。
当我们使用 import 资源路径 + ?worker 的方式来导入一个 Worker 的时候,在 Vite 的编译过程中,会自动将其编译为一个字符串,然后通过 Blob 构造函数来创建一个新的 Worker 实例。这样就可以实现在浏览器中利用多个 CPU 核心来并行处理大量复杂的计算任务,提高代码运行效率。
需要注意的是,在使用 import 资源路径 + ?worker 的方式来导入一个 Worker 的时候,我们需要确保这份代码中没有依赖其它模块,否则会出现引用错误的问题。因此,我们通常会在 import 语句中使用相对路径来导入 Worker 中需要的其它代码。
举个例子
新建一个myworker.js文件, 通过postMessage项主线程发送消息
let i = 0
function timedCount() {
i = i + 1
postMessage(i) // 向主线程发送消息
setTimeout(timedCount, 500) // 500ms后再次调用timedCount
}
timedCount()
在app.vue中引入
// 导入worker
import Worker from '@/test/myworker.js?worker'
const worker = new Worker()
worker.onmessage = (e) => {
console.log(e)
console.log('接收worker传递过来的值', e.data)
}
打印结果如图:
可以看到我们成功的接收到了来自worker 传递过来的值,实现了主线程和子线程之间的通信。
JSON 可以被直接导入 —— 同样支持具名导入:
// 导入package.json
import pkg from '../package.json'
console.log(pkg)
// 具名导入
import { name } from '../package.json'
console.log(name)