起因
公司项目的某个业务场景如下:下载订单时,提供四个可选的背景图片;客户点击其中一个,则可以实时预览订单效果,点击下载按钮即保存到本地。
前辈写的一行代码如下,功能是在页面加载时即读取几张图片资源的base64。
const img = require('!!url-loader?limit=100000!@/assets/images/xxx.png');
可以看到,使用了webpack中的url-loader,但是这个loader并没有出现在项目的vue.config.js中。使用这种写法的目的是什么呢?我开始了探究:
webpack-loader的inline引入
最新的webpack 5.x文档中已经找不到这种写法,但是我搜到webpack 2.2文档 -- url-loader中提到了这种使用方式:
url加载器的功能类似file加载器,但是在文件大小低于指定的限制时(单位 bytes)可以返回一个 Data Url。大小限制可以通过传递查询参数来指定。(默认为无限制)
如果文件大小大于限制,将转为使用 file-loader,所有的查询参数也会透传过去。
require("url-loader?limit=10000!./file.png");
// => 如果 "file.png" 大小小于 10kb 将返回 DataUrl
require("url-loader?mimetype=image/png!./file.png");
// => 指定文件的 mimetype(否则会用文件后缀推测)
require("url-loader?prefix=img/!./file.png");
// => file-loader 的参数也有效,如果被使用它们将被传递给 file-loader
这里有一个实际应用的例子,仅将选中的部分资源转换为base64格式。
同时,facebook的react教程出于随时可能弃用webpack的考虑,不建议用户在代码中使用inline写法;而eslint/no-webpack-loader-syntax这一eslint规范也提到,即使webpack支持inline语法,但更推荐用户通过配置文件的形式来使用loader:
Webpack allows specifying the loaders to use in the import source string using a special syntax ......
This syntax is non-standard, so it couples the code to Webpack. The recommended way to specify Webpack loader configuration is in a Webpack configuration file.
双感叹号写法
可以注意到,上方参数中使用了双感叹号写法。!!是一种js语法,但在此处是一种webpack-loader的语法:
-!禁用前置和正常 loader!禁用普通 loader!!禁用前置后置以及正常 loader
公司项目中,虽然vue.config.js中没有显示进行url-loader的配置,但是使用vue inspect 导出的完整配置中,还是能看到相关的代码。这是因为公司的脚手架中,将url-loader作为其默认加载器。这样一来,!!语法的禁用就显得很重要了。
语句末尾的!则代表着loader分隔符,用来将依次使用的多个loder分开。此处是为了分割loader和实际图片资源的地址。
其他实现方式
上文提到,webpack官网文档已经删除了这种inline写法,并且大公司也不推荐使用这种方式。那我们有没有其他方式实现按需转换呢?
有的,老老实实写正则表达式吧hhh
几篇讲loader的参考文章:
www.dazhuanlan.com/yitumoon/to…