您会注意到在项目结构中我们有两个资源目录:/public/ 和 /src/assets/。他们有什么区别?前者是纯静态资源,后者需要由构建工具打包处理后导入。
我们先讨论常规资源和静态资源的区别。
常规资源 - /src/assets
在 *.vue 组件中,所有的模板和 CSS 都会经过 vue-html-loader 和 css-loader 进行解析,在解析时会查找其中的资源链接。例如: 在<img src="./logo.png"> 和 background: url(./logo.png), "./logo.png" 中存在相对路径,它们会被 Vite 解析成一个依赖模块。
由于这些资源可能在构建期间被内联/复制/重命名,因此它们可被看作是源代码的一部分。这也是为什么推荐您将其放在 /src/assets 目录下,与其他源码放在一起。实际上,甚至不需要将它们全部都放在 /src/assets 目录下,例如,您可以将每个组件需要用的资源跟组件放在一起。
资源解析规则
相对路径,例如:./assets/logo.png,会被解析为一个依赖模块。它们将根据您的 vite 输出配置将它们替换为自动生成的 URL。
前缀为 ~ 的 URL 会被视为模块请求,类似于导入 import 'some-module/image.png'。如果要利用 Vite 的模块解析,则需要使用此前缀。所以推荐您这样使用:<img src="~assets/logo.png">,注意其中的 ~ 前缀。
静态资源 - /public
绝对路径不会被构建工具处理(例如:/logo.png – 其中 ‘/’ 是您设置的 publicPath)这些资源应该放在 public/ 目录中。这个目录中的内容不会被处理,在构建时会被简单的被复制到产物目录中。
必须保持确切名称和路径的文件(favicon、robots.txt、URL 来自数据的图片)应放在 public/ 中。public 文件夹中的内容会被原样复制到产物目录,不做任何处理。
请用根相对 URL 引用它们,例如 <img src="/logo.png">。这类 URL 完全不被处理:浏览器从域名根路径解析它们,因此只有当 build > publicPath 为 /(默认值)时才与 public 文件夹匹配。当应用部署在子路径下时,请给它们加上 import.meta.env.BASE_URL 前缀,Vite 会将其设为你的 publicPath:
<template>
<img :src="base + 'logo.png'" />
</template>
<script setup>
const base = import.meta.env.BASE_URL
</script>像 logo.png(没有前导斜杠)这样的裸相对 URL 同样不被处理。浏览器会相对当前页面 URL 解析它,因此一旦路由包含多个片段就会失效(/users/42 会请求 /users/logo.png)。对于 public 资源,请始终使用前导 / 或 import.meta.env.BASE_URL 前缀。
“assets” 目录中的文件,只有您在 vue 文件中引入并使用了的文件,才会被打包到构建产物中去。 而 “public” 目录中的文件在构建时全部都会被直接复制到构建产物中去。
如果您不是构建 SPA/PWA/SSR/SSG 应用,那么 /public/icons/* 和 /public/favicon.ico 目录中的文件不会被构建到应用中,因为它们不会用于任何目的。例如,Electron 或 Cordova 应用程序不需要这些文件。
更多关于 Vite
请阅读 Vite 文档.