# 资源 URL 处理

当 Vue Loader 编译 SFC 中的 <template> 块时,它还会将遇到的任何资源 URL 转换为 **webpack 模块请求**。

例如,以下模板片段

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

将被编译成

createElement('img', {
  attrs: {
    src: require('../image.png') // this is now a module request
  }
})

默认情况下,以下标签/属性组合将被转换,并且可以使用 transformAssetUrls 选项进行配置。

{
  video: ['src', 'poster'],
  source: 'src',
  img: 'src',
  image: ['xlink:href', 'href'],
  use: ['xlink:href', 'href']
}

此外,如果您已配置使用 css-loader 处理 <style> 块,CSS 中的资源 URL 也将以类似的方式处理。

# 转换规则

资源 URL 转换遵循以下规则

  • 如果 URL 是绝对路径(例如 /images/foo.png),它将按原样保留。

  • 如果 URL 以 . 开头,它将被解释为相对模块请求,并根据文件系统上的文件夹结构进行解析。

  • 如果 URL 以 ~ 开头,它后面的任何内容都将被解释为模块请求。这意味着您甚至可以引用节点模块中的资源

    <img src="~some-npm-package/foo.png">
    
  • 如果 URL 以 @ 开头,它也被解释为模块请求。这在您的 webpack 配置为 @ 设置别名时很有用,默认情况下,@ 指向由 vue-cli 创建的任何项目中的 /src

由于 .png 等扩展名不是 JavaScript 模块,您需要配置 webpack 使用 file-loaderurl-loader 来正确处理它们。使用 Vue CLI 创建的项目已预先配置了此功能。

# 为什么

资源 URL 转换的好处是

  1. file-loader 允许您指定将资源文件复制和放置的位置,以及如何使用版本哈希对其进行命名以实现更好的缓存。此外,这也意味着 **您只需将图像放在 *.vue 文件旁边,并使用基于文件夹结构的相对路径,而无需担心部署 URL**。通过适当的配置,webpack 将自动将文件路径重写为捆绑输出中的正确 URL。

  2. url-loader 允许您有条件地将文件内联为 base-64 数据 URL,如果它们小于给定阈值。这可以减少对琐碎文件的 HTTP 请求数量。如果文件大于阈值,它将自动回退到 file-loader