├── index.js ├── .gitignore ├── .npmignore ├── .eslintrc ├── .travis.yml ├── package.json ├── README.md ├── LICENSE └── gatsby-node.js /index.js: -------------------------------------------------------------------------------- 1 | // noop 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .npm 3 | .eslintcache 4 | logs 5 | *.log 6 | npm-debug.log* 7 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | package-lock.json 3 | .eslintrc 4 | .eslintcache 5 | .travis.yml 6 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "parser": "babel-eslint", 3 | "extends": "airbnb-base", 4 | "rules": { 5 | "arrow-parens": ["error", "as-needed"] 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - 10 4 | - "node" 5 | script: 6 | - npm install 7 | - npm run lint 8 | cache: 9 | directories: 10 | - node_modules 11 | notifications: 12 | email: 13 | on_success: never 14 | on_failure: always 15 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "gatsby-plugin-optimize-svgs", 3 | "version": "1.0.5", 4 | "description": "A Gatsby Plugin to minify SVGs output to the filesystem during the build.", 5 | "main": "index.js", 6 | "scripts": { 7 | "lint": "eslint --cache --ext .js ." 8 | }, 9 | "repository": "https://github.com/vzhou842/gatsby-plugin-optimize-svgs", 10 | "author": "Victor Zhou ", 11 | "license": "MIT", 12 | "keywords": [ 13 | "gatsby", 14 | "gatsby-plugin", 15 | "svg", 16 | "minify", 17 | "optimize" 18 | ], 19 | "dependencies": { 20 | "svgo": "^1.3.2", 21 | "walk": "^2.3.14" 22 | }, 23 | "devDependencies": { 24 | "babel-eslint": "^10.0.2", 25 | "eslint": "^6.1.0", 26 | "eslint-config-airbnb-base": "^13.2.0", 27 | "eslint-plugin-import": "^2.18.2" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # gatsby-plugin-optimize-svgs 2 | 3 | [![Build Status](https://travis-ci.com/vzhou842/gatsby-plugin-optimize-svgs.svg?branch=master)](https://travis-ci.com/vzhou842/gatsby-plugin-optimize-svgs) 4 | 5 | A [Gatsby](https://www.gatsbyjs.org/) Plugin to minify SVGs output to the filesystem during the build. Uses [svgo](https://github.com/svg/svgo) under the hood to minify SVGs. 6 | 7 | Read the [blog post](https://victorzhou.com/blog/minify-svgs/) on minifying SVGs for some more context. 8 | 9 | ## Usage 10 | 11 | Install: 12 | 13 | ``` 14 | $ npm install gatsby-plugin-optimize-svgs 15 | ``` 16 | 17 | Add to `gatsby-config.js`: 18 | 19 | ```js 20 | module.exports = { 21 | plugins: [ 22 | 'gatsby-plugin-optimize-svgs', 23 | ], 24 | }; 25 | ``` 26 | 27 | ## Example Output 28 | 29 | ``` 30 | 59 SVGs minified, reducing the total size from 447780 bytes to 208237 bytes, a reduction of 53.5%! 31 | ``` 32 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Victor Zhou 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /gatsby-node.js: -------------------------------------------------------------------------------- 1 | const SVGO = require('svgo'); 2 | const fs = require('fs'); 3 | const walk = require('walk'); 4 | const process = require('process'); 5 | const path = require('path'); 6 | 7 | const svgo = new SVGO({ 8 | plugins: [{ removeViewBox: false }], 9 | }); 10 | const cwd = process.cwd(); 11 | 12 | // Resolves with [beforeSize, afterSize] 13 | const optimizeSVG = async svgPath => new Promise((resolve, reject) => { 14 | const fullPath = path.join(cwd, svgPath); 15 | fs.readFile(fullPath, 'utf8', (readErr, data) => { 16 | if (readErr) { 17 | reject(readErr); 18 | return; 19 | } 20 | 21 | svgo.optimize(data) 22 | .then(({ data: result }) => { 23 | fs.writeFile(fullPath, result, 'utf8', writeErr => { 24 | if (writeErr) { 25 | reject(writeErr); 26 | } else { 27 | resolve([data.length, result.length]); 28 | } 29 | }); 30 | }) 31 | .catch(reject); 32 | }); 33 | }); 34 | 35 | exports.onPostBuild = async ({ reporter }) => new Promise((resolve, reject) => { 36 | const walker = walk.walk('public'); 37 | 38 | let allSVGs = []; 39 | 40 | walker.on('names', (root, names) => { 41 | // Add any SVG filepaths found to allSVGs 42 | allSVGs = allSVGs.concat( 43 | names.filter(n => n.substring(n.length - 4) === '.svg') 44 | .map(n => path.join(root, n)), 45 | ); 46 | }); 47 | 48 | walker.on('errors', reject); 49 | 50 | walker.on('end', async () => { 51 | if (allSVGs.length === 0) { 52 | // Print a warning if no SVGs were found 53 | reporter.warn('gatsby-plugin-optimize-svgs: No SVGs found to optimize!'); 54 | } else { 55 | // Calculate and print some stats 56 | const stats = await Promise.all(allSVGs.map(optimizeSVG)); 57 | const [beforeSize, afterSize] = stats.reduce(([a, b], [c, d]) => [a + c, b + d], [0, 0]); 58 | 59 | reporter.success( 60 | `${stats.length} SVGs minified, reducing the total size from ${beforeSize} bytes to ${afterSize} bytes, a reduction of ${(100 * (beforeSize - afterSize) / beforeSize).toFixed(1)}%!`, 61 | ); 62 | } 63 | resolve(); 64 | }); 65 | }); 66 | --------------------------------------------------------------------------------