html-webpack-inline-svg-plugin icon indicating copy to clipboard operation
html-webpack-inline-svg-plugin copied to clipboard

absolute path resolve

Open cyocun opened this issue 4 years ago • 2 comments

Hello! Thanks for the great library. I often use svg as inline for animation, so this is very helpful.

Now, I have a problem with my webpack setup and I've fixed it, but I want to pullrequest it. I've never done a pull request for someone else so I'm not sure how to do it 😂

There are two points.

Now set the outputPath as options. This is important for my directory structure to pass the outputPath.

-        this.outputPath = ''
+       this.outputPath = _.get(options, 'outputPath', '')

If svgSrc starts with a slash, it's a relative path to . If the svgSrcstarts with a slash, you need to add a. Also, if the svgSrc contains [hash] (e.g. foo.svg?abcd) Trim to. Added on line 498.

            svgSrc = svgSrc.replace(/^\//,'./').split('?')[0];

I don't know how to write better, as I usually make this alone. If you have a smarter way, please fix the file.

Looking at issues #10 and #6 , this may be an extra fix, but please consider this for absolute paths and for many situations where you want to set the outputPath.

cyocun avatar Jul 06 '20 17:07 cyocun

voting this up. I think this plugin should consider publicPath for images it should inline. In my case, it's /, so output src for all assets start with /assets/..., to make sure it will work from any route on the site.

not sure if the solution above will work though, but I think I could investigate a bit in this and create a PR if no other workaround is found.

cc @theGC hoping for a help!

idudinov avatar Feb 23 '21 12:02 idudinov

Hi guys,

If SVG file paths are relative to SOURCE, files have to be relative to the source entry template (the template config option in html-webpack-plugin).

output.publicPath is never taken into account by html-webpack-inline-svg-plugin. I'm trying to understand how this variable can be a problem.

So the issue is, if we have the below folder structure:

my-project
├─ package.json
├─ webpack.config.js
├─ node_modules
├─ src
│  ├─ entry.html
│  └─ imagesSource
│     ├─ icon1.svg
│     └─ image1.png
├─ assets
│  └─ bar.svg
└─ output
   ├─ index.html
   └─ imagesOutput
      ├─ icon1.svg
      └─ image1.png

with the below webpack config:

// webpack.config.js

exports = {
  output: {
    path: 'output',
    publicPath: 'public'
  },
  module: {
    rules: [
      {
        test: /\.svg$/,
        loader: 'file-loader',
        options: {
          name: 'imagesOutput/[name].[ext]'
        },
      },
      {
        test: /\.html$/,
        loader: 'html-loader'
      }
    ]
  },
  // ...
}

If we use loaders and SVG files are relative to SOURCE, the <img> element in the template will look like:

<img src="imagesSource/icon1.svg">

However, when webpack is resolving paths after files have been emitted to the output folder, because we have set output.publicPath to public, the resolving path to icon1.svg will be:

output/public/imagesOutput/icon1.svg

instead of:

output/imagesOutput/icon1.svg

and hence it will fail because that public/ addition breaks the correct path.

I think I understand the issue now. In the next months I will make changes to consider output.publicPath in path resolutions.

AntonioRedondo avatar Aug 02 '21 16:08 AntonioRedondo