0
点赞
收藏
分享

微信扫一扫

webpack原理篇(六十二):实战开发一个自动合成雪碧图的loader


说明

玩转 webpack 学习笔记

支持的语法

对样式里面图片引用后面加 ​​__sprite​​ 进行图片合并

webpack原理篇(六十二):实战开发一个自动合成雪碧图的loader_雪碧图

如何将两张图片合成一张图片?

使用 spritesmith

​​https://github.com/twolfson/spritesmith​​

webpack原理篇(六十二):实战开发一个自动合成雪碧图的loader_webpack_02

spritesmith 使用示例

const sprites = ['./images/1.jpg', './images/2.jpg'];
Spritesmith.run({ src: sprites }, function handleResult(err,) {
result.image;
result.coordinates;
result.properties;
});

实战开发

1、新建初始化项目

新建文件夹 sprite-loader,然后执行下面命令初始化项目

npm

webpack原理篇(六十二):实战开发一个自动合成雪碧图的loader_css_03

2、添加图片资源

我们在 src 的 img 文件夹里添加 3 张图片

webpack原理篇(六十二):实战开发一个自动合成雪碧图的loader_雪碧图_04

3、安装依赖

npm

webpack原理篇(六十二):实战开发一个自动合成雪碧图的loader_webpack_05

4、测试合成雪碧图的代码

新建 ​​test.js​​ 文件

const Spritesmith = require('spritesmith');

const sprites = [
'./src/img/kaimo-001.png',
'./src/img/kaimo-002.jpg',
'./src/img/kaimo-003.png'
];

// 生成精灵表
Spritesmith.run({
src: sprites
}, function handleResult(err,) {
// 如果有错误,抛出它
if (err) {
throw err;
}
console.log("result---->", result)
});

我们执行 ​​node test.js​

webpack原理篇(六十二):实战开发一个自动合成雪碧图的loader_雪碧图_06

如果你报 ​​Invalid file signature​​​ 错,可以参考我这篇文章:使用 spritesmith 报错 Error: Invalid file signature

然后我们输出到磁盘

const Spritesmith = require('spritesmith');
const fs = require('fs');
const path = require('path');

const sprites = [
'./src/img/kaimo-001.png',
'./src/img/kaimo-002.jpg',
'./src/img/kaimo-003.png'
];

// 生成精灵表
Spritesmith.run({
src: sprites
}, function handleResult(err,) {
// 如果有错误,抛出它
if (err) {
throw err;
}
console.log("result---->", result)
// 输出图片
fs.mkdir('./dist', { recursive: true }, function(err) {
if (err) throw err;
console.log("目录创建成功");
// 使用 fs.writeFileSync 将数据同步写入文件
fs.writeFileSync(path.join(__dirname + '/dist/sprite.png'), result.image);
console.log("输出图片完毕");
});
});

然后执行 ​​node test.js​

webpack原理篇(六十二):实战开发一个自动合成雪碧图的loader_css_07


然后可以看到 dist 目录生成了一个 ​​sprite.png​​ 图片

webpack原理篇(六十二):实战开发一个自动合成雪碧图的loader_webpack_08

5、编写 sprite-loader

实现需要安装 ​​loader-runner​

npm i loader-runner

安装好之后添加 ​​run-loader.js​​ 文件

const fs = require("fs");
const path = require("path");
const { runLoaders } = require("loader-runner");

runLoaders(
{
resource: "./loaders/index.css",
loaders: [
path.resolve(__dirname, "./loaders/sprite-loader.js")
],
context: {
minimize: true
},
readResource: fs.readFile.bind(fs),
},
(err,) => {
err ? console.error(err) : console.log(result)
}
);

然后在 loaders 文件夹添加图片跟 css 文件

.kaimo-bg-1 {
background: url(./img/kaimo-001.png?__sprite);
}
.kaimo-bg-2 {
background: url(./img/kaimo-002.jpg?__sprite);
}
.kaimo-bg-3 {
background: url(./img/kaimo-003.png);
}

webpack原理篇(六十二):实战开发一个自动合成雪碧图的loader_数据同步_09

最后在 loaders 文件里添加 ​​sprite-loader.js​​ 文件

const Spritesmith = require('spritesmith');
const fs = require('fs');
const path = require('path');

module.exports = function(source) {
const callback = this.async();
console.log("source---->", source)
// 配置所有需要合图的
const imgs = source.match(/url\((\S*)\?__sprite/g);
console.log("imgs-->", imgs)
const sprites = [];

// 遍历生成需要合图的图片路径
for(let i = 0; i < imgs.length; i++) {
const img = imgs[i].match(/url\((\S*)\?__sprite/)[1];
console.log('img---->', img)
sprites.push(path.join(__dirname, img));
}
console.log("sprites---->", sprites)

// 生成精灵表
Spritesmith.run({
src: sprites
}, function handleResult(err,) {
// 如果有错误,抛出它
if (err) {
throw err;
}
console.log("result---->", result)
// 输出图片到 dist 文件夹
fs.mkdir(path.join(process.cwd() + '/dist'), { recursive: true }, function(err) {
if (err) throw err;
console.log("目录创建成功");
// 使用 fs.writeFileSync 将数据同步写入文件
fs.writeFileSync(path.join(process.cwd(), 'dist/sprite.jpg'), result.image);
console.log("图片输出完毕");
// 然后替换 css 里的图片路径为雪碧图的路径
source = source.replace(/url\((\S*)\?__sprite/g, (match) => {
return `url("dist/sprite.jpg"`;
})
callback(null, source);
fs.writeFileSync(path.join(process.cwd(), 'dist/index.css'), source);
console.log("样式替换完毕");
});
});
}

6、测试 sprite-loader.js 效果

运行命令 ​​node run-loader.js​​,输出如下

webpack原理篇(六十二):实战开发一个自动合成雪碧图的loader_webpack_10


webpack原理篇(六十二):实战开发一个自动合成雪碧图的loader_css_11


然后我们查看一下 dist 目录,我们发现加了 ​​__sprite​​ 的样式被替换了

webpack原理篇(六十二):实战开发一个自动合成雪碧图的loader_雪碧图_12


并且输出的 ​​sprite.jpg​​ 图片也是,只合成了加了的

webpack原理篇(六十二):实战开发一个自动合成雪碧图的loader_webpack_13


举报

相关推荐

0 条评论