Webpack: Can't display SVG images with file-loader (svg parse error)

3.8k views Asked by At

SVGs that I use using require doesn't get displayed.

In my terminal, svg assets gets emitted and paths were set properly in my html.

<img src="/images/brand-illustration.f20767e375d3094978f5cc5c9726d0a6.svg">

However, the SVG won't display while other formats like jpg or png works. I tried opening the original svg file and it definitely works. And when I inspected the emitted svg asset and load it in the browser like so: localhost:8080/images/brand-illustration.f20767e375d3094978f5cc5c9726d0a6.svg, I get this parse error: enter image description here

This is how I use the svg in my pug file

img(src=require('../../assets/img/brand-illustration.svg').default)

webpack config

module.exports = {
    entry: {
        main: "./src/index.js"
    },
    output: {
        path: path.join(__dirname, "../build"),
        filename: "[name].bundle.js",
        publicPath: '/'
    },
    mode: "development",
    module: {
        rules: [
            {
                test: /\.js$/,
                exclude: /node_modules/,
                use: {
                    loader: "babel-loader"
                }
            },
            {
                test: /\.s?css$/,
                use: [{
                    loader: MiniCssExtractPlugin.loader
                }, {
                    loader: 'css-loader',
                    options: {
                        sourceMap: true
                    }
                }, {
                    loader: 'resolve-url-loader',
                    options: {
                        sourceMap: true
                    }
                }, {
                    loader: 'sass-loader',
                    options: {
                        sourceMap: true
                    }
                }]
            }, {
                test: /\.pug$/,
                use: ["pug-loader"]
            },
            {
                test: /\.(png|svg|jpe?g|gif|webp)$/,
                use: [
                    {
                        loader: "file-loader",
                        options: {
                            limit: 10000,
                            outputPath: 'images',
                            name: '[name].[hash].[ext]'
                        }
                    },
                ]
            },
            {
                test: /\.(woff(2)?|ttf|otf|eot|svg)(\?v=\d+\.\d+\.\d+)?$/,
                use: [{
                    loader: 'file-loader',
                    options: {
                        limit: 10000,
                        name: '[name].[hash].[ext]',
                        outputPath: 'fonts'
                    }
                }]
            },
            {
                test: /\.html$/,
                use: {
                    loader: "html-loader?interpolate",
                    options: {
                        attrs: ["img:src", ":data-src"],
                        minimize: true
                    }
                }
            }
        ]
    },
    plugins: [
        // CleanWebpackPlugin will do some clean up/remove folder before build
        // In this case, this plugin will remove 'dist' and 'build' folder before re-build again
        new MiniCssExtractPlugin({
            filename: 'css/[name].css',
            chunkFilename: 'css/[name].[contenthash]_[id].css'
        }),
        new CleanWebpackPlugin(),
        // The plugin will generate an HTML5 file for you that includes all your webpack bundles in the body using script tags
        new HtmlWebpackPlugin({
            filename: 'index.html',
            template: path.join(__dirname, '..', '/src/index.pug'),
            inject: true,
            publicPath: '/'
        }),
        new HtmlWebpackPlugin({
            filename: 'about.html',
            template: path.join(__dirname, '..', '/src/about.pug'),
            inject: true,
            publicPath: '/'
        }),
        new HtmlWebpackPlugin({
            filename: 'works.html',
            template: path.join(__dirname, '..', '/src/works.pug'),
            inject: true,
            publicPath: '/'
        }),
        new HtmlWebpackPlugin({
            filename: 'contact.html',
            template: path.join(__dirname, '..', '/src/contact.pug'),
            inject: true,
            publicPath: '/'
        }),
        new HtmlWebpackPlugin({
            filename: '404.html',
            template: path.join(__dirname, '..', '/src/404.pug'),
            inject: true,
            publicPath: '/'
        })
    ].concat(htmlPlugins)
};

devDependencies

    "@babel/core": "^7.7.7",
    "@babel/plugin-syntax-dynamic-import": "^7.2.0",
    "@babel/preset-env": "^7.7.7",
    "babel-loader": "^8.0.6",
    "brotli-webpack-plugin": "^1.1.0",
    "clean-webpack-plugin": "^3.0.0",
    "compression-webpack-plugin": "^3.0.1",
    "css-loader": "^3.4.1",
    "cssnano": "^4.1.0",
    "file-loader": "^5.0.2",
    "html-loader": "^0.5.5",
    "html-webpack-plugin": "^3.2.0",
    "mini-css-extract-plugin": "^0.9.0",
    "node-sass": "^4.13.0",
    "optimize-css-assets-webpack-plugin": "^5.0.3",
    "postcss-loader": "^3.0.0",
    "postcss-preset-env": "^6.7.0",
    "pug-html-loader": "^1.1.5",
    "pug-loader": "^2.4.0",
    "purgecss-webpack-plugin": "^1.6.0",
    "resolve-url-loader": "^3.1.2",
    "sass-loader": "^8.0.0",
    "style-loader": "^1.1.2",
    "terser-webpack-plugin": "^2.3.1",
    "url-loader": "^4.1.1",
    "webpack": "^4.41.5",
    "webpack-cli": "^3.3.10",
    "webpack-dev-server": "^3.10.1",
    "webpack-merge": "^5.7.0"
1

There are 1 answers

0
Pablo On

Remove the file-loader usage and add type: 'asset/resource' in the Webpack config