Webpack loader 之 url-loader
本文于851天之前发表,文中内容可能已经过时。
简介
安装
1 | npm install --save-dev url-loader |
用法
url-loader
功能类似于 file-loader
,但是在文件大小(单位 byte)低于指定的限制时,可以返回一个 DataURL。
1 | import img from './webpack-logo.png' |
webpack.config.js
1 | module.exports = { |
常用配置项
limit
limit 用于配置需内联的文件字节限制,类型是 Number,默认值为 undefined。如果文件大于限制(以字节为单位),该文件将交由 file-loader
处理 ,并将所有查询参数传递给它。
webpack.config.js
1 | { |
mimetype
mimetype 用于设置文件的 MIME 类型。如果未指定,则将使用文件扩展名来查找对应的 MIME 类型。
webpack.config.js
1 | { |
fallback
fallback 用于设置当 url-loader 加载的文件大于限制时,所对应的处理器。类型是 String,默认值是 “file-loader”。
webpack.config.js
1 | { |
loader 准则
编写 loader 时应该遵循以下准则:
- 简单易用。
- 使用链式传递。
- 模块化的输出。
- 确保无状态。
- 使用 loader utilities。
- 记录 loader 的依赖。
- 解析模块依赖关系。
- 提取通用代码。
- 避免绝对路径。
- 使用 peer dependencies。
以上的准则按重要程度排序,但某些仅适用于某些场景。若想进一步了解自定义 loader,可以阅读 编写一个 loader 这个文档。接下来,我们来基于上述的准则分析一下 url-loader 的源码。
url-loader 源码简析
所谓 loader 只是一个导出为函数对象的 JavaScript 模块。loader runner 会调用这个函数,然后把上一个 loader 产生的结果或者资源文件传入进去。函数的 this
上下文将由 webpack 填充,并且 loader runner 具有一些有用方法,可以使 loader 改变为异步调用方式,或者获取 query 参数。
其实本文介绍的 url-loader 在处理 limit 范围内文件时,并不是复制文件,而是把文件转成 Data URLs,然后直接内嵌到 html/css/js 文件中。
导入依赖项
1 | import { getOptions } from 'loader-utils'; |
需要注意的是,默认情况下 webpack 会对文件内容进行 UTF8 编码,当 loader 需要处理二进制数据时,需要设置 raw 为 true。此后,webpack 用使用 raw-loader 来加载所指定的文件,而不会对文件内容进行 UTF8 编码。
获取配置对象及验证
1 | export default function loader(src) { |
url-loader 会先调用 loaderUtils 对象的 getOptions 方法,获取当前 loader 对应的配置对象,然后基于已定义的 Schema,验证配置对象的有效性。对应的 Schema 定义如下:
1 | { |
处理 limit
1 | const file = this.resourcePath; // 资源文件路径 |
Data URLs 由四个部分组成:前缀(data:
)、指示数据类型的MIME类型、如果非文本则为可选的base64
标记、数据本身:
1 | data:[<mediatype>][;base64],<data> |
mediatype 是个 MIME 类型的字符串,例如 “image/jpeg
“ 表示 JPEG 图像文件。如果被省略,则默认值为 text/plain;charset=US-ASCII
。
如果数据是文本类型,你可以直接将文本嵌入 (根据文档类型,使用合适的实体字符或转义字符)。如果是二进制数据,你可以将数据进行 base64 编码之后再进行嵌入。
处理 fallback
1 | // 规范化fallback参数,处理字符串或对象的形式 |
总结
在 Webpack loader 之 file-loader 文章中,我们简单介绍了 file-loader。那么 url-loader 和 file-loader 之间有什么关系呢?通过阅读 url-loader 源码,我们知道 url-loader 有两种工作模式:
- 当文件大小小于 limit 值时,url-loader 将会把文件转为 Data URLs;
- 当文件大小大于 limit 值时,url-loader 会默认调用 file-loader 进行处理,参数也会直接传给 file-loader。
简单地说,url-loader 封装了 file-loader。但 url-loader 不依赖于 file-loader,通过配置 fallback 参数,我们可以灵活地设定 fallback Loader。在实际项目中,通过配置 url-loader 的 limit 参数,我们就可以把一些静态资源转成 Data URLs,从而避免过多的 HTTP 请求,从而提高页面的性能。当然 limit 参数也不能设置得太大,不然也会导致加载的资源过大,影响页面的加载速度。
参考资源
欢迎小伙伴们订阅全栈修仙之路,及时阅读 TypeScript、Node/Deno、Angular 技术栈最新文章。
