首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >craco 中的图片处理

craco 中的图片处理

原创
作者头像
kmokidd
发布2019-07-31 21:07:26
1.6K0
发布2019-07-31 21:07:26
举报

使用 craco 覆盖框架默认的 webpack 配置

从前我以为 HTTP/2 开启以后,雪碧图可以逐渐退出舞台,现在感觉到自己的天真。且不论 svg 如果做成雪碧图可以通过 gzip 受益不少,多个单张的 png 还是比起一张要浪费请求。

  1. 雪碧图 使用插件 webpack-spritesmith,该插件的原理是,监听目标文件夹中的图片变化,根据开发者设定的规则,生成对应的雪碧图和样式。 我们的项目有 2x 和 3x 的图片,需要生成两张雪碧图和两份 css 文件。思路:将 2x 和 3x 资源分开放,写两套规则来生成两组文件。 生成雪碧图还有另一种原理,是反过来的,找到样式文件中用到图片,再合成雪碧图,比如 postcss-sprite,如果是使用大量图片资源的项目,建议使用这种方法,不容易产生冗余代码和图片。
// craco.config.js

const SpritesmithPlugin = require("webpack-spritesmith");
...

const templateFunction = function(data) {
  const ratio = data.sprites[0].name.split("@")[1].split("x")[0] || 1;

  // 2x 配置
  let shared = ".ico { display: inline-block; background-image: url(I); background-size: Dpx Hpx; }"
    .replace("I", data.sprites[0].image)
    .replace("D", data.sprites[0].total_width / ratio)
    .replace("H", data.sprites[0].total_height / ratio);

  let perSprite = data.sprites
    .map(function(sprite) {
      let name = sprite.name.split("@")[0].replace(/_/g, "-");
      return ".ico-N { width: Wpx; height: Hpx; background-position: Xpx Ypx; }"
        .replace("N", name)
        .replace("W", sprite.width / ratio)
        .replace("H", sprite.height / ratio)
        .replace("X", sprite.offset_x / ratio)
        .replace("Y", sprite.offset_y / ratio);
    })
    .join("\n");

  // mq 配置
  let result = {
    x2: `${shared}\n${perSprite}\n`, // 默认使用 2x
    x3: `@media only screen and (-o-min-device-pixel-ratio: 9/4),
          only screen and (-webkit-min-device-pixel-ratio: 2.25),
          only screen and (min-device-pixel-ratio: 2.25),
          only screen and (min-resolution: 2.25dppx) {\n${shared}\n${perSprite}\n}`
  };

  if (ratio != 3) {
    return result.x2;
  } else {
    return result.x3;
  }
};

...

// 注!以下配置大部分来自 https://www.chauncywu.com/?p=232
// 两套配置有很多重复的地方,应该不少也能提成统一的变量
const webpack = {
  ...
	plugins: [
		new SpritesmithPlugin({
      src: {
        cwd: path.resolve(__dirname, "public/assets/slice/2x"), // 图标根路径
        glob: "*.png" // 图标类型
      },
      target: {
        image: path.resolve(
          __dirname,
          "src/styles/img/sprite2x.png"
        ), // 生成雪碧图的名称和路径
        css: [
          [
            path.resolve(
              __dirname,
              "src/styles/sprite2x.css"
            ),
            {
              // 生成CSS文件的名称和路径
              format: "function_based_template" // 模板配置,注意在customTemplates中配置对应名称的属性名
            }
          ],
          [
            path.resolve(
              __dirname,
              "src/styles/sprite2x.json"
            ),
            {
              // 生成json文件的名称和路径,想看图片数据的可以配置该项
              format: "json_texture"
            }
          ]
        ]
      },
      customTemplates: {
        function_based_template: templateFunction // 上一项使用到的模板变量
      },
      apiOptions: {
        cssImageRef: "./img/sprite2x.png" // 生成的CSS中引用的雪碧图路径
      },
      spritesmithOptions: {
        algorithm: "binary-tree", // 生成的雪碧图图标排列方式
        padding: 2 // 图标的间隔
      }
    }),
    new SpritesmithPlugin({
      src: {
        cwd: path.resolve(__dirname, "public/assets/slice/3x"), // 图标根路径
        glob: "*.png" // 图标类型
      },
      target: {
        image: path.resolve(
          __dirname,
          "src/styles/img/sprite3x.png"
        ), // 生成雪碧图的名称和路径
        css: [
          [
            path.resolve(
              __dirname,
              "src/styles/sprite3x.css"
            ),
            {
              // 生成CSS文件的名称和路径
              format: "function_based_template" // 模板配置,注意在customTemplates中配置对应名称的属性名
            }
          ],
          [
            path.resolve(
              __dirname,
              "src/styles/sprite3x.json"
            ),
            {
              // 生成json文件的名称和路径,想看图片数据的可以配置该项
              format: "json_texture"
            }
          ]
        ]
      },
      customTemplates: {
        function_based_template: templateFunction // 上一项使用到的模板变量
      },
      apiOptions: {
        cssImageRef: "./img/sprite3x.png" // 生成的CSS中引用的雪碧图路径
      },
      spritesmithOptions: {
        algorithm: "binary-tree", // 生成的雪碧图图标排列方式
        padding: 2 // 图标的间隔
      }
    }) 
  ]
}

// craco 的文件入口
module.exports = {
  ...
  webpack
};
  1. 图片压缩 未完
参考资料
  1. 基于Webpack的CSS Sprites实现方案
  2. webpack雪碧图生成
  3. Webpack3之雪碧图插件(WEBPACK-SPRITESMITH配置简述)
  4. add-stylelint/craco.config.js
  5. Media Queries for @2x, @3x, and @4x images

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 参考资料
相关产品与服务
图片处理
图片处理(Image Processing,IP)是由腾讯云数据万象提供的丰富的图片处理服务,广泛应用于腾讯内部各产品。支持对腾讯云对象存储 COS 或第三方源的图片进行处理,提供基础处理能力(图片裁剪、转格式、缩放、打水印等)、图片瘦身能力(Guetzli 压缩、AVIF 转码压缩)、盲水印版权保护能力,同时支持先进的图像 AI 功能(图像增强、图像标签、图像评分、图像修复、商品抠图等),满足多种业务场景下的图片处理需求。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档