Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Data URL as data:image/svg+xml is unable to be rendered after updating to 6.0.0 #1342

Closed
jesse-iluminai opened this issue Jul 15, 2021 · 15 comments · Fixed by #1348
Closed

Comments

@jesse-iluminai
Copy link

After updating to 6.0.0 from 5.2.6 the default Bootstrap drop down arrow defined as an inline data:image/svg+xml URL no longer displays on screen.

  • Operating System: MacOS 11.3.1
  • Node Version: v14.16.1
  • NPM Version: 6.14.12
  • webpack Version: 5.44.0
  • css-loader Version: 6.0.0

Confirmed in Firefox 89.0.2 and Chrome 91.0.4472.114

Expected Behavior

We should be able to see the drop down arrow as given in the image below:

Screen Shot 2021-07-15 at 4 15 17 PM

URL is modified in such a way that it is not able to render

This is an out of the box/untouched Bootstrap 5.0.2 rule as seen below as an image and the copied rule from bootstrap.css

Screen Shot 2021-07-15 at 4 15 48 PM

background-color: #fff;
background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23343a40' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M2 5l6 6 6-6'/%3e%3c/svg%3e");
background-repeat: no-repeat;
background-position: right 0.75rem center;
background-size: 16px 12px;

Actual Behavior

After updating to 6.0.0 the arrow no longer renders as seen in the image below.

Screen Shot 2021-07-15 at 4 23 59 PM

When using devtools in Firefox to examine the styles for the dropdown, it appears that some encoding has been applied to the data URL, making it unrenderable.

Screen Shot 2021-07-15 at 4 24 09 PM

background-image: url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2016%2016'%3E%3Cpath%20fill='none'%20stroke='#343a40'%20stroke-linecap='round'%20stroke-linejoin='round'%20stroke-width='2'%20d='M2%205l6%206%206-6'/%3E%3C/svg%3E");
background-repeat: no-repeat;
background-position: right 0.75rem center;
background-size: 16px 12px;

Code

Note: Bootstrap 5.0.2 is set up as a vendor module outside of package.json and therefore not included below.

{
  "repository": {},
  "description": " ",
  "license": "MIT",
  "scripts": {
    "webpack-dev-server": "webpack serve --mode development --progress"
  },
  "dependencies": {
    "alpinejs": "3.2.2",
    "phoenix": "file:deps/phoenix",
    "phoenix_html": "file:deps/phoenix_html",
    "phoenix_live_view": "file:deps/phoenix_live_view",
    "webpack-manifest-plugin": "3.1.1"
  },
  "devDependencies": {
    "@babel/core": "7.14.6",
    "@babel/preset-env": "7.14.7",
    "@babel/plugin-transform-runtime": "7.14.5",
    "babel-loader": "8.2.2",
    "copy-webpack-plugin": "9.0.1",
    "clean-webpack-plugin": "4.0.0-alpha.0",
    "css-loader": "6.0.0",
    "mini-css-extract-plugin": "2.1.0",
    "sass": "1.35.2",
    "sass-loader": "12.1.0",
    "webpack": "5.44.0",
    "webpack-cli": "4.7.2",
    "webpack-dev-server": "3.11.2"
  }
}
    module: {
      rules: [
        {
          test: /\.js$/,
          exclude: /node_modules/,
          use: {
            loader: 'babel-loader'
          }
        },
        {
          test: /\.(jpg|png|gif)$/,
          type: 'asset/resource',
          generator: {
            filename: 'images/[hash][ext][query]'
          }
        },
        {
          test: /\.(woff(2)?|ttf|eot|svg)(\?v=\d+\.\d+\.\d+)?$/,
          type: 'asset/resource',
          generator: {
            filename: 'fonts/[hash][ext][query]'
          }
        },
        {
          test: /\.[s]?css$/,
          use: [
            MiniCssExtractPlugin.loader,
            {
              loader: 'css-loader',
              options: {
                sourceMap: true,
                importLoaders: 2
              }
            },
            { 
              loader: "sass-loader", 
              options: { 
                sourceMap: true 
              }
            },
          ],
        }
      ]
    },
    plugins: [
      new CleanWebpackPlugin(),
      new MiniCssExtractPlugin({ 
        filename: isProductionMode ? "[name].[contenthash].css" : "css/[name].css"
      }),
      new CopyWebpackPlugin({ 
        patterns: [
          { from: 'assets/static/', to: '' }
        ]
      }),
      new WebpackManifestPlugin(),
      new webpack.ContextReplacementPlugin(/moment[/\\]locale$/, /en/),
    ].concat(isProductionMode ? [] : [

    ]),
    optimization: {
      minimizer: [
        
      ]
    } 

How Do We Reproduce?

5.2.6 -> dropdown is visible
6.0.0 -> dropdown is not visible

@lerit
Copy link

lerit commented Jul 16, 2021

maybe relate with:#1337

@wendt88
Copy link

wendt88 commented Jul 16, 2021

I had the same issue as this and can confirm making the change from: #1337 (comment) has resolved the issue

for me not and I can not understand, how /\.png$/ can match a data:image/svg+xml....-string.
the only change was, that all png's get converted to inline data uri's (as expected)

@OwenPattison
Copy link

I had the same issue as this and can confirm making the change from: #1337 (comment) has resolved the issue

for me not and I can not understand, how /\.png$/ can match a data:image/svg+xml....-string.
the only change was, that all png's get converted to inline data uri's (as expected)

I've just removed that comment actually as I've found a small problem - so it's not 100% resolved, with regards to .png$, I also have more file extensions that are managed by this, svg jpg etc

@OwenPattison
Copy link

Digging into this issue a little deeper and comparing url-loader with asset modules the problem seems to be with the encoding of the generated data:image, in my case there is a # which if I change to %23 then the asset loads.

@alexander-akait
Copy link
Member

Bug in decoding

@alexander-akait
Copy link
Member

Fixed webpack/webpack#13807, let's wait release

@jesse-iluminai
Copy link
Author

jesse-iluminai commented Jul 16, 2021 via email

@jakejarvis
Copy link

In the meantime if anyone needs an easy temporary fix, adding a filter to ignore any inline assets starting with data:image/svg+xml is working for me:

{
  loader: "css-loader",
  options: {
    url: {
      // skip any data URLs of type image/svg+xml
      filter: (url) => !(url.startsWith("data:image/svg+xml"))
    }
  }
}

@alexander-akait alexander-akait mentioned this issue Jul 17, 2021
6 tasks
@alexander-akait
Copy link
Member

Fixed in webpack, please update webpack to the latest version https://github.com/webpack/webpack/releases/tag/v5.45.1 and remove workaround

@jakejarvis
Copy link

confirmed fixed after updating to 5.45.1 and removing my workaround above, thanks as always @alexander-akait 🙌

@marvindanig
Copy link

Has the issue reappeared with 5.46.0? SVGs stopped working as element background images on my css at least.

@alexander-akait
Copy link
Member

No, double check webpack version, or provide example of the problem

@richallanb
Copy link

A generic solution to this problem for people still running into it (and will address url resolution being filtered for absolute paths) is to use loader-utils

const {isUrlRequest} = require('loader-utils');

{
  loader: "css-loader",
  options: {
    url: {
      // skip any data URLs or absolute paths
      filter: url => isUrlRequest(url)
    }
  }
}

This was taken from the default url filter for [email protected] that didn't have this problem,
https://github.com/webpack-contrib/css-loader/blob/v3.6.0/src/index.js#L62

@Roberto14
Copy link

I faced this issue when updating from v5.66.0 to v5.67.0, dataUrls with inlined SVG's stopped working.

CSS sourcecode:

content: url("data:image/svg+xml,%3Csvg width='32' height='32' vie....");

Resulting code:

content: url("data:image/svg+xml,export%20default%20__webpack_public_path__%20%2B%20....%2Fsvg%253E.2d5d40b2.bin%22%3B");

Webpack replaces the SVG by a JS template and emits an asset where it should not.
Issue currently happening on v5.88.0.

@alexander-akait
Copy link
Member

@Roberto14 I think you have a problem with your configuration, can you provide a reproducible example and I will show you how to fix it

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

9 participants