Skip to content
This repository has been archived by the owner on Mar 17, 2021. It is now read-only.

Set specific path for file-loader to look for assets #180

Closed
jewbetcha opened this issue Jul 24, 2017 · 13 comments
Closed

Set specific path for file-loader to look for assets #180

jewbetcha opened this issue Jul 24, 2017 · 13 comments

Comments

@jewbetcha
Copy link

I'm using file-loader along with extract-loader and html-loader to process images within some generated static HTML (Hugo is the generator).

The generated HTML and assets are all under a public/ folder, the structure is:

webpack.config.js
public/
    index.html
    images/
    some-path/
    |   index.html
    |   another-path/
    |   |    index.html

etc.

All images are referenced absolutely as /images/image.png from all HTML files. Some are at a path like /images/foo/bar/image.png.

I have successfully gotten Webpack to process all of the HTML files, but since the images all come with absolute paths it doesn't know where to find them in the context of my project root (at least with my current config). I have also successfully processed a single HTML file and its images by altering the image paths of that single file, so I know the config works in that regard. The image paths were hashed in HTML and the image filename was also hashed.

Is there a way I can tell file-loader and Webpack where to find these images, without manually altering their path in the HTML?

Here is my current config:

           test: /\.(png|jpg|svg)$/, 
                use: [{
                    loader: "file-loader?outputPath=images/",
                    options:  {
                        limit: 10000,
                        emitFile: true,
                        useRelativePath: true
                    }
                }] 
            },
            {
                test: /\.html$/,
                use: [
                    "file-loader?name=[name].[ext]",
                    "extract-loader",
                    "html-loader?" + JSON.stringify({
                        attrs: ["img:src"]
                    })
                ]
            }
output: {
        path: path.resolve(__dirname + '/public/'),
        publicPath: "./public/",
        filename: '[name].js'
    }

The entry is an object glob containing all of the HTML under the public/ folder.

I'm using file-loader v0.11.1 and Webpack v3

@AndreKR
Copy link

AndreKR commented Aug 23, 2017

You can set publicPath: '' and at runtime set __webpack_public_path__ = 'path/to/your/assets'.

Note that currently you have to downgrade to file-loader 0.10.1 to make this work.

@TimVervers
Copy link

Hi @AndreKR, I'm having the same issue as @jewbetcha. I followed your advice and added publicpath to my webpack.config and set the public path inside my entry point file. Sadly, this wont work cause the CSS imports with the URL link inside them will load earlier then setting the webpack_public_path.

My stackoverflow post (initially for url-loader) https://stackoverflow.com/questions/46001976/webpack-url-loader-dynamic-public-path

Thanks in advance,

Tim

@AndreKR
Copy link

AndreKR commented Sep 7, 2017

First double-check please that you are really using file-loader 0.10.1 and not something newer.

Then, what's in your ./src/admin.planningview.js? If is contains something like

__webpack_public_path__ = 'path/to/your/assets';
require('base.css');

then it should work.

@poorpaddy
Copy link

@jewbetcha If you figured out the solution to this would you mind posting it in a comment please? Running into a similar issue where the home page is in root and image paths are ./img/ but subdirectory/routes have the same when they need to be ../img.

@jewbetcha
Copy link
Author

@poorpaddy I haven't figured it out 😭 I'm either missing something obvious, or this is just a thing Webpack isn't made for (working with assets that aren't built with JS frameworks)

@alexander-akait
Copy link
Member

Problem still exists? Somebody can create minimum example repo and description?

@DawidMmM
Copy link

DawidMmM commented Mar 6, 2018

Yes. The problem still exists, I got the same issue if I try to load images form subfolders. When i use ./img/ everything is fine but if I got an .html file in a subfolder to load images I need to use this ../img/ and it doesn't work.

@poorpaddy
Copy link

I managed to fix this by just using ./ as my root. However it is far from a perfect solution. In the end I ended up no longer bundling images in webpack and now serve them from CDN. It actually drastically improved build times and load times since I served the images thru a cache.

@mimi149
Copy link

mimi149 commented Mar 26, 2018

I have the same problem and I recognize that webpack stores the images in the folder which are set in the config.output.path1 + path2, where path2 is in '[path2][name].[ext]' when setting the option for file-loader (path2 is the original location of the images).

The browser tries to retrieve the images from another location such as app_url/path2, however. I have tried different configuration for webpack but failed. I don't know if someone could do that.

My temporary solution is copying the images to the necessary folder after running webpack. I hope to hear a solution from someone else so that the browser retrieves the images where webpack stores in.

@alexander-akait
Copy link
Member

Please create minimum reproducible test repo

@fredyrivas
Copy link

@mimi149 I ended up using other way for handle images:
https://github.com/webpack-contrib/copy-webpack-plugin
so I only use file-loader for fonts

@mimi149
Copy link

mimi149 commented Apr 27, 2018

Thank you @fredyrivas, maybe I can put it in my webpack config and do not have to copy manually anymore.

@evilebottnawi, sorry that I was too busy and could not answer you. What I set is like this:

            {
              test: /\.(png|jpg|gif)$/,
              use: [
                {
                  loader: 'url-loader',
                  options: {
                    limit: 12000, // if less than 12000 bytes, add base64 encoded image to css
                    name (file) {
                      return '/[path][name].[ext]';
                    }
                  },
                }
              ]
            },

and:

  output: {
    path: path.resolve('./webapp/static/bundles/prod/'),
    filename: "[name]-[hash].js",
  },

The orginal place is: ./static/IMAGES/img1.jpg

Webpack copies it to ./webapp/static/bundles/prod/IMAGES/img1.jpg.

I have to copy it to ./webapp/static/IMAGES/img1.jpg so that the website can get it.

@siakaramalegos
Copy link

siakaramalegos commented Oct 12, 2018

@evilebottnawi If you check out this commit in my repo, you can reproduce the problem.

Essentially, it looks like if you use file-loader to build HTML files not at the root of your build folder, it won't do relative paths for images correctly. It's like it can't do ../ at all.

I was playing with [path] and context in that commit and forgot to uncomment my context settings, but the case is still true either way.

EDIT: It looks like this is the same exact issue but from the standpoint of CSS instead of HTML. This particular comment explains the issue well: webpack-contrib/mini-css-extract-plugin#44 (comment)

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

No branches or pull requests

10 participants