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

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

说明

玩转 webpack 学习笔记



支持的语法

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

a5f3917f8bb5499680cd78de7de7eca2.png

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


使用 spritesmith

https://github.com/twolfson/spritesmith

c791fdb8a495471487f0e0ddfc32197b.png


spritesmith 使用示例

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


实战开发


1、新建初始化项目

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

npm init -y


48d74ae3222742afa9b1d74055fd31b5.png


2、添加图片资源

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


e10d2202968b42dcac659b36492f8081.png



3、安装依赖

npm i spritesmith


3b8b1496e86a4e289aac3f5d78c62858.png



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, result) {
    // 如果有错误,抛出它
    if (err) {
        throw err;
    }
    console.log("result---->", result)
});


我们执行 node test.js


b4e3a3c31c1046479684d2a7d6fd3cb3.png


如果你报 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, result) {
    // 如果有错误,抛出它
    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

58f479c71a7d4cffa4bc4dc71000d131.png



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


424c5649535f46e2967f304d20e14148.png



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, result) => {
        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);
}


3ab0c07b7a7e45d49ae7f92ffddaa30d.png


最后在 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, result) {
        // 如果有错误,抛出它
        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,输出如下


dfbb370bd83b43b8b120e2241f6854d5.png


70d262febbca479dac1266566f2a1a0b.png


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

e2cc8f5dd7a446daa03deb0163750092.png


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

cd8ce9168b7e464d8407886e20e492ec.png








目录
相关文章
|
2月前
|
前端开发
在Webpack配置文件中,如何配置loader以处理其他类型的文件,如CSS或图片
在Webpack配置文件中,通过设置`module.rules`来配置loader处理不同类型的文件。例如,使用`css-loader`和`style-loader`处理CSS文件,使用`file-loader`或`url-loader`处理图片等资源文件。配置示例:在`rules`数组中添加对应规则,指定`test`匹配文件类型,`use`指定使用的loader。
|
2月前
|
前端开发 JavaScript
webpack 中 loader 和 plugin 的区别
在 webpack 中,loader 用于转换模块的源代码,如将 TypeScript 转为 JavaScript;而 plugin 则扩展了 webpack 的功能,可以执行更复杂的任务,如优化打包文件、注入环境变量等。两者共同作用于构建流程的不同阶段。
|
2月前
|
JavaScript 前端开发
Webpack中loader的使用场景
Webpack中的Loader用于处理和转换模块文件,如将TypeScript转为JavaScript、CSS预处理等,通过配置不同的Loader,可以灵活地支持多种文件类型和语言,实现模块化开发与构建优化。
|
2月前
|
监控 前端开发 JavaScript
Webpack 中 HMR 插件的工作原理
【10月更文挑战第23天】可以进一步深入探讨 HMR 工作原理的具体细节、不同场景下的应用案例,以及与其他相关技术的结合应用等方面的内容。通过全面、系统地了解 HMR 插件的工作原理,能够更好地利用这一功能,为项目的成功开发提供有力保障。同时,要不断关注技术的发展动态,以便及时掌握最新的 HMR 技术和最佳实践。
|
2月前
|
缓存 前端开发 JavaScript
Webpack 动态加载的原理
【10月更文挑战第23天】Webpack 动态加载通过巧妙的机制和策略,实现了模块的按需加载和高效运行,提升了应用程序的性能和用户体验。同时,它也为前端开发提供了更大的灵活性和可扩展性,适应了不断变化的业务需求和技术发展。
|
2月前
|
缓存 前端开发 JavaScript
webpack 原理
【10月更文挑战第23天】Webpack 原理是一个复杂但又非常重要的体系。它通过模块解析、依赖管理、加载器和插件的协作,实现了对各种模块的高效打包和处理,为现代前端项目的开发和部署提供了强大的支持。同时,通过代码分割、按需加载、热模块替换等功能,提升了应用程序的性能和用户体验。随着前端技术的不断发展,Webpack 也在不断演进和完善,以适应不断变化的需求和挑战。
|
3月前
|
缓存 前端开发 JavaScript
Webpack 打包的基本原理
【10月更文挑战第5天】
|
3月前
|
前端开发 UED
Webpack 中处理 CSS 和图片资源的多 Loader 配置
【10月更文挑战第12天】 处理 CSS 和图片资源是 Webpack 配置中的重要部分。通过合理选择和配置多个 Loader,可以实现对这些资源的精细处理和优化,提升项目的性能和用户体验。在实际应用中,需要不断探索和实践,根据项目的具体情况进行灵活调整和优化,以达到最佳的处理效果。通过对 Webpack 中多 Loader 处理 CSS 和图片资源的深入了解和掌握,你将能够更好地应对各种复杂的资源处理需求,为项目的成功构建和运行提供坚实的基础。
91 1
|
3月前
|
前端开发 JavaScript
Webpack 中多个 Loader 的配置
【10月更文挑战第12天】使用多个 Loader 进行配置是 Webpack 中常见的操作,可以实现对各种资源的精细处理和优化。在配置时,需要根据具体需求合理选择和排列 Loader,并注意它们之间的顺序和交互关系。同时,不断了解和掌握新的 Loader 以及它们的特性,有助于更好地发挥 Webpack 的强大功能,提升项目的开发效率和质量。通过深入理解和熟练运用多个 Loader 的配置方法,你将能够更加灵活地处理各种资源,满足项目的多样化需求。
86 2
|
3月前
|
前端开发 JavaScript
Webpack 常用 Loader 和 Plugin
【10月更文挑战第12天】Webpack 是一个强大的模块打包工具,能够将各种资源模块进行打包和处理。Loader 用于转换模块的源代码,如 `babel-loader` 将 ES6+ 代码转换为 ES5,`css-loader` 处理 CSS 文件等。Plugin 扩展 Webpack 功能,如 `HtmlWebpackPlugin` 自动生成 HTML 文件,`UglifyJsPlugin` 压缩 JavaScript 代码。通过合理配置和使用 Loader 和 Plugin,可以构建高效、优化的项目。
32 2