Why
- webpack配置下的react项目,目前自己没有找到一个好的插件可以快速生成精灵图
- 部分小图标会可以转base64合并入代码中,大图标却不方便转base64
- 公司的项目绝大多数使用环境是弱网,所以基于图片下载还是需要有所优化
使用模块
- free texture pack (npm 图片打包模块)
- glob (匹配文件用)
- commander (命令)
- styled-jsx (用于将样式写入的组件中)
- react
具体实现
-
初始化npm项目
npm init -y -
安装模块
npm i commander free-tex-packer-core glob -
实现基本打包功能
- 3.1 匹配到所有的文件
glob(path.join(__dirname,"**/*.png"), {}, (er, files) => { if (er){ throw error .... } })- 3.2 配置精灵图模块的参数
let options = { textureName: "my-texture", //文件名 fixedSize: false, padding: 2, // 精灵图片元素间距 allowRotation: false, //是否旋转 detectIdentical: true, allowTrim: false, //是否裁切 removeFileExtension: true, //删除文件后缀 prependFolderName: false, tinify:true, // 要不要压缩图片 tinifyKey:'', // tini 秘钥 packer: "MaxRectsPacker", // 图片生成的类型 exporter: { // 自定义导出 fileExt: "js", //导出文件后缀 template: path.join(__dirname,`./template.mst`), // 导出模板 }, };- 3.3 合成精灵图数据及精灵图内各图片数据信息
let images = files.map((item) => { return { path: item, contents: fs.readFileSync(item), }; }); texturePacker(images, options, (files, error) => { if (error) { console.error("Packaging failed", error); } else { for (let item of files) { <!--文件名 跟buffer数据--> console.log(item.name, item.buffer); } } });- 3.4 自定义模板文件(styled-jsx类型)
<!--style.js--> import css from 'styled-jsx/css' export default css.global` .icon-sprite{ background-size:{{config.imageWidth}}px {{config.imageHeight}}px; background-image: url({{config.imageName}}); background-repeat: no-repeat; display:inline-block; vertical-align: middle; } {{#rects}} .icon-{{name}}{ background-position: -{{frame.x}}px -{{frame.y}}px; width: {{frame.w}}px; height: {{frame.h}}px; } {{/rects}} `- 3.5 将3.3读取的buffer生成精灵图片及style js文件
<!--output 自定义的生成文件目录--> fs.writeFile(path.join(output,item.name), item.buffer, (err) => { if (err) throw err; console.log(item.name + "文件已被保存"); });- 3.6 生成的js文件的使用
import styles from './style.js'; interface iProps {} const Butn = () => { return <span className='icon-sprite icon-tab2'></span>; }; const App: FC<iProps> = () => { return ( <div> <div className='icon-sprite icon-header'></div> <div> <Butn /> </div> <div> <span className='icon-sprite icon-close'></span> </div> <style global jsx> {style} </style> </div> ); }; export default App;以上完成了一个基本的打包精灵图片的小功能,可是每次都跑到node项目里面去执行命令打包太麻烦了,所以需要建立一个简单的命令行可以在任何目录下进行操作
新建命令行
- 项目根目录 新建文件 bin/index.js
#!/usr/bin/env node var program = require('commander'); program.version('v' + require('../package.json').version) .description('Manipulate asar archive files') program.command('pack <dir> <output>') .alias('p') .description('create asar archive') .action(function (__dirpath, output) { console.log(output+"文件成功生成"); <!--执行打包代码--> }) program.parse(process.argv) if (program.args.length === 0) { program.help() }- package.json内添加命令
"bin": { "spr": "./bin/index.js" }- 链接命令到全局下 文件根目录下执行
npm link - 测试命令,找个有图片的目录执行
spr p ./ ../sprite/
测试命令过程,查找当前执行目录下的所有png文件进行打包图片精灵,在上层目录sprite将生成一个js文件跟一个图片文件,这里就可以自己引入到react的组件里面直接使用了