kuzivany / rollup-plugin-svgi

Import SVG files as JSX components
MIT License
4 stars 1 forks source link
javascript jsx preact react rollup rollup-plugin svg

rollup-plugin-svgi

npm@latest dependencies

Import SVG files as JSX components.

Purpose

This is a Rollup plugin for importing SVG as components in Preact, React and other libraries.

Installation

Get started by installing rollup-plugin-svgi from your terminal with your preferred package manager:

npm

npm install rollup-plugin-svgi --save-dev

yarn

yarn add rollup-plugin-svgi -D

Usage

// rollup.config.js
import svgi from 'rollup-plugin-svgi';

const config = {/* ... */};

export default {
  entry: 'main.js',
  plugins: [
    svgi(config)
  ]
}

Configuration

The config object passed to the plugin is composed of the following properties:

Property Description Default
options The options object undefined
options.jsx The JSX library or module name to use e.g. "preact" or "react" (required) undefined
options.factory The JSX pragma—the function used for compiling each JSX node e.g. preact.h or React.createElement undefined
options.default Whether or not the options.factory is the default export of the provided options.jsx library.
If false, the provided options.jsx will be a named export
true
options.clean The function used to clean up/ prepare the SVG for inlining. It removes the DOCTYPE, XML declaration, comments and namespaced attributes and has a (rawSVG) => string or (rawSVG) => Promise<string> function signature function
exclude Minimatch pattern(s) to exclude.
More at rollupjs.org.
undefined
include Minimatch pattern(s) to include.
More at rollupjs.org.
"**/*.svg"

Examples

Here are some complete rollup.config.js and starter project examples for:

Basic example

// main.js
import { h } from 'preact'; // OR import React from 'react';
import Logo from 'path/to/logo.svg';

export default () => (
  <div class="App">
    <div class="App-header">
      <Logo class="App-logo" />
    </div>
  </div>
);
// rollup.config.js
import svgi from 'rollup-plugin-svgi';

export default {
  entry: 'main.js',
  // ...
  plugins: [
    svgi({
      options: {
        jsx: 'preact', // Your chosen JSX library
      },
    }),
  ]
}

Advanced examples

Specifying a library
// rollup.config.js
import svgi from 'rollup-plugin-svgi';

export default {
  entry: 'main.js',
  plugins: [
    svgi({
      options: {
        jsx: 'inferno-create-element',
        factory: 'createElement',
        'default': false // import { createElement } from 'inferno-create-element';
      },
    }),
  ]
}

See full library example here

Using SVGO

options.clean allows you to specify a custom function to remove any unnecessary elements in your SVG files.

SVGO can be used through options.clean to optimise your SVG files:

// rollup.config.js
import svgi from 'rollup-plugin-svgi';
import SVGO from 'svgo';

export default {
  entry: 'main.js',
  plugins: [
    svgi({
      options: {
        jsx: 'react',
        clean: rawSVG => (
          new SVGO({
            plugins: [
              {removeDoctype: true},
              {removeXMLNS: true},
              {removeComments: true},
              {removeViewBox: false},
            ]
          }).optimize(rawSVG).then(optzSvg => optzSvg.data)
        )
      }
    })
  ]
}

Full SVGO example here

Internals

SVG files are imported as functional components which accept props. An example logo.svg file:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<!-- Generated by hand -->
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="100%" height="100%" version="1.1" viewBox="-50 -50 100 100">
  <circle cx="0" cy="0" fill="red" r="25"/>
</svg>

imported in a javascript file:

import Logo from 'path/to/logo.svg';

makes this available in your code:

const Logo = props => (
  <svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%" version="1.1" viewBox="-50 -50 100 100" {...props}>
    <circle cx="0" cy="0" fill="red" r="25"/>
  </svg>
)