Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update SVG optimization workflow #1215

Merged
merged 6 commits into from
Aug 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,16 @@ jobs:

- name: Lint
run: npm run lint

- name: Optimize SVGs
run: |
npm run optimize-svgs
if git diff --quiet; then
echo "All SVGs are optimized ✔︎"
else
echo "The following SVGs are not optimized:"
git diff --name-only
echo
echo "Please run 'npm run optimize-svgs' and commit the changes"
exit 1
fi
10 changes: 10 additions & 0 deletions bin/__tests__/__snapshots__/optimize-svg.test.js.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`optimizes SVG correctly 1`] = `"<svg xmlns=\\"http://www.w3.org/2000/svg\\" width=\\"24\\" height=\\"24\\" viewBox=\\"0 0 24 24\\" fill=\\"none\\" stroke=\\"currentColor\\" stroke-width=\\"2\\" stroke-linecap=\\"round\\" stroke-linejoin=\\"round\\"><line x1=\\"23\\" y1=\\"1\\" x2=\\"1\\" y2=\\"23\\"/><line x1=\\"1\\" y1=\\"1\\" x2=\\"23\\" y2=\\"23\\"/></svg>"`;

exports[`rejects when passed unparsable SVG string 1`] = `
[Error: Error in parsing SVG: Unclosed root tag
Line: 0
Column: 10
Char: ]
`;
26 changes: 0 additions & 26 deletions bin/__tests__/__snapshots__/process-svg.test.js.snap

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
/* eslint-env jest */
import processSvg from '../process-svg';
import optimizeSvg from '../optimize-svg';

test('processes SVG correctly', () => {
test('optimizes SVG correctly', () => {
const SVG =
'<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><title>Title</title><line x1="23" y1="1" x2="1" y2="23" fill="none" stroke="#000" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/><line x1="1" y1="1" x2="23" y2="23" fill="none" stroke="#000" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/></svg>';

expect(processSvg(SVG)).resolves.toMatchSnapshot();
expect(optimizeSvg(SVG)).resolves.toMatchSnapshot();
});

test('rejects when passed unparsable SVG string', () => {
const UNPARSABLE_SVG = '<svg></svg';

expect(processSvg(UNPARSABLE_SVG)).rejects.toMatchSnapshot();
expect(optimizeSvg(UNPARSABLE_SVG)).rejects.toMatchSnapshot();
});
3 changes: 0 additions & 3 deletions bin/build.sh
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
#!/bin/bash

# Process SVG files
# npx babel-node bin/process-svgs.js

# Create dist directory
npx rimraf dist
mkdir dist
Expand Down
24 changes: 8 additions & 16 deletions bin/process-svg.js → bin/optimize-svg.js
Original file line number Diff line number Diff line change
@@ -1,32 +1,24 @@
import Svgo from 'svgo';
import cheerio from 'cheerio';
import { format } from 'prettier';

import DEFAULT_ATTRS from '../src/default-attrs.json';

/**
* Process SVG string.
* Optimize SVG string.
* @param {string} svg - An SVG string.
* @returns {Promise<string>}
*/
function processSvg(svg) {
return (
optimize(svg)
.then(setAttrs)
.then(format)
// remove semicolon inserted by prettier
// because prettier thinks it's formatting JSX not HTML
.then(svg => svg.replace(/;/g, ''))
);
function optimizeSvg(svg) {
return svgo(svg).then(setAttrs);
}

/**
* Optimize SVG with `svgo`.
* Run SVGO on SVG string.
* @param {string} svg - An SVG string.
* @returns {Promise<string>}
*/
function optimize(svg) {
const svgo = new Svgo({
function svgo(svg) {
const s = new Svgo({
plugins: [
{ convertShapeToPath: false },
{ mergePaths: false },
Expand All @@ -36,7 +28,7 @@ function optimize(svg) {
});

return new Promise(resolve => {
svgo.optimize(svg, ({ data }) => resolve(data));
s.optimize(svg, ({ data }) => resolve(data));
});
}

Expand All @@ -55,4 +47,4 @@ function setAttrs(svg) {
return $('body').html();
}

export default processSvg;
export default optimizeSvg;
6 changes: 3 additions & 3 deletions bin/process-svgs.js → bin/optimize-svgs.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
import fs from 'fs';
import path from 'path';

import processSvg from './process-svg';
import optimizeSvg from './optimize-svg';

const IN_DIR = path.resolve(__dirname, '../icons');

console.log(`Processing SVGs in ${IN_DIR}...`);
console.log(`Optimizing SVGs in ${IN_DIR}...`);

fs.readdirSync(IN_DIR)
.filter(file => path.extname(file) === '.svg')
.forEach(svgFile => {
const svg = fs.readFileSync(path.join(IN_DIR, svgFile));
processSvg(svg).then(svg =>
optimizeSvg(svg).then(svg =>
fs.writeFileSync(path.join(IN_DIR, svgFile), svg),
);
});
14 changes: 1 addition & 13 deletions icons/activity.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
15 changes: 1 addition & 14 deletions icons/airplay.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
16 changes: 1 addition & 15 deletions icons/alert-circle.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
16 changes: 1 addition & 15 deletions icons/alert-octagon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
16 changes: 1 addition & 15 deletions icons/alert-triangle.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
17 changes: 1 addition & 16 deletions icons/align-center.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
17 changes: 1 addition & 16 deletions icons/align-justify.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
17 changes: 1 addition & 16 deletions icons/align-left.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
17 changes: 1 addition & 16 deletions icons/align-right.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
16 changes: 1 addition & 15 deletions icons/anchor.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
20 changes: 1 addition & 19 deletions icons/aperture.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
16 changes: 1 addition & 15 deletions icons/archive.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
16 changes: 1 addition & 15 deletions icons/arrow-down-circle.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading