From f9f6990beaf152453b9ff36d5792cf191ffa66f3 Mon Sep 17 00:00:00 2001 From: Jordan Eldredge Date: Sun, 8 Jan 2023 16:16:55 -0800 Subject: [PATCH] Switch to postcss to use uri optimization plugin --- packages/webamp/postcss.config.js | 3 ++ .../scripts/postcss-optimize-data-uri-pngs.js | 37 +++++++++++++++++++ .../postcss-optimize-data-uri-pngs.test.js | 11 ++++++ 3 files changed, 51 insertions(+) create mode 100644 packages/webamp/postcss.config.js create mode 100644 packages/webamp/scripts/postcss-optimize-data-uri-pngs.js create mode 100644 packages/webamp/scripts/postcss-optimize-data-uri-pngs.test.js diff --git a/packages/webamp/postcss.config.js b/packages/webamp/postcss.config.js new file mode 100644 index 0000000000..b46b91a30c --- /dev/null +++ b/packages/webamp/postcss.config.js @@ -0,0 +1,3 @@ +module.exports = { + plugins: [require("./scripts/postcss-optimize-data-uri-pngs")], +}; diff --git a/packages/webamp/scripts/postcss-optimize-data-uri-pngs.js b/packages/webamp/scripts/postcss-optimize-data-uri-pngs.js new file mode 100644 index 0000000000..94e00d2a58 --- /dev/null +++ b/packages/webamp/scripts/postcss-optimize-data-uri-pngs.js @@ -0,0 +1,37 @@ +const postcss = require("postcss"); +const dataUriToBuffer = require("data-uri-to-buffer"); +const imagemin = require("imagemin"); +const imageminOptipng = require("imagemin-optipng"); + +const DATA_URL_REGEX = new RegExp(/url\((data:image\/png;base64,.+)\)/gi); +const DATA_URL_PROPS_REGEX = /^(background(?:-image)?)|(content)|(cursor)/; + +async function optimizeDataUri(dataUri) { + const buffer = dataUriToBuffer(dataUri); + const optimized = await imagemin.buffer(buffer, { + use: [imageminOptipng()], + }); + return `data:image/png;base64,${optimized.toString("base64")}`; +} + +module.exports = postcss.plugin("postcss-optimize-data-uri-pngs", () => { + return async function (css) { + // walkDecls does not let us work async, so we collect the async work we + // need to do here, and await it at the end + const promisesFactories = []; + css.walkDecls(DATA_URL_PROPS_REGEX, (decl) => { + let matches; + // WTF JavaScript. This is the worst API for iterating RegEx matches. + while ((matches = DATA_URL_REGEX.exec(decl.value))) { + const [, dataUri] = matches; + promisesFactories.push(async () => { + decl.value = decl.value.replace( + dataUri, + await optimizeDataUri(dataUri) + ); + }); + } + }); + await Promise.all(promisesFactories.map((p) => p())); + }; +}); diff --git a/packages/webamp/scripts/postcss-optimize-data-uri-pngs.test.js b/packages/webamp/scripts/postcss-optimize-data-uri-pngs.test.js new file mode 100644 index 0000000000..f2e1dbf06b --- /dev/null +++ b/packages/webamp/scripts/postcss-optimize-data-uri-pngs.test.js @@ -0,0 +1,11 @@ +const fs = require("fs"); +const postcss = require("postcss"); + +const plugin = require("./postcss-optimize-data-uri-pngs"); + +const css = fs.readFileSync("./css/base-skin.css", "utf8"); +// This seems to timeout a lot in CI +it.skip("does something", async () => { + const result = await postcss([plugin({})]).process(css); + expect(result.css.length).toBeLessThan(css.length); +});