vue填坑-引用静态资源

vue-cli静态资源

静态资源可以通过两种方式进行处理:

  • 在 JavaScript 被导入或在 template/CSS 中通过相对路径被引用。这类引用会被 webpack 处理。

  • 放置在 public 目录下或通过绝对路径被引用。这类资源将会直接被拷贝,而不会经过 webpack 的处理。

从相对路径导入

当你在 JavaScript、CSS 或 *.vue 文件中使用相对路径 (必须以 . 开头) 引用一个静态资源时,该资源将会被包含进入 webpack 的依赖图中。在其编译过程中,所有诸如 <img src="...">background: url(...)CSS @import 的资源 URL 都会被解析为一个模块依赖。

就是说 相对路径引用 会被webpack打包

例如:

1
<img src="./image.png">

会被编译为:

1
h('img', { attrs: { src: require('./image.png') }})

在其内部,Vue CLI 通过 file-loader 用版本哈希值和正确的公共基础路径来决定最终的文件路径,再用 url-loader 将小于 4kb 的资源内联,以减少 HTTP 请求的数量。

可以通过 chainWebpack 调整内联文件的大小限制。例如,下列代码会将其限制设置为 10kb:

1
2
3
4
5
6
7
8
9
10
// vue.config.js
module.exports = {
chainWebpack: config => {
config.module
.rule('images')
.use('url-loader')
.loader('url-loader')
.tap(options => Object.assign(options, { limit: 10240 }))
}
}

URL 转换规则

如果 URL 是一个绝对路径 (例如 /images/foo.png),它将会被保留不变。

如果 URL 以 . 开头,它会作为一个相对模块请求被解释且基于你的文件系统中的目录结构进行解析。

如果 URL 以 ~ 开头,其后的任何内容都会作为一个模块请求被解析。这意味着你甚至可以引用 Node 模块中的资源:

1
<img src="~some-npm-package/foo.png">

如果 URL 以 @ 开头,它也会作为一个模块请求被解析。它的用处在于 Vue CLI 默认会设置一个指向 <projectRoot>/src 的别名 @。(仅作用于模版中)

public 文件夹

VUE CLI 推荐将静态资源作为模块引入,会被webpack打包:

  • 脚本和样式表会被打包在一起,减少网络请求
  • 编译时查找文件,而不是在用户端报错
  • 打包后的文件名包含了内容哈希,浏览器不会加载缓存的老版本

文件名直接带内容哈希,6666…

使用public内的资源

public 目录提供的是一个应急手段,当你通过绝对路径引用它时,留意应用将会部署到哪里。如果你的应用没有部署在域名的根部,那么你需要为你的 URL 配置 publicPath 前缀:

在 public/index.html 或其它通过 html-webpack-plugin 用作模板的 HTML 文件中,你需要通过 <%= BASE_URL %> 设置链接前缀:

1
<link rel="icon" href="<%= BASE_URL %>favicon.ico">

在模板中,你首先需要向你的组件传入基础 URL:

1
2
3
4
5
data () {
return {
publicPath: process.env.BASE_URL
}
}

然后:

1
<img :src="`${publicPath}my-image.png`">

何时使用 public 文件夹

  • 你需要在构建输出中指定一个文件的名字。
  • 你有上千个图片,需要动态引用它们的路径。
  • 有些库可能和 webpack 不兼容,这时你除了将其用一个独立的 <script> 标签引入没有别的选择。

reference

处理静态资源