4

I have a following output project structure:

img
  ...
portfolio
  masttech
    index.html
  index.html
...
index.html

And a following source project structure:

components
  ...
  Portfolio
    img
      ...
    Masttech
      img
        ...
      index.js
      template.pug
      style.sass
    index.js
    template.pug
    style.sass
  Index
    img
      ...
    index.js
    template.pug
    style.sass
  layout.pug
index.js

And a following webpack config:

context: __dirname,
entry: [
  './src/index.js'
],
output: {
  filename: 'main.js',
  path: path.resolve(__dirname, 'dist'),
  publicPath: '/'
},
devServer: {
  publicPath: '/'
},
module: {
  rules: [
    ...
    {
      test: /\.(png|svg|jpg|jpeg|gif)$/,
      use: [
        {
          loader: 'url-loader',
          options: {
            limit: 8192,
            name: 'img/[name].[hash:7].[ext]'
          }
        }
      ]
    }
  ]
},
plugins: [
  ...
  new HtmlWebpackPlugin({
    filename: 'index.html',
    template: './src/components/Index/template.pug'
  }),
  new HtmlWebpackPlugin({
    filename: 'portfolio/masttech/index.html',
    template: './src/components/Portfolio/Masttech/template.pug'
  })
]
...

The problem is all my image urls are just img/..., it's okay for index.html located in root but unsuitable for pages inside subdirectories. If I'd change their urls to absolute starting from / I think the problem will be solved but I don't know how to do it. If I prefix name option of the loader with /, the images can't be accessed at all.

For example this is how I require an image inside src/components/Portfolio/Masttech/template.pug: img(src=require('./img/pic__structure.png') While serving it transforms to img/pic__structure.7b94b5f.png, so that it can't be accessed from the output img directory since img folder is located in root while the page is located in portfolio/masttech folder.

shpindler
  • 357
  • 2
  • 12
  • `url-loader` transforms files to base64 data URLs, they shouldn't be being fetched from anywhere. – robinsax Dec 22 '18 at 05:37
  • 1
    @robinsax yes but If a file size is greater than the limit it works just as a file-loader. – shpindler Dec 22 '18 at 05:38
  • Is this you're looking for? [contentBase](https://webpack.js.org/configuration/dev-server/#devserver-contentbase) – Timothy Lee Dec 22 '18 at 05:40
  • @TimothyLee I tried to use it on the assets directory but it didn't help. An uncomfortable thing about it if I split my assets through a lot of component directories. – shpindler Dec 22 '18 at 05:48
  • you can reach image with relative path by `../` – skyboyer Dec 22 '18 at 08:07
  • @skyboyer in source code I do it exaclty so but while serving they're transformed to `img/...` by the loader so that they'll become unreached. – shpindler Dec 22 '18 at 08:21

1 Answers1

1

Adding publicPath: '/' to the loader options has solved the problem:

{
  loader: 'url-loader',
  options: {
    limit: 8192,
    name: 'img/[name].[hash:7].[ext]',
    publicPath: '/'
  }
}

Moreover I found out my frustrating fail - in the very end of webpack conf I had another output rule where publicPath wasn't defined, so that it rewrote the right rule with it. As a conclusion, you don't need publicPath: '/' in the loader options if you already have it in output.

shpindler
  • 357
  • 2
  • 12