how to set up an inline svg with webpack

2019-01-22 18:06发布

I am wondering how to set up an inline svg with webpack?

I am following the react-webpack-cookbook.

I have my webpack.config set up correctly with the file loader.

However the example shows using a background image like this:

.icon {
   background-image: url(./logo.svg);
}

which works fine, but I want to have an inline svg image how do I do this to include my logo.svg inline in my react component?

import React, { Component } from 'react'

class Header extends Component {

  render() {
    return (
        <div className='header'>
            <img src={'./logo.svg'} />
        </div>
    );
  }
};

export default Header

5条回答
一夜七次
2楼-- · 2019-01-22 18:44

Actually Michelle's answer pointed me in the right direction, and that works nicely for loading an svg file with webpack and using it as your <img> src

However to actually get the inline svg, I needed to do the following:

Instead of file-loader use svg-inline-loader as your svg loader:

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

Then to load the svg inline in a component:

import React, { Component } from 'react'
import logo from "./logo.svg";

class Header extends Component {

  render() {
    return (
        <div className='header'>
          <span dangerouslySetInnerHTML={{__html: logo}} />
        </div>
    );
  }
};

export default Header

It looks like there is an inline svg wrapper for react svg-inline-react which would be another option instead of the <div dangerouslySetInnerHTML={{__html: mySvg}} />

查看更多
劫难
3楼-- · 2019-01-22 18:49

I hope my late answer will still be useful for someone, because I don't like any of abovementioned options.

The react-svg-loader webpack loader allows you to import SVG icons like JSX components:

import Logo from './logo.svg';

class App extends Component {
  render() {
    return (
      <div className="App">
          <Logo fill="red" className="logo" width={50} height={50} />
      </div>
    );
  }
}

and minimum config looks like this:

{
  test: /\.svg$/,
  use: [
    {
      loader: "babel-loader"
    },
    {
      loader: "react-svg-loader",
      options: {
        jsx: true // true outputs JSX tags
      }
    }
  ]
}

The best part is that it just outputs the svg file contents, without any extra wrappers and dangerouslySetInnerHTML in your code.

查看更多
闹够了就滚
4楼-- · 2019-01-22 18:59

Similar to another answer using React, there is also a handy Vue plugin as well.

vue-svg-loader just throw it in your configuration and start using. The nice thing is it will also run your svg through SVGO to optimize it.

Configuration

{
    test: /\.svg$/,
  loader: 'vue-svg-loader', // `vue-svg` for webpack 1.x
  options: {
    // optional [svgo](https://github.com/svg/svgo) options
    svgo: {
      plugins: [
        {removeDoctype: true},
        {removeComments: true}
      ]
    }
  }
}

Usage

<template>
  <nav id="menu">
    <a href="...">
      <SomeIcon class="icon" />
      Some page
    </a>
  </nav>
</template>

<script>
import SomeIcon from './assets/some-icon.svg';

export default {
  name: 'menu',
  components: {
    SomeIcon,
  },
};
</script>
查看更多
Bombasti
5楼-- · 2019-01-22 19:01

If I'm not mistaken, since you're using the file loader, you can utilize it in much the same way as any other require. Webpack will turn require("./logo.svg") into a path to a file, which it will emit when it bundles.

import React, { Component } from 'react'

import mySvg from './logo.svg'

class Header extends Component {

  render() {
    return (
        <div className='header'>
            <img src={mySvg} />
        </div>
    );
  }
};

export default Header
查看更多
姐就是有狂的资本
6楼-- · 2019-01-22 19:08

Old question, but I didn't see this solution anywhere so I decided to post it, hoping it will help someone.

If you want to be able to style those SVG icons, you might want to load them with the raw loader:

webpack.config.js:

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

The import in my view:

import closeIcon from 'svg/ic_close_black_24px.svg'; 

The template (Mustache uses 3 brackets to insert the SVG data (URL)unencoded):

<button id="closeModal">
  {{{closeIcon}}}
</button>

this way the SVG data will be inserted instead of the brackets and look like this:

<button id="closeModal">
  <svg fill="#000000" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
    <path d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"></path>
    <path d="M0 0h24v24H0z" fill="none"></path>
  </svg>
</button>

I'm using Backbone with Mustache template engine with Webpack 2.5.1

查看更多
登录 后发表回答