JetBrains / svg-sprite-loader

Webpack loader for creating SVG sprites.
MIT License
2.02k stars 270 forks source link

Browser Error can't locate sprite.svg #368

Open davidcarela opened 4 years ago

davidcarela commented 4 years ago

Do you want to request a feature, report a bug or ask a question? Ask What is the current behavior? Browser Error What is the expected behavior? Render svg icon If the current behavior is a bug, please provide the steps to reproduce, at least part of webpack config with loader configuration and piece of your code. The best way is to create repo with minimal setup to demonstrate a problem (package.json, webpack config and your code). It you don't want to create a repository - create a gist with multiple files Here's a stack link https://stackoverflow.com/questions/59061938/having-an-issue-rendering-an-svg-icon-using-webpack-4 If this is a feature request, what is motivation or use case for changing the behavior?

Please tell us about your environment:

Catalina 10.15.1

Other information (e.g. detailed explanation, stacktraces, related issues, suggestions how to fix, links for us to have context, eg. stackoverflow, gitter, etc)

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'
        }
    })
],

};

Screen Shot 2019-12-06 at 3 46 52 PM Screen Shot 2019-12-06 at 3 44 43 PM
davidcarela commented 4 years ago

Forgot to include my.js file ... Assistance to resolve is appreciated


import './sidebar.scss';
import photo from './usrPic.jpg';
// import twitter from './twitter.svg';
import  './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 html = `<div class="sidebar-box">
                        <div class="sidebar-header">
                            <span class="sidebar-title__main">Title</span>
                            <span class="sidebar-title__sub">subTitle</span>
                            <div class="Icon-box">

                            <svg class="icon-twitter "height="30px" width="30px">
                                <use xlink:href='./sprite.svg#icon-twitter'></use>
                            </svg> 

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

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

    }
}
davidcarela commented 4 years ago

Hi,

I made some changes to my webpack.config file.

webpack.dev.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|svg)$/,
                use:  [ 'file-loader'],

            },

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

                    {
                        loader: 'svg-sprite-loader',
                        options: { extract: true, spriteFilename: path.resolve(__dirname, './src/components/sidebar.sprite.svg') }
                    },
                    '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()
    ],
};

I'm unable to display the svg icon and I get the following webpack warning.

WARNING in ./src/components/sidebar/sprite.svg Module Warning (from ./node_modules/svg-sprite-loader/lib/loader.js): svg-sprite-loader exception. Some loaders will be applied after svg-sprite-loader in extract mode @ ./src/index.js 5:0-41

WARNING in ./src/components/sidebar/twitter.svg Module Warning (from ./node_modules/svg-sprite-loader/lib/loader.js): svg-sprite-loader exception. Some loaders will be applied after svg-sprite-loader in extract mode @ ./src/components/sidebar/sidebar.js 9:0-36 @ ./src/index.js Child html-webpack-plugin for "index.html": 1 asset Entrypoint undefined = index.html 21 modules ℹ 「wdm」: Compiled with warnings.

jsfile

import './sidebar.scss';
import photo from './usrPic.jpg';
import twitter from './twitter.svg';
import  symbol from './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 html = `<div class="sidebar-box">
                        <div class="sidebar-header">
                            <span class="sidebar-title__main">Title</span>
                            <span class="sidebar-title__sub">subTitle</span>
                            <div class="Icon-box">

                            <svg id="icon-twitter" "height="30px" width="30px">
                                <use xlink:href='#icon-twitter'></use>
                            </svg> 

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

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

    }
}
davidcarela commented 4 years ago

@kisenka - Thoughts are appreciated : )

dramoturg commented 4 years ago

HI. @davidcarela have you details about way resolve this problem?