前言
经常遇到这么一个问题。h5项目需要做图片资源预加载的情况,我们往往需要手动的拿到一个个图片地址存在数组里面,然后再对其遍历做预加载处理,比如这样:
let imgList = ['http://domain.com/img/1.jpg','http://domain.com/img/2.jpg','http://domain.com/img/3.jpg',...];
本着能偷懒就偷懒的心态,我们可以编写一个webpack loader来处理,然后给我们返回以上所述那样一个数组。
预期在页面上这样调用,获取项目目录下的img文件夹的图片,给返回一个URL数组。
let imgList = __getPath('img');
原理
代码量很少,其实原理也比较简单,使用正则匹配__getPath('img')
获得图片所在的文件夹名称,然后拿到图片的相对路径,require,再将其拼接字符返回,如:
'[require("img/1.jpg"),require("img/2.jpg"),require("img/3.jpg"),...]'
最终return的content会被执行,然后就返回了一个图片URL数组。
const fs = require("fs")
const path = require('path');
const glob = require('glob');
const loaderUtils = require('loader-utils');
module.exports = function (content) {
const options = loaderUtils.getOptions(this) || {};
if(options.noCache)this.cacheable(false);
let fileReg = /__getPath\(([^\)]+)\)/gim;
//自定义文件 context|| 从webpack 4开始,原先的this.options.context被改进为this.rootContext
let rootPath = options.context || this.rootContext || (this.options && this.options.context);
let srcPath = path.join(rootPath, "/src");
let filepath = this.context; //当前处理文件所在的目录
content = content.replace(fileReg, (ret, src) => {
let folderName = src.replace(/'|"/g, "");
let resList = glob.sync(path.join(srcPath, folderName) + "/*");
let result = '[';
for (let i = 0; i < resList.length; i++) {
let respath = path.relative(filepath, resList[i]).replace(/\\/g, "/")
result += "require('" + respath + "')" + ","
}
result = result.substr(0,result.length-1) + "]";
return result;
})
return content;
}
安装和使用
我将其命名为imgurl-loader
发布到npm上了。
npm install --save-dev imgurl-loader
webpack配置
...
module: {
rules: [
{
test: /\.js$/,
include:/src/,
use: [{
loader:'imgurl-loader'
}]
},
//图片处理
{
test: /\.(png|jpg|jpeg|gif|svg)$/,
use: [{
loader: 'file-loader',
options: {
outputPath: 'img',
name: '[name]_[contenthash:8].[ext]'
}
}]
}
],
},
源码: https://github.com/xiaojiecong/imgurl-loader
Demo: https://github.com/xiaojiecong/imgurl-loader-demo
(如果可以帮到大家,可以star一下o( ̄︶ ̄)o)