首页 > 解决方案 > 使用 Webpack 4 渲染 SVG 图标时出现问题

问题描述

我正在尝试做的事情: 渲染一个 svg 图标。

我的结果:虽然 svg 和 img 属性附加到 DOM,但 HTML 不呈现图标,并且我没有收到 webpack 或浏览器错误。

我的组件文件结构/方法 我将 SVG 导入到 sidebar.js

侧边栏.js

import './sidebar.scss';
import photo from './usrPic.jpg';
import '../base/SVG/twitter.svg';
import  '../base/sprite.svg';



export default class Sidebar {


    render() {

        const img = document.createElement('img');
        img.alt = 'image';
        img.width = 200;
        img.src = photo;
        img.classList = 'sidebar__user-photo';

        // const svg = document.createElement('svg');


        const use = document.createElement('use');
        use.setAttribute('href', `../base/SVG/twitter.svg#icon-twitter.svg`);

        const html = `<div class="sidebar-box">
                        <div class="sidebar-header">
                            <span class="sidebar-title__main">Something</span>
                            <span class="sidebar-title__sub">Sub</span>
                            <div class="Icon-box">
                                <svg class="twitter__icon">


                                </svg>
                            </div>
                        </div>
                    </div>`;
        const contentBox = document.querySelector('.content');
        contentBox.insertAdjacentHTML('beforeend', html);

        const sidebarHeader = document.querySelector('.sidebar-header');
        sidebarHeader.insertAdjacentElement("afterbegin", img);

        const twitterIcon = document.querySelector('.twitter__icon');
        twitterIcon.insertAdjacentElement("afterbegin", use);
    }
}

webpack.dev.config

...
    {
       test: /\.svg$/,
       use: 'svg-sprite-loader'

     },
     {
       test: /\.(png|svg|jpg|gif)$/,
       use:  'file-loader',
     },

html

HTML 代码

到目前为止我所尝试的:

  1. 用直接 icon.svg 交换 sprite.svg<use href="..." />

  2. 我换了<use href="..." />。和<use xlink:href="..." />

  3. 我用“img”属性交换了元素。

  4. 将 40px 应用于 svg 元素的宽度和高度

    鉴于这一切,我没有收到错误,但元素已附加到 DOM,但没有图标。

    非常感谢任何帮助。

第一次更新:

侧边栏.js

被修改为:

...

var SVG_NS = 'http://www.w3.org/2000/svg';
        var XLink_NS = 'http://www.w3.org/1999/xlink';
        const use = document.createElementNS(SVG_NS, 'image');
        use.setAttributeNS(null, 'width', '100');
        use.setAttributeNS(null, 'height', '100');
        use.setAttributeNS(XLink_NS, 'xlink:href', '../base/sprite.svg#icon-twitter' );

const twitterIcon = document.querySelector('.twitter__icon');
        twitterIcon.insertAdjacentElement("afterbegin", use);

这产生了一个 Webpack 错误

ERROR in ./src/components/sidebar/sidebar.js
Module not found: Error: Can't resolve 'svg-sprite-loader' in '/Users/dev/Developer/projects/dcbio'
 @ ./src/components/sidebar/sidebar.js 10:0-28
 @ ./src/index.js

注释掉../sprite.svg文件可以解决上述错误。然而,浏览器现在产生了一个让我发疯的 404 错误。

浏览器错误

渲染 的 HLTM 元素

建议表示赞赏。

谢谢

第二次更新

在阅读了 webpack 的文档和它的 git 之后,我对我的 webpack.config 进行了更改:

const path = require('path');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const SpriteLoaderPlugin = require('svg-sprite-loader/plugin');

module.exports = {
    entry: './src/index.js',
    output: {
        filename: 'bundle.js',
        path: path.resolve(__dirname, './dist'),
        publicPath: '',
    },
    mode: 'development',
    devServer: {
        contentBase: path.resolve(__dirname, './dist'),
        index: 'index.html',
        port: 9000
    },
    module: {
        rules: [
            {
                test: /\.css$/,
                use: [
                    'style-loader', 'css-loader'
                ]
            },
            {
                test: /\.scss$/i,
                use: [
                    'style-loader', 'css-loader', 'sass-loader'

                ],
            },
            {
                test: /\.(png|jpg|gif)$/,
                use:  [ 'file-loader'],

            },

            {
                test: /\.svg$/,
                use: [
                    {
                    loader: 'svg-sprite-loader',
                    options: {
                        extract: true,
                        publicPath: '/src'

                    }
                },
                    'svg-inline-loader',
                    'svgo-loader'
                ] 
            },

            {
                test: /\.js$/,
                exclude: /node_modules/,
                use: {
                    loader: 'babel-loader',
                    options: {
                        presets: [ '@babel/env' ],
                        plugins: [ 'transform-class-properties' ]
                    }
                }
            },
            {
                test: /\.hbs$/,
                use: [
                    'handlebars-loader'
                ]
            }
        ],
    },
    plugins: [
        new CleanWebpackPlugin(),
        new HtmlWebpackPlugin({
            template: 'src/index.hbs',
            title: 'Hello world',
            description: 'Some description'

        }),
        new SpriteLoaderPlugin({
            plainSprite: true,
            spriteAttrs: {
                id: 'icon-twitter'
            }
        })
    ],
};

我仍然收到浏览器错误 - 见图片

浏览器错误

DOM 返回: 在此处输入图像描述

标签: javascripthtmlsvgwebpack

解决方案


最终更新和答案:

经过广泛的研究和编辑,我意识到在我的base.js文件中,属性inner.HTML元素导致<svg>图标无法加载。

此外,我将原始帖子中提到的以下文件修改为:

侧边栏.js

...

import symbol from '../../images/icons_sprite.svg';

...

html = `<svg class="icon-fb">
         <use href="#icons_sprite_icon-facebook"></use>
        </svg>`;

const iconBox = document.querySelector('.Icon-box');
iconBox.insertAdjacentHTML("afterbegin", html);

请注意,我只使用href而不是xlink:href。根据 MDN 文档xlink:href在弃用桶中,所以我选择保留他们推荐的方法 - 只需使用href.

webpack.dev.config

...
    {
      test: /\.svg$/i,
      include: /\.*_sprite\.svg/,
      use:[

       {
         loader: 'svg-sprite-loader',
         options: {
             publicPath: './src',
         }
       },
       {
          loader: 'svgo-loader',
          options: {
          plugins: [
              { cleanupIDs: false },
          ]
       }
    },
..

问题解决了...

以下是有助于解决问题的链接。我希望这个解决方案可以为将来的某个人提供帮助。
MDN
https://developer.mozilla.org/en-US/docs/Web/SVG
Webpack-svg
https://github.com/JetBrains/svg-sprite-loader
https://github.com/svg/svgo
https ://github.com/vp-online-courses/webpack-tutorial/compare/svg-sprites-begin...svg-sprites-end


推荐阅读