在 Vue 项目中,你是否遇到过这样的困惑:
"
assets
和static
文件夹有什么区别?" "图片到底该放哪个文件夹?" "为什么有的资源路径变了,有的没变?"
本文将彻底解析 assets
与 static
的核心差异 、使用场景 和最佳实践。
一、核心结论:一句话总结
assets
走构建流程(可处理),static
直接拷贝(不处理)。
维度 | assets |
static |
---|---|---|
是否参与构建 | ✅ 是 | ❌ 否 |
是否被 webpack 处理 | ✅ 是 | ❌ 否 |
是否支持模块化导入 | ✅ 是 | ❌ 否 |
是否会被重命名(hash) | ✅ 是 | ❌ 否 |
是否支持 Tree-shaking | ✅ 是 | ❌ 否 |
二、详细对比:从构建流程说起
🔄 1. assets
:构建流程的"参与者"
text
src/assets/logo.png
↓
webpack 处理
↓
压缩、转 base64、生成 hash 名
↓
dist/static/img/logo.2f1f87g.png
✅ assets
的特点:
- 参与构建 :被
webpack
处理; - 优化处理 :
- 图片压缩(
image-webpack-loader
); - 小图转
base64
(减少 HTTP 请求); - 文件名加
hash
(缓存优化);
- 图片压缩(
- 支持模块化导入:
js
import logo from '@/assets/logo.png';
console.log(logo); // /static/img/logo.abc123.png
- 路径动态化 :路径由构建工具生成,不可预测。
🔄 2. static
:构建流程的"旁观者"
text
static/favicon.ico
↓
直接拷贝
↓
dist/favicon.ico
✅ static
的特点:
- 不参与构建 :原封不动拷贝到
dist
; - 无优化:不压缩、不转码、不加 hash;
- 路径固定 :访问路径 =
/ + 文件名
; - 适合"即插即用"资源。
html
<!-- 直接通过绝对路径访问 -->
<link rel="icon" href="/favicon.ico">
<script src="/js/third-party.js"></script>
三、实战演示:同一个图片的不同命运
场景:项目中使用 logo.png
方式一:放在 assets
vue
<template>
<img :src="logo" alt="Logo">
</template>
<script>
import logo from '@/assets/logo.png';
// logo = "/static/img/logo.abc123.png"
</script>
✅ 优势:
- 图片被压缩,体积更小;
- 文件名加 hash,缓存友好;
- 支持按需加载。
方式二:放在 static
vue
<template>
<img src="/static/logo.png" alt="Logo">
</template>
✅ 优势:
- 构建速度快(跳过处理);
- 路径固定,适合第三方脚本引用。
❌ 劣势:
- 图片未压缩,体积大;
- 无 hash,缓存更新困难。
四、何时使用 assets
?何时使用 static
?
✅ 推荐使用 assets
的场景:
资源类型 | 示例 |
---|---|
项目自用图片 | logo、banner、icon |
CSS/SCSS 文件 | @import '@/assets/styles/main.scss' |
字体文件 | .woff , .ttf (可被 hash) |
SVG 图标 | 可被 svg-sprite-loader 处理 |
需要按需引入的 JS | 工具函数、配置文件 |
💡 原则:项目源码中直接引用的资源 → 放
assets
。
✅ 推荐使用 static
的场景:
资源类型 | 示例 |
---|---|
第三方库 | static/js/jquery.min.js |
Favicon | favicon.ico |
Robots.txt | SEO 爬虫规则 |
大型静态文件 | PDF、视频(避免 webpack 处理) |
CND 回退文件 | 当 CDN 失败时本地加载 |
html
<!-- 第三方库回退 -->
<script src="https://cdn.example.com/vue.js"></script>
<script>window.Vue || document.write('<script src="/static/js/vue.min.js"><\/script>')</script>
💡 原则:不希望被构建工具处理的资源 → 放
static
。
五、Vue CLI 项目结构示例
bash
my-project/
├── public/ # Vue CLI 中 static 的新名字
│ ├── favicon.ico
│ ├── robots.txt
│ └── static/
│ └── js/
│ └── analytics.js
├── src/
│ ├── assets/ # 所有需要构建的资源
│ │ ├── images/
│ │ ├── fonts/
│ │ └── styles/
│ └── components/
└── package.json
⚠️ 注意:在 Vue CLI 3+ 中,
static
文件夹已更名为public
。
六、常见误区与最佳实践
❌ 误区 1:所有图片都放 static
html
<!-- 错误:大图未压缩,无 hash -->
<img src="/static/banner.jpg">
✅ 正确做法:
js
import banner from '@/assets/banner.jpg';
<img :src="banner">
❌ 误区 2:在 assets
中放第三方库
js
// ❌ 错误:第三方库应放 public
import 'jquery'; // 来自 node_modules 或 assets
✅ 正确做法:
html
<!-- 放 public,通过 script 标签引入 -->
<script src="/static/js/jquery.min.js"></script>
✅ 最佳实践清单
实践 | 说明 |
---|---|
✅ 小图放 assets |
转 base64,减少请求 |
✅ 大图放 assets |
压缩,但不转 base64 |
✅ 第三方库放 public |
避免重复打包 |
✅ 使用 require 动态加载 |
:src="require('@/assets/dynamic.png')" |
✅ 配置 publicPath |
部署到子目录时设置 |
💡 结语
"
assets
是你的'智能资源库',static
(public
)是你的'原始文件仓库'。"
选择 | 使用场景 |
---|---|
assets |
项目源码引用、需要优化、支持 hash |
static / public |
第三方资源、固定路径、避免构建 |
掌握这一原则,你就能:
✅ 优化项目性能;
✅ 减少打包体积;
✅ 提升缓存效率;
✅ 避免资源加载错误。