From 2130b1057df0ccc13bed90c7007b9e74cf6c19b5 Mon Sep 17 00:00:00 2001 From: Andrey Nikonov Date: Sat, 23 Apr 2022 17:52:05 +0300 Subject: [PATCH] Add SVG sprite inline in HTML, amend README --- .eleventy.js | 11 ++++++++ README.md | 50 +++++++++++++++++++------------------ gulp-tasks/svg.js | 15 +++++++++-- gulpfile.js | 10 ++++---- package.json | 11 +++++--- src/_layouts/base.njk | 1 + src/index.njk | 10 ++++---- src/js/utils/svg-sprites.js | 16 ------------ 8 files changed, 68 insertions(+), 56 deletions(-) delete mode 100644 src/js/utils/svg-sprites.js diff --git a/.eleventy.js b/.eleventy.js index 82839fa..9a329cc 100644 --- a/.eleventy.js +++ b/.eleventy.js @@ -3,6 +3,7 @@ const { RemoteAssetCache } = require('@11ty/eleventy-cache-assets'); const sizeOf = require('image-size'); const generateImageHTML = require('./generate-image-html'); +const fs = require('fs'); function imageShortcode(src, attributes = {}, maxWidth = 2636) { console.log('src', src); @@ -63,6 +64,15 @@ function imageShortcode(src, attributes = {}, maxWidth = 2636) { return generateImageHTML(metadata, imageAttributes); } +function inlineSvgSprite() { + try { + return fs.readFileSync('./dist/svg/sprite.svg', 'utf8'); + } catch (error) { + console.warn("SVG Sprite file doesn't exist"); + } + return ''; +} + module.exports = (eleventyConfig) => { eleventyConfig.addPassthroughCopy({ 'src/public': '/' }); @@ -77,6 +87,7 @@ module.exports = (eleventyConfig) => { }); eleventyConfig.addNunjucksShortcode('image', imageShortcode); + eleventyConfig.addNunjucksShortcode('svg_sprite', inlineSvgSprite); return { dir: { diff --git a/README.md b/README.md index c4d2537..7f22147 100755 --- a/README.md +++ b/README.md @@ -7,32 +7,18 @@ This is a production-ready starter that features Nunjucks, SASS, TailwindCSS (wi 11ty is responsible for building HTML only, the rest is built with Gulp. -Can be used in conjunction with any data source either a headless CMS, JSON, markdown, or any other data source that has a JS API. Please see [11ty documentation](https://www.11ty.dev/docs/data/) on data source matter +Can be used in conjunction with any data source either a headless CMS, JSON, markdown, or any other data source that has a possibility to fetch data using JavaScript. Please see [11ty documentation](https://www.11ty.dev/docs/data/) on data source matter. ## Getting started #### 1. Install dependencies: -With `yarn` - -``` -yarn install -``` - -or with `npm`: - ``` npm install ``` #### 2. Run the project for development: -``` -yarn start -``` - -or - ``` npm start ``` @@ -44,19 +30,19 @@ npm start #### Running the project for development: ``` -yarn start +npm start ``` #### Build the project for production: ``` -yarn build +npm run build ``` #### Creating a production-ready zip-archive `build.zip`: ``` -yarn zip +npm run zip ``` ## Folder Structure @@ -85,21 +71,29 @@ This starter features Webpack v5 for building JS bundle. ## Customize static path -This template allows you to customize static path to project resources such as images, scripts, styles, etc. Add an `.env` file to the root directory of the project with the following content `STATIC_PATH=http://localhost:9000` and use _STATIC_PATH_ like `` +This template allows you to customize static path of project resources such as images, scripts, styles, etc. Add an `.env` file to the root directory of the project with the following content `STATIC_PATH=http://localhost:9000` and use _STATIC_PATH_ like `` **Keep mind:** To use _STATIC_PATH_ in macros, it must be passed as props ## The SVG sprite -It is possible to automatically keep your SVG files for the project inside a single SVG sprite with the [gulp-svgstore](https://github.com/w0rm/gulp-svgstore) plugin. So that it's better to add SVG files to the project in the following way: +It is possible to store SVG files inside a single SVG sprite. The starter uses the [gulp-svgstore](https://github.com/w0rm/gulp-svgstore) plugin to generate a sprite. SVG sprites technique is the recommended approach for adding vector images to the project. + +The SVG sprite markup is inlined in `base.njk` template using `{% svg_prite %}` shortcode function (there is no need to modify this code). + +To display an SVG image on the page, first add if to the `src/svg` folder. Let's suppose that this file would have the name `some-vector.svg`. + +Then add it to the page in the following way: ``` - + ``` -Keep in mind that, in doing so, the SVG file `some-vector-image.svg` should be located in the `src/svg` directory. You can also set, for example, `fill` or `stroke` for this element on the page by using CSS selectors (so without setting them inside the SVG file). +**Keep mind:** `some-vector.svg` file should be located in the `src/svg` directory so that `gulp-svgstore` could add it to the SVG sprite. + +You can also set, for example, `fill` or `stroke` for this element on the page by using CSS selectors (so without setting them inside the SVG file). It is also possible to animate SVG element parts (like ``, ``, etc). -See examples in the index.njk +You can also take a look at the `` examples in the index.njk. ## {% image %} Nunjucks tag @@ -107,7 +101,7 @@ This tag allows generating AVIF and WebP images. It also creates srcset sizes au ## Inlining raster or svg images into HTML -Attention! The files, which should be inlined, have to seat in the `src/images/inline` directory. +Attention! The files, which should be inlined, have to be placed into the `src/images/inline` folder. ### Inlining raster or svg images in CSS @@ -131,12 +125,20 @@ height: height('some-image.png') background-size: size('some-image.png') ``` +Attention! Please use this feature with caution as it may bloat the final `CSS` file. Inlining images could be a good approach if the file is quite small, in other cases prefer `{% image %}` tag. + ### Inlining images inside Nunjucks templates ``` Some image ``` +Attention! Please use this feature with caution as it may bloat the final `HTML` file. Inlining images could be a good approach if the file is quite small, in other cases prefer `{% image %}` tag. + ## Useful links [Nunjucks syntax](https://mozilla.github.io/nunjucks/templating.html). + +[TailwindCSS](https://tailwindcss.com/) + +[TailwindCSS Cheatsheet](https://nerdcave.com/tailwind-cheat-sheet) diff --git a/gulp-tasks/svg.js b/gulp-tasks/svg.js index 8e8645a..f7329a9 100644 --- a/gulp-tasks/svg.js +++ b/gulp-tasks/svg.js @@ -1,8 +1,10 @@ +const path = require('path'); + const gulp = require('gulp'); const rename = require('gulp-rename'); const svgstore = require('gulp-svgstore'); const svgmin = require('gulp-svgmin'); -const path = require('path'); +const cheerio = require('gulp-cheerio'); const PATHS = require('../paths'); @@ -22,7 +24,7 @@ module.exports = function svg() { }, { cleanupIDs: { - prefix: prefix + '-', + prefix: `${prefix}-`, minify: true, }, }, @@ -32,6 +34,15 @@ module.exports = function svg() { ) .pipe(rename({ prefix: 'icon-' })) .pipe(svgstore({ inlineSvg: true })) + .pipe( + cheerio({ + // eslint-disable-next-line id-length + run: ($) => { + $('svg').attr('style', 'display:none'); + }, + parserOptions: { xmlMode: true }, + }) + ) .pipe(rename('sprite.svg')) .pipe(gulp.dest(PATHS.build.svg)); }; diff --git a/gulpfile.js b/gulpfile.js index a8a4dda..948147b 100755 --- a/gulpfile.js +++ b/gulpfile.js @@ -1,18 +1,18 @@ const gulp = require('gulp'); -const styles = require('./gulp-tasks/styles'); +const scss = require('./gulp-tasks/styles'); const tailwind = require('./gulp-tasks/tailwind'); const svg = require('./gulp-tasks/svg'); const zip = require('./gulp-tasks/zip'); const watch = require('./gulp-tasks/watch'); // const w3cValidator = require('./gulp-tasks/w3c-validator'); -gulp.task('build', gulp.parallel(styles, tailwind, svg)); +gulp.task('svg', svg); -gulp.task('production', gulp.series('build')); +gulp.task('styles', gulp.parallel(scss, tailwind)); -gulp.task('zip', gulp.series('production', zip)); +gulp.task('zip', zip); // gulp.task('w3c-validator', w3cValidator); -gulp.task('default', gulp.parallel('build', watch)); +gulp.task('default', gulp.parallel(svg, 'styles', watch)); diff --git a/package.json b/package.json index 271794c..9d307fe 100644 --- a/package.json +++ b/package.json @@ -3,16 +3,18 @@ "version": "1.0.0", "description": "", "scripts": { - "start": "npm-run-all clean -p dev:*", + "start": "npm-run-all clean gulp:svg -p dev:*", + "gulp:svg": "gulp svg", + "gulp:styles": "gulp styles", "dev:gulp": "gulp&", "dev:eleventy": "node ./scripts/eleventy-dev.js", "dev:webpack": "webpack --watch", - "build": "cross-env NODE_ENV=production npm-run-all clean build-webpack -p build:* && npm run beautify-html", + "build": "cross-env NODE_ENV=production npm-run-all -s clean gulp:svg build-webpack build-eleventy gulp:styles beautify-html", "build:gulp": "gulp production", - "build:eleventy": "eleventy", + "build-eleventy": "eleventy", "build-webpack": "webpack", "clean": "rimraf dist/", - "zip": "cross-env NODE_ENV=production gulp zip", + "zip": "cross-env NODE_ENV=production npm run build && gulp zip", "format": "pretty-quick --staged", "lint:css": "stylelint --fix \"src/**/*.{scss,sass}\"", "lint:js": "eslint --max-warnings 0 \"src/**/*.{jsx,js}\"", @@ -54,6 +56,7 @@ "eslint-plugin-unicorn": "^28.0.2", "fancy-log": "^1.3.3", "gulp": "^4.0.2", + "gulp-cheerio": "^1.0.0", "gulp-clean-css": "^4.3.0", "gulp-dart-sass": "^1.0.2", "gulp-if": "^3.0.0", diff --git a/src/_layouts/base.njk b/src/_layouts/base.njk index fe06b5a..f3827a1 100644 --- a/src/_layouts/base.njk +++ b/src/_layouts/base.njk @@ -12,6 +12,7 @@ {% endblock stylesheets %} + {% svg_sprite %} {% block content %}{% endblock content %} diff --git a/src/index.njk b/src/index.njk index 37c4737..952515f 100644 --- a/src/index.njk +++ b/src/index.njk @@ -59,9 +59,9 @@

An image inlined in the CSS example (compress such images manually!)

-

- Attention! Please use this feature with caution as it may bloat the - final css file! +

+ Attention! Please use this feature with caution as it may bloat the + final CSS file. Inlining images could be a good approach if the file is quite small, in other cases prefer `{% image %}` tag.

@@ -70,7 +70,7 @@ Vector image example (using SVG sprite) - +
@@ -87,7 +87,7 @@
- +
diff --git a/src/js/utils/svg-sprites.js b/src/js/utils/svg-sprites.js deleted file mode 100644 index 02b3bdb..0000000 --- a/src/js/utils/svg-sprites.js +++ /dev/null @@ -1,16 +0,0 @@ -(function (doc) { - const scripts = doc.getElementsByTagName('script'); - const script = scripts[scripts.length - 1]; - const xhr = new XMLHttpRequest(); - xhr.onload = function () { - const div = doc.createElement('div'); - div.innerHTML = this.responseText; - div.style.display = 'none'; - if (!script || !script.parentNode) { - return; - } - script.parentNode.insertBefore(div, script); - }; - xhr.open('get', 'svg/sprite.svg', true); - xhr.send(); -})(document);