From be1289693fb3afe8ac99b6f587ccbaacda600774 Mon Sep 17 00:00:00 2001 From: Paulo Ferreira Date: Fri, 22 May 2020 16:23:45 -0300 Subject: [PATCH] Add support for SVG sprite (#46) --- app/src/WordPress/AssetsServiceProvider.php | 27 +++++++++++++++++++++ composer.json | 2 +- package.json | 1 + resources/build/lib/utils.js | 5 ++-- resources/build/spritesvg.js | 12 +++++++++ resources/build/webpack.development.js | 17 +++++++++++++ resources/build/webpack.production.js | 18 ++++++++++++++ resources/images/sprite-svg/.gitkeep | 0 resources/scripts/frontend/index.js | 1 + resources/scripts/frontend/spritesvg.js | 4 +++ 10 files changed, 84 insertions(+), 3 deletions(-) create mode 100644 resources/build/spritesvg.js create mode 100644 resources/images/sprite-svg/.gitkeep create mode 100644 resources/scripts/frontend/spritesvg.js diff --git a/app/src/WordPress/AssetsServiceProvider.php b/app/src/WordPress/AssetsServiceProvider.php index da5344b..0456c35 100644 --- a/app/src/WordPress/AssetsServiceProvider.php +++ b/app/src/WordPress/AssetsServiceProvider.php @@ -30,6 +30,8 @@ public function bootstrap( $container ) { add_action( 'admin_head', [$this, 'addFavicon'], 5 ); add_action( 'upload_dir', [$this, 'fixUploadDirUrlSchema'] ); + + add_action( 'wp_footer', [$this, 'loadSvgSprite'] ); } /** @@ -161,4 +163,29 @@ public function fixUploadDirUrlSchema( $upload_dir ) { return $upload_dir; } + + /** + * Load SVG sprite. + * + * @return void + */ + public function loadSvgSprite() { + $file_path = implode( + DIRECTORY_SEPARATOR, + array_filter( + [ + get_template_directory(), + 'dist', + 'images', + 'sprite.svg' + ] + ) + ); + + if ( ! file_exists( $file_path ) ) { + return; + } + + readfile( $file_path ); + } } diff --git a/composer.json b/composer.json index 12cd49f..6bedce2 100644 --- a/composer.json +++ b/composer.json @@ -28,7 +28,7 @@ }, "require-dev": { "filp/whoops": "^2.2", - "htmlburger/wpemerge-cli": "~0.15.0", + "htmlburger/wpemerge-cli": "~0.15.1", "symfony/debug": "~3.0", "wp-coding-standards/wpcs": "^2.0", "dealerdirect/phpcodesniffer-composer-installer": "^0.5.0" diff --git a/package.json b/package.json index a5771ca..fd789d5 100644 --- a/package.json +++ b/package.json @@ -50,6 +50,7 @@ "postcss-loader": "^3.0.0", "sass-loader": "^8.0.2", "style-loader": "^1.2.1", + "svg-sprite-loader": "^4.2.5", "webpack": "^4.26.1", "webpack-cli": "^3.1.2", "webpack-manifest-plugin": "^2.0.4", diff --git a/resources/build/lib/utils.js b/resources/build/lib/utils.js index 3604dfd..777480f 100644 --- a/resources/build/lib/utils.js +++ b/resources/build/lib/utils.js @@ -53,8 +53,9 @@ module.exports.distFontsPath = destPath => module.exports.tests = { scripts: /\.(js|jsx)$/, styles: /\.(css|scss|sass)$/, - images: /(resources|dist|node_modules)[\\/].*\.(ico|jpg|jpeg|png|svg|gif)$/, - fonts: /(resources|dist|node_modules)[\\/].*\.(eot|svg|ttf|woff|woff2)$/, + spriteSvgs: /(resources|dist|node_modules)[\\/]images[\\/]sprite-svg[\\/].*\.svg$/, + images: /(resources|dist|node_modules)[\\/](?!images[\\/]sprite-svg).*\.(ico|jpg|jpeg|png|svg|gif)$/, + fonts: /(resources|dist|node_modules)[\\/](?!images[\\/]sprite-svg).*\.(eot|svg|ttf|woff|woff2)$/, }; module.exports.detectEnv = () => { diff --git a/resources/build/spritesvg.js b/resources/build/spritesvg.js new file mode 100644 index 0000000..d014e0c --- /dev/null +++ b/resources/build/spritesvg.js @@ -0,0 +1,12 @@ +/** + * The external dependencies. + */ +const SvgSpriteLoaderPlugin = require('svg-sprite-loader/plugin'); + +module.exports = new SvgSpriteLoaderPlugin({ + plainSprite: true, + spriteAttrs: { + 'aria-hidden': 'true', + style: 'display: none; visibility: hidden;', + }, +}); diff --git a/resources/build/webpack.development.js b/resources/build/webpack.development.js index ed20c03..fcdd4d2 100644 --- a/resources/build/webpack.development.js +++ b/resources/build/webpack.development.js @@ -14,6 +14,7 @@ const get = require('lodash/get'); const utils = require('./lib/utils'); const configLoader = require('./config-loader'); const spriteSmith = require('./spritesmith'); +const spriteSvg = require('./spritesvg'); const postcss = require('./postcss'); /** @@ -56,6 +57,7 @@ const plugins = [ jQuery: 'jquery', }), spriteSmith, + spriteSvg, new ManifestPlugin(), ]; @@ -153,6 +155,21 @@ module.exports = { ], }, + /** + * Handle SVG sprites. + */ + { + test: utils.tests.spriteSvgs, + use: [ + { + loader: 'svg-sprite-loader', + options: { + extract: false, + }, + }, + ], + }, + /** * Handle fonts. */ diff --git a/resources/build/webpack.production.js b/resources/build/webpack.production.js index 5b2249f..f1558e0 100644 --- a/resources/build/webpack.production.js +++ b/resources/build/webpack.production.js @@ -13,6 +13,7 @@ const ManifestPlugin = require('webpack-manifest-plugin'); const utils = require('./lib/utils'); const configLoader = require('./config-loader'); const spriteSmith = require('./spritesmith'); +const spriteSvg = require('./spritesvg'); const postcss = require('./postcss'); /** @@ -52,6 +53,7 @@ const plugins = [ filename: `styles/[name]${env.filenameSuffix}.css`, }), spriteSmith, + spriteSvg, new ImageminPlugin({ optipng: { optimizationLevel: 7, @@ -193,6 +195,22 @@ module.exports = { ], }, + /** + * Handle SVG sprites. + */ + { + test: utils.tests.spriteSvgs, + use: [ + { + loader: 'svg-sprite-loader', + options: { + extract: true, + spriteFilename: 'images/sprite.svg', + }, + }, + ], + }, + /** * Handle fonts. */ diff --git a/resources/images/sprite-svg/.gitkeep b/resources/images/sprite-svg/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/resources/scripts/frontend/index.js b/resources/scripts/frontend/index.js index 97ad60f..c30857e 100644 --- a/resources/scripts/frontend/index.js +++ b/resources/scripts/frontend/index.js @@ -4,5 +4,6 @@ import './vendor/*.js'; import '@styles/frontend'; import '@images/favicon.ico'; import 'airbnb-browser-shims'; +import './spritesvg'; // Your code goes here ... diff --git a/resources/scripts/frontend/spritesvg.js b/resources/scripts/frontend/spritesvg.js new file mode 100644 index 0000000..04f9101 --- /dev/null +++ b/resources/scripts/frontend/spritesvg.js @@ -0,0 +1,4 @@ +const icons = require.context('@images/sprite-svg', true, /\.svg$/); + +// Automatically load all SVG files in the sprite-svg directory. +icons.keys().forEach(filename => icons(filename));