Giter VIP home page Giter VIP logo

svg-inline-loader's Introduction

npm deps test coverage chat

! NO LONGER MAINTAINED !

This module is deprecated and will no longer be maintained.

In most cases, you can replace the functionality by using raw-loader and image-minimizer-webpack-plugin instead:

webpack.config.js

const ImageMinimizerPlugin = require('image-minimizer-webpack-plugin');

module.exports = {
  module: {
    rules: [
      {
        test: /\.svg$/,
        use: [
          {
            loader: "raw-loader"
          }
        ]
      },
    ],
  },
  plugins: [
    new ImageMinimizerPlugin({
      minimizerOptions: {
        plugins: [
          [
            'imagemin-svgo',
            {
              plugins: [
                // SVGO options is here "https://github.com/svg/svgo#what-it-can-do"
                {
                  removeViewBox: false,
                  removeXMLNS: true,
                },
              ],
            },
          ],
        ],
      },
    }),
  ],
};

For optimization svg use imagemin-svgo.

SVG Inline Loader for Webpack

This Webpack loader inlines SVG as module. If you use Adobe suite or Sketch to export SVGs, you will get auto-generated, unneeded crusts. This loader removes it for you, too.

Install

npm install svg-inline-loader --save-dev

Configuration

Simply add configuration object to module.loaders like this.

    {
        test: /\.svg$/,
        loader: 'svg-inline-loader'
    }

warning: You should configure this loader only once via module.loaders or require('!...'). See #15 for detail.

Query Options

removeTags: boolean

Removes specified tags and its children. You can specify tags by setting removingTags query array.

default: removeTags: false

removingTags: [...string]

warning: this won't work unless you specify removeTags: true

default: removingTags: ['title', 'desc', 'defs', 'style']

warnTags: [...string]

warns about tags, ex: ['desc', 'defs', 'style']

default: warnTags: []

removeSVGTagAttrs: boolean

Removes width and height attributes from <svg />.

default: removeSVGTagAttrs: true

removingTagAttrs: [...string]

Removes attributes from inside the <svg />.

default: removingTagAttrs: []

warnTagAttrs: [...string]

Warns to console about attributes from inside the <svg />.

default: warnTagAttrs: []

classPrefix: boolean || string

Adds a prefix to class names to avoid collision across svg files.

default: classPrefix: false

idPrefix: boolean || string

Adds a prefix to ids to avoid collision across svg files.

default: idPrefix: false

Example Usage

// Using default hashed prefix (__[hash:base64:7]__)
var logoTwo = require('svg-inline-loader?classPrefix!./logo_two.svg');

// Using custom string
var logoOne = require('svg-inline-loader?classPrefix=my-prefix-!./logo_one.svg');

// Using custom string and hash
var logoThree = require('svg-inline-loader?classPrefix=__prefix-[sha512:hash:hex:5]__!./logo_three.svg');

See loader-utils for hash options.

Preferred usage is via a module.loaders:

    {
        test: /\.svg$/,
        loader: 'svg-inline-loader?classPrefix'
    }

Maintainers


Juho Vepsäläinen

Joshua Wiens

Kees Kluskens

Sean Larkin

svg-inline-loader's People

Contributors

agerard-godaddy avatar cap-bernardito avatar iernie avatar jhnns avatar joshwiens avatar nonmanifold avatar noxan avatar p3drosola avatar randak avatar rondonjon avatar stuk avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

svg-inline-loader's Issues

webpack-defaults upgrade

Addition of webpack-defaults & associated refactoring as a part of the next Major release

Issue exists for status tracking across the organization.

Please do not close

self-closing tags broken during output generation

Version 0.2.0 uses simple-html-tokenizer to parse and re-generate the svg contents.

This module seems to generate HTML4 output und not XML-compatible output.

Two independent elements <svg><rect ... /><circle ... /></svg> are then treated as if they contained each other in browser like Chrome and Firefox:

<svg><rect><circle></svg> is treated as if the <rect> was a parent (!) of the <circle>, and that is not valid according to SVG syntax, so the elements are completely removed from the display area.

Weird result using <img src="image.svg"> in HTML

Hi,

while using your loader, I am struggling with weird issue, which prevents me from using it.
I am using Webpack v.2.2.1.

In HTML I've got:
<img src="../../icons/font-awesome/svg/arrow_down.svg" alt="test_svg">

And after compiling and bundling, using your loader, it ends up like this:

<img src="&lt;svg xmlns=" http:="" www.w3.org="" 2000="" svg"="" viewbox="0 0 1664 1792">
<path d="M1611 832q0 53-37 90l-651 652q-39 37-91 37-53 0-90-37l-651-652q-38-36-38-90 0-53 38-91l74-75q39-37 91-37 53 0 90 37l294 294v-704q0-52 38-90t90-38h128q52 0 90 38t38 90v704l294-294q37-37 90-37 52 0 91 37l75 75q37 39 37 91z"></path>
" alt="test_svg">

And in my webpack config, options for this plugin:

{
  loader: 'svg-inline-loader',
  options: {
    mimetype: 'image/svg+xml',
    removeTags: false,
    removingTags: ['title', 'desc', 'defs', 'style'],
    removeSVGTagAttrs: false,
    removingTagAttrs: [],
    classPrefix: 'icon',
    idPrefix: 'icon-[name]',
  },
},

Fails to add prefix for class names using characters escaping (with backslash)

In CSS, it is possible to escape characters to use them in class name. For example if you want a class name that starts with a digit, say "1st", it is totally valid to escape it, ending with a CSS selector .\31 st (notice the space inside a selector that only indicates the end of escaping sequence). Then you can use it normally, as <div class="1st" />. The same applies to SVG, and it happens for example when SVG files are being exported from Adobe Illustrator with "unique classnames" option.

The loader fails to add a prefix to selector in <style> segment if it contains backslash, ending with an unstyled elements in SVG.

Can't inline SVG in stylesheets

There's a problem with using this loader in that it makes in impossible to load SVGs in stylesheets.

Would it be possible to change the output format to Data URI for certain file types? I'm thinking something similar to this approach.

.input {
  background-image: url('path/file.svg')
}

.output {
  /* current output ... this won't work */
  background-image: url('<svg>...</svg>');

  /* but something like this might work*/
  background-image: url('data:image/svg+xml;utf8,%3Csvg...');
}

inline styles?

I have a few svgs and they have the same classes .cls-1 and/or .cls-2. They overwrite each other's style. If they could be auto inlined that would be great!

<defs>
  <style>
    .cls-1 {
      fill: #3d5a98;
    }

    .cls-2 {
      fill: #fff;
    }
  </style>
</defs>

Better parser

simple-html-tokenizer has some problem. First of all, it does not understand HTML and SVG namespace and elements correctly (which makes us to expand self-closing tag manually via regex)

Secondly, it just gives array of parsed tag sequence rather than structured object. This makes code quite verbose (which I did not realize at first use)

simple-html-tokenizer is pretty fast and lightweight but we need parser with better output.

Add an option "auto add class name from svg file name".

Automatically add class name to <svg> tag from its svg file name.

What does the proposed API look like?

A file named logo.svg :

<svg class="foo" viewBox="0 0 25 25">
    <path d="..."/>
</svg>

The options :

  {
    test: /\.svg$/,
    loader: 'svg-inline-loader',
    options: {
      className: 'icon-[filename]',
      // or
      // classPrefix: 'icon-',
      // autoClassName: true
    }
  }

The expected output result :

<svg class="icon-logo" viewBox="0 0 25 25"><path d="..."/></svg>

Preserve <style>

One of the reason removeTags query option created was mainly due to Adobe Photoshop's SVG output. It puts .cls-<n> classes to each <g /> element and puts style in <def /> tag. When inlining SVG, <style /> becomes global-level style declaration and pollutes other style.

So idea is, just turn its <n /> to random hash...like .cls-<random hash>. But as far as this module is about just SVG I will definitely not add CSS parser so its use can be a bit limited.

removingTags not respected in loader config

It seems that specifying 'removingTags' in the loader config in my webpack.config.js file is having no effect. Looking at the code, it appears that the isRemovingTag function only looks at defaultConfig and not any passed-in config.

Is that intentional or a bug?

Move below webpack-contrib?

Hi,

I was wondering if you would be interested in moving the repository below webpack-contrib. It's an organization where we maintain third party loaders/plugins together. Let me know.

SVG rect broken

The following RegExp breaks <rect> tags because it removes their width and height attributes!

                 .replace(/width="\d+(\.\d+)?(px)?"/gi, "")
                 .replace(/height="\d+(\.\d+)?(px)?"/gi, "")

Webpack@2 support

I wonder if you know how webpack@2 support could be added, seems like it's erroring due to loader-utils not being available:

ERROR in ./~/icons/warning.svg
Module build failed: (SystemJS) ENOENT: no such file or directory, open '/Users/karolis/overview-ui/loader-utils'

Missing 'idPrefix' in config.js

The 'idPrefix' default option is missing in config.js. And you will get id="undefined<ID>" in result.
Just add one string to easily fix it.

  ...
  classPrefix: false,
  idPrefix: false
};

One set of Quotation marks coming extra

One set of Quotation marks coming extra on html, when i am using in react, see the below code
{require('!svg-inline-loader!./../../../../images/icons/added_to_list.svg')} and output is

screenshot 98

because of extra quotations react treating as text, when i remove the extra quotations it's working fine, please help me to sort it out,

Thanks in advance.

Parser won't transform xlink:href calls made from the <Image> tag

First of thank you for this loader, which is kind of exactly what i need in most of my projects. One thing though that came up is if you consider this svg code:

<svg viewBox="0 0 475 257">
    <defs>
        <pattern id="pattern" patternUnits="userSpaceOnUse"
                 width="475" height="250" viewbox="0 0 475 275">
            <image xlink:href="/assets/frizzle-475x250.png" width="475" height="275" />
        </pattern>
    </defs>
    <path fill="#fdc420" d="M0 72l475-72-17 216-443 41z"/>
    <path fill="url(#pattern)" d="M0 72l475-72-17 216-443 41z"/>
</svg>

The code will be properly inlined as expected. The problem is though webpack will not be informed, that inside the SVG a link to another ressource is requested by the Image tag. Vue Loader hat a similar problem and maybe the solution also fits here: vuejs/vue-loader#569. Webpack will miss these files and not add them to your output folder, so if you don't add them manually or use the path to the original source, the references will be broken. The nicer way would be webpack simply pulling them in the build as it would with other files.

Thanks in advance,
Simon

Disable options on files that match a specific name

Maybe this is a more generic question about webpack loaders.

I'd like to disable an option when the loader detect a specific file name.

{ 
  test: /\.svg$/,
  include: path.join(__dirname, 'assets'),
  use: {
    loader: 'svg-inline-loader',
    options: {
      removeTags: true,
      removingTagAttrs: removeSVGAttrs( name ) // pass file name of the current file
    }
  }
}

function removeSVGAttrs(fileName) {
  removeFill = /\.removeFill/.test(fileName); // test if a file has '.removeFill' in its name
  removeFill ? ['fill'] : false;
}

How can I get the file name of current file being parsed by the loader?

A workaround would be to create two separate instances of svg-inline-loader and include different paths but I'd like a more elegant solution if possibile.

JavaScript Foundation License

The license in this repo needs to be updated at the request of the foundation.

The LICENSE needs to be named LICENSE ( no extension ) if it isn't already.

The LICENSE needs to have the following copy.

Copyright JS Foundation and other contributors

Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
'Software'), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

As a request from the JavaScript Foundation to simplify the legal issues, the update needs to be committed by @sairion

Removal of <defs> breaks SVG images

I have noticed the recent addition of:

+    // Non-displayed elements
+    [/<title>.*<\/title>/gi, ""],
+    [/<desc>.*<\/desc>/gi, ""],
+    [/<defs>.*<\/defs>/gi, ""],

Although it's true that these elements are never "displayed" directly, SVG images are likely to break if <defs> is removed, because this is where gradients, clip paths etc. are often stored.

IMO at least <defs> should be removed or replaced with a RegExp that only removes the <defs> if they're empty or contain only whitespace.

This package duplicates functionality of svgo-loader

After doing some research around svg support in the webpack ecosystem, I have found svgo-loader to pretty much handle almost all of the functionally of this module and then much more. Furthermore, it it based around svgo which is more standarized.

My recommendation would be to deprecate this package and recommend users use svgo-loader instead.

Provide an example in the documentation

This loader doesn't have an example provided in the documentation. It may be obvious to people using React and JSX but providing usage examples would clear up confusion.


Happy to break this out into a separate issue, since this is a question about my usage of svg-inline-loader

I'm using it with Angular 1.5. My component file requires the SVG using:

// component controller
this.iconSvg = require('path/to/icon.svg');

My Angular template uses this:

<div>

    {{$ctrl.iconSvg}}

</div>

The generated output doesn't inline the SVG, instead providing a file or url-loader type output:

//generated output
this.iconSvg = __webpack_require__(11);

/***/ },
/* 11 */
/***/ function(module, exports, __webpack_require__) {

module.exports = __webpack_require__.p + "05e675e0076e90460de5b3e3257738e5.svg";

/***/ },

I would have expected value of __webpack_require__(11) to be the inlined svg rather than a path to it.

I have checked my loader config and can verify that .svg uses svg-inline.

can't load svg file from html file using svg-inline-loader

Is there anyone who knows how to load svg files from index.html?

This is how i try to load svg files in my html file:

<main class="content">
            <img class="img img_custom-size" src="img/close.svg">
            <img src={require("img/close.svg")} /> 
            <img src={require('!svg-inline!img/close.svg')} />
            <img class="img img_custom-size" src=<%=require("./img/close.svg") %>
</main>

and this is my webpack.common.js:

const {resolve} = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const webpack = require('webpack');

module.exports = {
  entry: {
    // polyfills: 'babel-polyfill',
    bundle: './src/app.js'
  },
  output: {
    path: resolve(__dirname, 'dist'),
    filename: '[name].js'
  },
  resolve: {
    extensions: ['.js', '.css']    
  },
  module: {    
    rules: [
      {
        test: /\.scss$/,
        enforce: "pre",
        loader: 'import-glob-loader'
      },  
      {
        test: /\.js$/,
        exclude: /node_modules/,
        use: {
          loader: 'babel-loader',
          options: {
            presets: ['env']
          }
        }
      },
      { 
        test: /\.(ttf|eot|woff2?|svg)$/,
        loaders: [
          {
            loader: 'url-loader',
            options: { 
              limit: 50000,    
              name: "./fonts/[name].[ext]"
            }
          }
        ]
      },
      {
        test: /\.(ico|gif|png|jpe?g)$/,
        loaders: [
          {
            loader: 'file-loader',
            options: {
              name: '[path][name].[ext]',
              context: './src'     
            }
          }          
        ]
      },      
      {
        test: /\.svg$/,
        loaders: [
          {
            loader: 'svg-inline-loader'                      
          }          
        ]
      }
    ]
  },
  plugins: [       
    new HtmlWebpackPlugin({
      title: 'Sticky Notes',
      hash: true,    
      template: './src/index.html',
      // minify: {
      //   collapseWhitespace: true
      // },
    }) 
  ]
};

and any of my paths don't work. I really don't know how to make it works.

webpack 2 idPrefix passed by options not working

webpack 2 idPrefix passed by options generates the same ids among multiple svgs:

// passed by options

// ...

{
    test: /.svg$/,
    use: [
        {
            loader: 'svg-inline-loader',
            options: {
                idPrefix: '[sha512:hash:hex:5]-'
            }
        }
    ]
}

// ...

But passed by query works as expected

// passed by query

// ...

{
    test: /.svg$/,
    use: [
        {
            loader: 'svg-inline-loader?idPrefix=[sha512:hash:hex:5]-'
        }
    ]
}

// ...

how to ignore fonts ?

Hi !

I have some svg to inline but, i load fonts too..

with this test

    {
        test: /\.svg$/,
        loader: 'svg-inline'
    }

How can i ignore fonts ?

thanks !

SVG styles override each other

If I have a few SVGs I want to use on the same view, the styles from the last svg will override the others.

If the SVG files look something like this:
(actual svgs I'm using are much more complicated, these are just to demonstrated the issue)

// logo_one.svg
<svg viewBox="0 0 24 24">
    <style>.a{fill:#FF0000;}</style>
    <circle class='a' cx="12" cy="12" r="12"/>
</svg>

// logo_two.svg
<svg viewBox="0 0 24 24">
    <style>.a{fill:#00FF00;}</style>
    <circle class='a' cx="12" cy="12" r="12"/>
</svg>

// logo_three.svg
<svg viewBox="0 0 24 24">
    <style>.a{fill:#0000FF;}</style>
    <circle class='a' cx="12" cy="12" r="12"/>
</svg>

and if I use them into my react app like this:

import InlineSVG from 'svg-inline-react';

function SomeComponent() {
    return (
        <div>
            <InlineSVG src={require('svg-inline!./logo_one.svg')} />
            <InlineSVG src={require('svg-inline!./logo_two.svg')} />
            <InlineSVG src={require('svg-inline!./logo_three.svg')} />
        </div>
    )
}

then all SVGs end up rendering with same color because style class .a gets overridden by the last.

Is there a known solution for this using inline SVGs with this loader?
Would it be possible to add a prefix or something to style classes on loading?

Link to svg-inline-react in the readme

Hey, like the work,

sorry can't easily supply a PR right now, but in the readme you should link to svg-inline-react i.e. [svg-inline-react](https://github.com/sairion/svg-inline-react), otherwise it's not clear what package you mean

Add Karma test

As shown as #3, what really matter is browser, not Node environment. Webpack+Karma test is needed

className and float numbers bug

I have an SVG that has two classes and one defines the opacity attribute.

Here is what it will make of it:
inline-svg_classname_bug

It probably needs a better way how to parse css selectors.

how to use with angular template?

This may ne silly question but how would I set this up with an angular template?

As in for angular materail design:


I have configed the loader, but how do I get the the url?

Any plans for more releases?

It seems like PRs are still being merged into master, but the most recent release to npm was back in September 2016.

I'm running into this issue: #41

Cannot add property value, object is not extensible

Hi,
I receive this when running svg-inline-loader on server side. It worked fine before upgrade to webpack 4.

Module build failed: TypeError: Cannot add property value, object is not extensible
at Object.SVGInlineLoader (/home/xxx/node_modules/svg-inline-loader/index.js:61:5)

in particular is thrown by the line with:
this.value = content

Ubuntu 17
Webpack 4.5.0

Getting Invalid value for <path>

Would love to get this working with my react app. (0.14) But I keep getting:

Error: Invalid value for <path> attribute d="\\\"M243.621"

I've tried with several svg files. Same results with each. Any ideas what could be missing?

Thanks in advance.

Invariant Violation: ReactCompositeComponent.render()

Uncaught Error: Invariant Violation: ReactCompositeComponent.render(): A valid ReactComponent must be returned. You may have returned undefined, an array or some other invalid object.

import IconSVG from '../../../../../node_modules/svg-inline-loader/lib/component.jsx';

// ...

<IconSVG src="/public/images/video_controls_volume_icon.svg" className="toggle"  />

Remove attributes transform

HI! Thanks for this loader!
I was asking me about using svgo like issue #9 to support, for example, removing custom attributes (verison) from the inline svg result.
As far as I know removingTags do not remove attributes but only tags.

import returns base64 encoded URL

I have:

      // "svg-inline" loader for svgx (just to distinguish it from svg loaded as files
      {
        test: /\.svgx$/,
        loader: 'svg-inline-loader',
      },
import svg from './spinner.svgx'

But it returns me the base64 encoded file instead of the SVG as string...

data:application/octet-stream;base64,.....

README instructions for loader

Is there a reason that the README specifies the following instructions? I couldn't get it to work without appending -loader to the svg-inline key.

    {
        test: /\.svg$/,
        loader: 'svg-inline'
    }

Need to update loaderUtils?

(node:4896) DeprecationWarning: loaderUtils.parseQuery() received a non-string value which can be problematic, see webpack/loader-utils#56
parseQuery() will be replaced with getOptions() in the next major version of loader-utils.
at Object.parseQuery (.../node_modules/svg-inline-loader/node_modules/loader-utils/index.js:78:3)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.