diff --git a/assets.json b/assets.json index c6940545..9ba746aa 100644 --- a/assets.json +++ b/assets.json @@ -1,3 +1,3 @@ { - "version": 1706549368176 + "version": 1706558057916 } \ No newline at end of file diff --git a/build/config/svgo.js b/build/config/svgo.js new file mode 100644 index 00000000..bdc5a9c0 --- /dev/null +++ b/build/config/svgo.js @@ -0,0 +1,63 @@ +/** + * @file Provides a custom configuration to optimize (but not minimize) + * individual SVG files. + * + * This configset will not work, as is, with spritesheets. + * You will need to remove the following plugins: + * + * - `cleanupIds` + * - `removeHiddenElems` + */ + +export default { + multipass: true, + js2svg: { + indent: 4, + pretty: true, + }, + plugins: [ + 'cleanupAttrs', + 'cleanupEnableBackground', + 'cleanupIds', + 'cleanupListOfValues', + 'cleanupNumericValues', + 'collapseGroups', + 'convertColors', + 'convertEllipseToCircle', + 'convertPathData', + 'convertShapeToPath', + 'convertStyleToAttrs', + 'convertTransform', + 'inlineStyles', + 'mergePaths', + 'mergeStyles', + 'minifyStyles', + 'moveElemsAttrsToGroup', + 'moveGroupAttrsToElems', + 'removeComments', + 'removeDesc', + 'removeDimensions', + 'removeDoctype', + 'removeEditorsNSData', + 'removeEmptyAttrs', + 'removeEmptyContainers', + 'removeEmptyText', + 'removeHiddenElems', + 'removeMetadata', + 'removeNonInheritableGroupAttrs', + 'removeRasterImages', + 'removeScriptElement', + 'removeStyleElement', + 'removeTitle', + 'removeUnknownsAndDefaults', + 'removeUnusedNS', + 'removeUselessDefs', + 'removeUselessStrokeAndFill', + 'removeViewBox', + // 'removeXMLNS', + // 'removeXMLProcInst', + // 'reusePaths', + // 'sortAttrs', + 'sortDefsChildren', + ], +}; diff --git a/build/helpers/svgo.js b/build/helpers/svgo.js new file mode 100644 index 00000000..4e68432e --- /dev/null +++ b/build/helpers/svgo.js @@ -0,0 +1,26 @@ +/** + * @file If available, returns the SVGO API. + */ + +let createContentItem, extendDefaultPlugins, loadConfig, optimize; + +try { + let svgo = await import('svgo'); + + ({ + createContentItem, + extendDefaultPlugins, + loadConfig, + optimize + } = svgo.default); +} catch (err) { + // do nothing +} + +export default optimize; +export { + createContentItem, + extendDefaultPlugins, + loadConfig, + optimize +}; diff --git a/build/tasks/svgs.js b/build/tasks/svgs.js index 86cc420d..6ad69685 100644 --- a/build/tasks/svgs.js +++ b/build/tasks/svgs.js @@ -1,6 +1,8 @@ +import defaultSVGOOptions from '../config/svgo.js'; import loconfig from '../helpers/config.js'; import message from '../helpers/message.js'; import notification from '../helpers/notification.js'; +import optimize from '../helpers/svgo.js'; import resolve from '../helpers/template.js'; import { merge } from '../utils/index.js'; import { basename } from 'node:path'; @@ -20,25 +22,48 @@ export const developmentMixerOptions = Object.assign({}, defaultMixerOptions); export const productionMixerOptions = Object.assign({}, defaultMixerOptions); /** - * @const {object} developmentSVGsArgs - The predefined `compileSVGs()` options for development. - * @const {object} productionSVGsArgs - The predefined `compileSVGs()` options for production. + * Exclude certain SVGO plugins for the purposes of building a spritesheet. + */ +const excludeSVGOPlugins = [ + 'cleanupIds', + 'removeHiddenElems', +]; +defaultSVGOOptions.plugins = defaultSVGOOptions.plugins.filter((plugin) => !excludeSVGOPlugins.includes(plugin)); +defaultSVGOOptions.js2svg.pretty = false; + +/** + * @const {object} defaultSVGOOptions - The default shared SVGO options. + * @const {object} developmentSVGOOptions - The predefined SVGO options for development. + * @const {object} productionSVGOOptions - The predefined SVGO options for production. + */ +export { defaultSVGOOptions }; +export const developmentSVGOOptions = Object.assign({}, defaultSVGOOptions); +export const productionSVGOOptions = Object.assign({}, defaultSVGOOptions); + +/** + * @const {object|boolean} developmentSVGsArgs - The predefined `compileSVGs()` options for development. + * @const {object|boolean} productionSVGsArgs - The predefined `compileSVGs()` options for production. */ export const developmentSVGsArgs = [ developmentMixerOptions, + false, ]; export const productionSVGsArgs = [ productionMixerOptions, + productionSVGOOptions, ]; /** * Generates and transforms SVG spritesheets. * * @async - * @param {object} [mixerOptions=null] - Customize the Mixer API options. + * @param {object} [mixerOptions=null] - Customize the Mixer API options. + * If `null`, default production options are used. + * @param {object|boolean} [svgoOptions=null] - Customize the SVGO processor API options. * If `null`, default production options are used. * @return {Promise} */ -export default async function compileSVGs(mixerOptions = null) { +export default async function compileSVGs(mixerOptions = null, svgoOptions = null) { if (mixerOptions == null) { mixerOptions = productionMixerOptions; } else if ( @@ -48,6 +73,18 @@ export default async function compileSVGs(mixerOptions = null) { mixerOptions = merge({}, defaultMixerOptions, mixerOptions); } + if (optimize) { + if (svgoOptions == null) { + svgoOptions = productionSVGOOptions; + } else if ( + svgoOptions !== false && + svgoOptions !== developmentSVGOOptions && + svgoOptions !== productionSVGOOptions + ) { + svgoOptions = Object.assign({}, defaultSVGOOptions, svgoOptions); + } + } + /** * @async * @param {object} entry - The entrypoint to process. @@ -79,6 +116,10 @@ export default async function compileSVGs(mixerOptions = null) { const result = await mixer(includes, mixerOptions); + if (optimize && svgoOptions) { + result.content = optimize(result.content, svgoOptions).data; + } + await result.write(outfile); message(`${label} compiled`, 'success', timeLabel); diff --git a/docs/development.md b/docs/development.md index 5cb7b117..a772360c 100644 --- a/docs/development.md +++ b/docs/development.md @@ -49,6 +49,9 @@ npm start # Compile and minify assets npm run build + +# Optimize individual SVG files +npm run optimize:svg -- -f ./assets/images ./assets/images ``` See [`build.js`](../build/build.js) and [`watch.js`](../build/watch.js) @@ -306,7 +309,7 @@ See the [documentation on our Grid System](grid.md#build-tasks) for details. ### `svgs` -A wrapper around [SVG Mixer] for transforming and minifying SVG files +A wrapper around [SVG Mixer] and [SVGO] for transforming and minifying SVG files and generating spritesheets. Example: @@ -429,4 +432,5 @@ See [`versions.js`](../build/tasks/versions.js) for details. [PurgeCSS]: https://purgecss.com/ [RegExp]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp [SVG Mixer]: https://npmjs.com/package/svg-mixer +[SVGO]: https://npmjs.com/package/svgo [tiny-glob]: https://npmjs.com/package/tiny-glob diff --git a/package-lock.json b/package-lock.json index 23d6e8d3..c6595af9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -25,6 +25,7 @@ "purgecss": "^5.0.0", "sass": "^1.70.0", "svg-mixer": "~2.3.14", + "svgo": "^3.2.0", "tiny-glob": "^0.2.9" }, "engines": { @@ -411,6 +412,15 @@ "resolved": "https://registry.npmjs.org/@studio-freight/lenis/-/lenis-1.0.29.tgz", "integrity": "sha512-z/qS8ato5m2wlxQREYj5iALcxMrhhm06vEiLqYzLI+3HmpPzPscmJ8cXNiay4bj692vOot2hyTA3WP++AQVoKA==" }, + "node_modules/@trysound/sax": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz", + "integrity": "sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==", + "dev": true, + "engines": { + "node": ">=10.13.0" + } + }, "node_modules/@types/cookie": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.4.1.tgz", @@ -702,6 +712,12 @@ "node": ">=8" } }, + "node_modules/boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", + "dev": true + }, "node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -1355,6 +1371,114 @@ "node": ">= 0.10" } }, + "node_modules/css-select": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz", + "integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==", + "dev": true, + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^6.1.0", + "domhandler": "^5.0.2", + "domutils": "^3.0.1", + "nth-check": "^2.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/css-select/node_modules/dom-serializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", + "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", + "dev": true, + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "entities": "^4.2.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/css-select/node_modules/domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ] + }, + "node_modules/css-select/node_modules/domhandler": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", + "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", + "dev": true, + "dependencies": { + "domelementtype": "^2.3.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/css-select/node_modules/domutils": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz", + "integrity": "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==", + "dev": true, + "dependencies": { + "dom-serializer": "^2.0.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/css-select/node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "dev": true, + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/css-tree": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz", + "integrity": "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==", + "dev": true, + "dependencies": { + "mdn-data": "2.0.30", + "source-map-js": "^1.0.1" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0" + } + }, + "node_modules/css-what": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", + "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==", + "dev": true, + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, "node_modules/cssesc": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", @@ -1367,6 +1491,39 @@ "node": ">=4" } }, + "node_modules/csso": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/csso/-/csso-5.0.5.tgz", + "integrity": "sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==", + "dev": true, + "dependencies": { + "css-tree": "~2.2.0" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/csso/node_modules/css-tree": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.2.1.tgz", + "integrity": "sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==", + "dev": true, + "dependencies": { + "mdn-data": "2.0.28", + "source-map-js": "^1.0.1" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/csso/node_modules/mdn-data": { + "version": "2.0.28", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.28.tgz", + "integrity": "sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==", + "dev": true + }, "node_modules/debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", @@ -2721,6 +2878,12 @@ "node": ">=0.10.0" } }, + "node_modules/mdn-data": { + "version": "2.0.30", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz", + "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==", + "dev": true + }, "node_modules/memory-fs": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz", @@ -3026,6 +3189,18 @@ "resolved": "https://registry.npmjs.org/normalize.css/-/normalize.css-8.0.1.tgz", "integrity": "sha512-qizSNPO93t1YUuUhP22btGOo3chcvDFqFaj2TRybP0DMxkHOCTYwp3n34fel4a31ORXy4m1Xq0Gyqpb5m33qIg==" }, + "node_modules/nth-check": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", + "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", + "dev": true, + "dependencies": { + "boolbase": "^1.0.0" + }, + "funding": { + "url": "https://github.com/fb55/nth-check?sponsor=1" + } + }, "node_modules/object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", @@ -4519,6 +4694,40 @@ "node": ">=0.8.0" } }, + "node_modules/svgo": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/svgo/-/svgo-3.2.0.tgz", + "integrity": "sha512-4PP6CMW/V7l/GmKRKzsLR8xxjdHTV4IMvhTnpuHwwBazSIlw5W/5SmPjN8Dwyt7lKbSJrRDgp4t9ph0HgChFBQ==", + "dev": true, + "dependencies": { + "@trysound/sax": "0.2.0", + "commander": "^7.2.0", + "css-select": "^5.1.0", + "css-tree": "^2.3.1", + "css-what": "^6.1.0", + "csso": "^5.0.5", + "picocolors": "^1.0.0" + }, + "bin": { + "svgo": "bin/svgo" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/svgo" + } + }, + "node_modules/svgo/node_modules/commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "dev": true, + "engines": { + "node": ">= 10" + } + }, "node_modules/tiny-glob": { "version": "0.2.9", "resolved": "https://registry.npmjs.org/tiny-glob/-/tiny-glob-0.2.9.tgz", @@ -5103,6 +5312,12 @@ "resolved": "https://registry.npmjs.org/@studio-freight/lenis/-/lenis-1.0.29.tgz", "integrity": "sha512-z/qS8ato5m2wlxQREYj5iALcxMrhhm06vEiLqYzLI+3HmpPzPscmJ8cXNiay4bj692vOot2hyTA3WP++AQVoKA==" }, + "@trysound/sax": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz", + "integrity": "sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==", + "dev": true + }, "@types/cookie": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.4.1.tgz", @@ -5315,6 +5530,12 @@ "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", "dev": true }, + "boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", + "dev": true + }, "brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -5815,12 +6036,113 @@ "vary": "^1" } }, + "css-select": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz", + "integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==", + "dev": true, + "requires": { + "boolbase": "^1.0.0", + "css-what": "^6.1.0", + "domhandler": "^5.0.2", + "domutils": "^3.0.1", + "nth-check": "^2.0.1" + }, + "dependencies": { + "dom-serializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", + "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", + "dev": true, + "requires": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "entities": "^4.2.0" + } + }, + "domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", + "dev": true + }, + "domhandler": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", + "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", + "dev": true, + "requires": { + "domelementtype": "^2.3.0" + } + }, + "domutils": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz", + "integrity": "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==", + "dev": true, + "requires": { + "dom-serializer": "^2.0.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3" + } + }, + "entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "dev": true + } + } + }, + "css-tree": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz", + "integrity": "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==", + "dev": true, + "requires": { + "mdn-data": "2.0.30", + "source-map-js": "^1.0.1" + } + }, + "css-what": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", + "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==", + "dev": true + }, "cssesc": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", "dev": true }, + "csso": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/csso/-/csso-5.0.5.tgz", + "integrity": "sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==", + "dev": true, + "requires": { + "css-tree": "~2.2.0" + }, + "dependencies": { + "css-tree": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.2.1.tgz", + "integrity": "sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==", + "dev": true, + "requires": { + "mdn-data": "2.0.28", + "source-map-js": "^1.0.1" + } + }, + "mdn-data": { + "version": "2.0.28", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.28.tgz", + "integrity": "sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==", + "dev": true + } + } + }, "debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", @@ -6897,6 +7219,12 @@ "object-visit": "^1.0.0" } }, + "mdn-data": { + "version": "2.0.30", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz", + "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==", + "dev": true + }, "memory-fs": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz", @@ -7131,6 +7459,15 @@ "resolved": "https://registry.npmjs.org/normalize.css/-/normalize.css-8.0.1.tgz", "integrity": "sha512-qizSNPO93t1YUuUhP22btGOo3chcvDFqFaj2TRybP0DMxkHOCTYwp3n34fel4a31ORXy4m1Xq0Gyqpb5m33qIg==" }, + "nth-check": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", + "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", + "dev": true, + "requires": { + "boolbase": "^1.0.0" + } + }, "object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", @@ -8335,6 +8672,29 @@ "resolved": "https://registry.npmjs.org/svg4everybody/-/svg4everybody-2.1.9.tgz", "integrity": "sha1-W9n23vwTOFmgRGRtR0P6vCjbfi0=" }, + "svgo": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/svgo/-/svgo-3.2.0.tgz", + "integrity": "sha512-4PP6CMW/V7l/GmKRKzsLR8xxjdHTV4IMvhTnpuHwwBazSIlw5W/5SmPjN8Dwyt7lKbSJrRDgp4t9ph0HgChFBQ==", + "dev": true, + "requires": { + "@trysound/sax": "0.2.0", + "commander": "^7.2.0", + "css-select": "^5.1.0", + "css-tree": "^2.3.1", + "css-what": "^6.1.0", + "csso": "^5.0.5", + "picocolors": "^1.0.0" + }, + "dependencies": { + "commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "dev": true + } + } + }, "tiny-glob": { "version": "0.2.9", "resolved": "https://registry.npmjs.org/tiny-glob/-/tiny-glob-0.2.9.tgz", diff --git a/package.json b/package.json index 41be5c30..237b4db3 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,8 @@ }, "scripts": { "start": "node --experimental-json-modules --no-warnings build/watch.js", - "build": "node --experimental-json-modules --no-warnings build/build.js" + "build": "node --experimental-json-modules --no-warnings build/build.js", + "optimize:svg": "svgo --config=build/config/svgo.js" }, "dependencies": { "locomotive-scroll": "^5.0.0-beta.11", @@ -31,6 +32,7 @@ "purgecss": "^5.0.0", "sass": "^1.70.0", "svg-mixer": "~2.3.14", + "svgo": "^3.2.0", "tiny-glob": "^0.2.9" }, "overrides": { diff --git a/www/assets/images/sprite.svg b/www/assets/images/sprite.svg index 23ac934d..ba19b4e1 100644 --- a/www/assets/images/sprite.svg +++ b/www/assets/images/sprite.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file