npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

parcel-plugin-svg-sprite

v1.4.1

Published

Parcel plugin which generate a SVG sprite with <symbol> elements and inject it in built html

Downloads

126

Readme

SVG sprite parcel plugin

A parcel plugin which create a svg sprite of imported svg and inject it in html entry point.

warning : this plugin overwrite HTMLPackager, it can be in conflit with other plugin which also overwrite HTMLPackager.

Until version 1.1.2 files in an assets folder or subfolder wasn't injected in sprite to have the possibility to use svg files in css (css can't reference a svg symbol).
Since version 1.2.0 you can use options include and exclude to define path patterns you don't want to inject in sprite and import them as file url. This can be usefull to import svg font in css or to use svg file in css background-image.

Installation

yarn add -D parcel-plugin-svg-sprite

# or with npm

npm install -D parcel-plugin-svg-sprite

Exemple

Once the plugin is installed, you can import svg like this :

In html file :

...
<body>
  ...
  <!-- relative path from the html file -->
  <svg>
    <use href="icons/checkmark.svg">
  </svg>
  ...
</body>
...

In javascript file :

import checkmark from './icons/checkmark.svg';

const icon = `
<svg>
  <use xlink:href="${checkmark}" />
</svg>`;

Or with JSX :

import React from 'react';
import checkmark from './icons/checkmark.svg';

const icon = (
  <svg>
    <use xlinkHref={checkmark} />
  </svg>
);

When you import a svg, you get the id of the symbol generated in built sprite. This is why you can use it as xlink:href attribute.

HTML input example:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>
<body>
  <div id="app"></div>
  <script src="app.tsx"></script>
</body>
</html>

Generated HTML expected

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>
<body>
  <!-- Begin of svg sprite wrapper -->
  <svg width="0" height="0" style="position:absolute">
    <symbol id="generated_symbol_id_1" xmlns="http://www.w3.org/2000/svg">
      <!-- first imported svg file content -->
    </symbol>
    <symbol id="generated_symbol_id_2" xmlns="http://www.w3.org/2000/svg">
      <!-- second imported svg file content -->
    </symbol>
    ...
  </svg>
  <!-- End of svg sprite wrapper -->
  <div id="app"></div>
  <script src="app.tsx"></script>
</body>
</html>

Options :

This plugin has 2 options to give the possibility to handle specific cases.
There are 2 ways to set plugin options:

  • add an object svgSpriteOptions in package.json of the project
  • create svgSprite.config.js file which export an object at the root of your project.

options set in svgSprite.config.js overwrite options set in package.json

exclude string[]
List of glob patterns which should not be included in svg sprite and should be imported as file url (like Parcel's default behavior).
This can be usefull if you need to import file in css (for font or background-image).
example (to avoid inject files from assets folder in svg sprite):

// package.json
"name": "my-package-name",
...
"svgSpriteOptions": {
  "exclude": ["**/assets/**/*"]
}

include string[]
List of glob patterns which can be injected in svg sprite.
If the option isn't set all svg file which aren't exluded will be injected in svg sprite.
If a file path matches with both include and exclude options, the path will be excluded.
example:

// package.json
"name": "my-package-name",
...
"svgSpriteOptions": {
  "include": ["src/**/*"]
}

getSymbolId (filePath, fileContent, fileHash) => string (only in svgSprite.config.js)
Give the possibilty to define how svg symbol ids are generated. By default the svg id will be the hash of file content. exemple:

// svgSprite.config.js
const path = require('path');

module.exports = {
  getSymbolId: (filePath, fileContent, fileHash) => {
    return path.basename(filePath, '.svg');
  },
};

Advantages :

  • Unlike initial parcel behaviour which return an url, here you can apply css to customise the imported svg (for example the color, the stroke, ...)
  • Optimize the size of imported svg
  • Create a sprite to avoid several http requests
  • Inject sprite at compilation time instead of browser run time
  • Limit DOM manipulation by injected only symbol id instead of all svg nodes when the svg is injected in a page

Why inject SVG sprite in HTML instead of using an external file ?

Each time we inject an element <use xlink:href="file.svg#icon" /> in the DOM, a request is launch to get "file.svg". So the icon appear with a delay depending on http response time. If you have an animation when svg symbol is injected in DOM, the icon will appear in the middle of animation.

In which case this plugin is made for

This plugin was developped to create icon system based on svg. As long as you import little svg and the size of the sprite isn't too heavy, I think there isn't any problem (it depends on your case but in my opinion the sprite should not exceed 100kb). If you have to much icons, there is a risk to have a significantly bad impact on the delay of first render of your web app.

In which case I don't recommend this plugin

Like I said above, if you want to import a lot of svg files, or big illustrations, this plugin is not good for your case. You first render time can be too much delayed.

Improvement to make

  • code splitting : this plugin can generate a svg by bundle, but I didn't find a way to inject them at runtime. For the moment, all svg of all bundles are injected at compilation time in HTML entry point.