Webpack 中 file-loader 和 url-loader 的区别

6,602 阅读3分钟

场景

我们希望在页面引入图片(包括 img 的 src 和 background 的 url)或设置字体。但是当我们基于 webpack 进行开发时,引入图片会遇到一些问题:(webpack是用JS写的,运行在node环境,所以默认webpack打包的时候只会处理JS之间的依赖关系!!!)

1. 引用路径的问题

举例:拿 background 样式用 url 引入背景图来说,众所周知,webpack 最终会将各个模块打包成一个文件,因此我们样式中的 url 路径是相对入口 html 页面的,而不是相对于原始 css 文件所在的路径。这就会导致图片引入失败。

解决办法

file-loader 可以指定要复制和放置资源文件的位置,以及如何使用版本哈希命名以获得更好的缓存。此外,这意味着 你可以就近管理图片文件,可以使用相对路径而不用担心部署时 URL 的问题。使用正确的配置,webpack 将会在打包输出中自动重写文件路径为正确的 URL。

用 file-loader 解决,file-loader 可以解析项目中的 url 引入(不仅限于 css),根据我们的配置,将图片拷贝到相应的路径,修改打包后文件引用路径,使之指向正确的文件。

2. 图片较多,会发很多 http 请求,会降低页面性能

url-loader 允许你有条件地将文件转换为内联的 base-64 URL (当文件小于给定的阈值),这会减少小文件的 HTTP 请求数。如果文件大于该阈值,会自动的交给 file-loader 处理。

这个问题可以通过 url-loader 解决。url-loader 会将引入的图片编码,生成 dataURl。相当于把图片数据翻译成一串字符。再把这串字符打包到文件中,最终只需要引入这个文件就能访问图片了。当然,如果图片较大,编码会消耗性能。因此 url-loader 提供了一个 limit 参数,小于 limit 字节的文件会被转为 DataURl,大于 limit 的还会使用 file-loader 进行 copy。

url-loader和file-loader关系

简答地说,url-loader 封装了 file-loader。url-loader 不依赖于 file-loader,即使用 url-loader 时,只需要安装 url-loader 即可,不需要安装 file-loader,因为 url-loader 内置了 file-loader。

url-loader 工作情况

通过上面的介绍,我们可以看到,url-loader 工作分两种情况:

  1. 文件大小 < limit 参数,url-loader 将会把文件转为 DataURL;
  2. 文件大小 > limit参数,url-loader 会调用 file-loader 进行处理,参数也会直接传给 file-loader。

ps. 因此通常只需要安装 url-loader 即可。

把字体文件转成 base64 是浏览器无法识别的,这是错误的操作.

工程中配置

如下:webpack.config.js

module.exports = ({
    ...
    module : {
        rules: [
            {
                // 小于10k的图片在img下不会有图片文件,而是直接把图片的base64值写到html引入图片的地方
                // 大于10k的图片会放在img下,需要的时候通过http请求下载
                test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
                loader: 'url-loader',
                options: {
                    limit: 10000,
                    name: utils.assetsPath('img/[name].[hash:7].[ext]')
                }
            },
            {
                test: /(\.(eot|ttf|woff|woff2|otf)|font)$/,
                loader: 'file-loader',
                options: { outputPath: 'fonts/' }
            }
        ]
    }
})

后续学习参考