Как настроить встроенный svg с webpack

Мне интересно, как настроить встроенный svg с webpack?

Я следую react-webpack-cookbook.

У меня есть webpack.config с файловым загрузчиком.

Однако пример показывает использование фонового изображения следующим образом:

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

который отлично работает, но я хочу иметь встроенный svg-образ, как мне сделать это, чтобы включить мой логотип .svg в мой компонент-ответ?

import React, { Component } from 'react'

class Header extends Component {

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

export default Header

Ответы

Ответ 1

На самом деле ответ Мишель указал мне правильное направление, и это прекрасно работает для загрузки файла SVG с веб-пакета и использования его в качестве <img>

Однако, чтобы получить встроенный svg, мне нужно было сделать следующее:

Вместо загрузчика файлов используйте svg-inline-loader в качестве загрузчика svg:

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

Затем загрузить встроенный svg в компонент:

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

Похоже, что есть встроенная оболочка svg для реагирования svg-inline-response, которая была бы другой опцией вместо <div dangerouslySetInnerHTML={{__html: mySvg}}/>

Ответ 2

Старый вопрос, но я не видел этого решения нигде, поэтому решил опубликовать его, надеясь, что это поможет кому-то.

Если вы хотите стилизовать эти значки SVG, вы можете загрузить их с помощью необработанного загрузчика:

webpack.config.js:

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

Импорт на мой взгляд:

import closeIcon from 'svg/ic_close_black_24px.svg'; 

Шаблон (Mustache использует 3 скобки для вставки SVG-данных (URL-адресов) некодированных):

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

таким образом SVG-данные будут вставлены вместо скобок и будут выглядеть так:

<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>

Я использую Backbone с движком шаблонов Mustache с Webpack 2.5.1

Ответ 3

Я надеюсь, что мой поздний ответ все еще будет полезен для кого-то, потому что мне не нравится ни один из вышеупомянутых вариантов.

Загрузчик веб - пакетов реактив -svg-loader позволяет импортировать значки SVG, такие как компоненты JSX:

import Logo from './logo.svg';

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

и минимальный конфиг выглядит так:

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

Самое приятное то, что он просто выводит содержимое файла svg без каких-либо дополнительных оболочек и dangerouslySetInnerHTML SetInnerHTML в вашем коде.

Ответ 4

Если я не ошибаюсь, поскольку вы используете загрузчик файлов, вы можете использовать его так же, как и любой другой. Webpack превратит require("./logo.svg") в путь к файлу, который он испустит, когда он свяжется.

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

Ответ 5

Подобно другому ответу с использованием React, есть также удобный плагин Vue.

vue-svg-loader просто добавьте его в свою конфигурацию и начните использовать. Приятно то, что он также будет запускать ваш svg через SVGO для его оптимизации.

конфигурация

{
    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}
      ]
    }
  }
}

использование

<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>

Ответ 6

Вот простое нереагирующее решение.

  1. Установите встроенный загрузчик SVG
  2. В webpack.config.js добавьте { test:/\.svg$/, loader: 'svg-inline-loader' }
  3. В вашем js файле импортируйте изображение SVG и добавьте его в элемент DOM следующим образом
  import Svg from './svg.svg';

  function component() {
    const element = document.createElement('div');

    element.innerHTML = Svg;

    return element;
  }

  document.body.appendChild(component());

Ответ 7

Угловое решение (2019): используйте svg-sprite-loader, чтобы объединить SVG в один спрайт, который лениво загружается с вашими пакетами Webpack.

Webpack

{
  test: /\.svg$/,
  use: [
    'svg-sprite-loader',
    'svgo-loader' // Optimize SVGs (optional)
  ]
}

HTML

<svg>
    <use xlink:href="#arrow"/>
</svg>

Angular компонент

export * from 'assets/images/icons/arrow.svg';

Я использую экспорт (вместо импорта), чтобы компилятор AOT не удалял импорт во время встряхивания дерева, при этом допуская минимальный код в компоненте, но вы можете использовать импорт, если хотите.

Чтобы использовать экспорт таким образом, вы должны настроить компилятор так, чтобы он ожидал побочных эффектов от файлов SVG в package.json (то есть вы не можете использовать "sideEffects": false). См. Руководство по встряхиванию дерева веб-пакетов

"sideEffects": [
    "*.svg",
],