6

I initially did not correctly understand the essence of the problem, I correct the question, so as to more accurately formulate the problem ...

There is such an assembly webpack:

'use strict';
const webpack = require('webpack');
const path = require('path');
const UglifyJsPlugin = require("uglifyjs-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const OptimizeCSSAssetsPlugin = require("optimize-css-assets-webpack-plugin");
const HtmlWebpackPlugin = require('html-webpack-plugin');
const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin');


const minimizerBlock = {
  minimizer: [
    new UglifyJsPlugin({
      uglifyOptions: {
        warnings: false,
        parse: {},
        compress: {},
        mangle: true,
        output: null,
        toplevel: false,
        nameCache: null,
        ie8: false,
        keep_fnames: false,
      },
    }),
    new OptimizeCSSAssetsPlugin({})
  ]
}

const config = {
  entry: {
    main: './frontend/src/index.js'
  },
  output: {
    path: path.resolve(__dirname, './public'),
    filename: 'main.js'
  },
  devServer: {
    contentBase: path.join(__dirname, 'public'),
    port: 8888,
    overlay: true,
    proxy: {
      '/api': 'http://localhost:8889'
    }
  },
  module: {
    rules: [{
        test: /\.js$/,
        exclude: /node_modules/,
        use: {
          loader: "babel-loader"
        }
      },
      {
        test: /\.less$/,
        use: [MiniCssExtractPlugin.loader, "css-loader", "less-loader"]
      },
      {
        test: /\.scss$/,
        use: [MiniCssExtractPlugin.loader, "css-loader", "sass-loader"]
      },
      {
        test: /\.sass$/,
        use: [MiniCssExtractPlugin.loader, "css-loader", "sass-loader"]
      },
      //{ test: /\.(ttf|eot|woff|woff2|png|jpg|jpeg|svg|gif|webp)$/, loader: 'url-loader', },
      {
        test: /\.(png|jpg|jpeg|svg|gif|webp)$/,
        include: [
          path.resolve(__dirname, './frontend/binary/image/')
        ],
        use: [{
          loader: 'file-loader',
          options: {
            name: 'image/[name].[ext]',
          }
        }]
      },
      {
        test: /\.(eot|svg|ttf|woff|woff2)$/,
        include: [
          path.resolve(__dirname, './frontend/binary/fonts/')
        ],
        use: [{
          loader: 'file-loader',
          options: {
            name: 'fonts/[name].[ext]',
          }
        }]
      },
      {
        test: /\.(mp3)$/,
        include: [
          path.resolve(__dirname, './frontend/binary/audio/')
        ],
        use: [{
          loader: 'file-loader',
          options: {
            name: 'audio/[name].[ext]',
          }
        }]
      },
      {
        test: /\.(html)$/,
        include: [
          path.resolve(__dirname, './frontend/pages/')
        ],
        use: [{
          loader: 'file-loader',
          options: {
            name: '[path][name].[ext]',
          }
        }]
      },
    ]
  },
  plugins: [
    new MiniCssExtractPlugin({
      filename: './index.css',
    }),
    new HtmlWebpackPlugin({
      template: path.resolve(__dirname, 'frontend/src/', 'template.html'),
      filename: 'index.html',
      favicon: 'frontend/binary/image/icons/iconfinder_tech_0001_4023871.png',

    }),

  ]
};
module.exports = (env, options) => {
  let production = options.mode == 'production';
  config.devtool = production ? false : 'inline-cheap-module-source-map';
  config.optimization = production ? minimizerBlock : {};
  return config;
}

There is a `src folder - template.html file, in which there is such a part of the layout

 <div id="root">
   <img src="${require(`../binary/image/icons/iconfinder_tech_0001_4023871.png`)}" alt="" />
</div>

which after compilation webpack

reincarnated in index.html in the public folder, I get this result

<div id="root">
  <img src="images/iconfinder_tech_0001_4023871.png" alt="" />
</div>

And it works.

At the same time src there is a folderpages with different pages, in which there is the same piece of typesetting

<header>
   <img src="${require(`../../../../binary/image/sheelak/0viber-image.jpg`)}" alt=""/>
</header>

and after running webpack a folder with these files is created and here is the result

 <header>
   <img src="${require(`../../../../binary/image/sheelak/0viber-image.jpg`)}" alt=""/>
</header>

And then the problem of require forimg which in header does not work

getting an error.

Tell me what's wrong with my webpack?

Link to the project

Air
  • 181
  • 3
  • 15

6 Answers6

2

You shall use html-loader with interpolate flag enabled:

       {
            test: /\.(html)$/,
            include: [
                path.resolve(__dirname, './frontend/pages/')
            ],
            use: [
                {
                    loader: 'file-loader'
                },
                {
                    loader: 'extract-loader'
                },
                {
                    loader: 'html-loader',
                    options: {
                        interpolate: true,
                    }
                }
            ],
            exclude: [
                path.resolve(__dirname, 'frontend/src/', 'template.html')
            ]
        }

I have create pr to fix your problem: https://github.com/sarnor/club/pull/1.

Also noting that interpolation is ugly when you can just write image source like: <img src="../../image/icons/iconfinder_tech_0001_4023871.png".

Also noting that your relative url was pointing to wrong directory, you were missing ../ in your url.

karaxuna
  • 26,752
  • 13
  • 82
  • 117
0

You're using file-loader on your html files, which I don't believe attempts to parse anything inside the file, it simply copies it into the output folder.

I'd suggest trying to use html-loader instead, and see if that fixes the issue.

In particular, you need to change this section:

{
  test: /\.(html)$/,
  include: [
    path.resolve(__dirname, './frontend/pages/')
  ],
  use: [{
    loader: 'file-loader',
    options: {
      name: '[path][name].[ext]',
    }
  }]
}

to look like this:

{
  test: /\.(html)$/,
  include: [
    path.resolve(__dirname, './frontend/pages/')
  ],
  use: [{
    loader: 'html-loader',
    options: {
      name: '[path][name].[ext]',
    }
  }]
}

And possibly install the html-loader using:

npm i -D html-loader
david
  • 17,925
  • 4
  • 43
  • 57
  • I already did it... Next, I have a script called "JS" that imports these "HTML" files, but if I add "html-loader" import does not occur – Air Feb 05 '19 at 04:56
  • I can't catch the point. I want to understand, I do not ask for a ready-made example. I love to understand what I am doing. Should I use and `html-loader` at `file-loader`? – Air Feb 05 '19 at 05:01
0

If you want to know when to which loader read:

https://webpack.js.org/loaders/ and

(Webpack) Using the url-loader or file-loader, do I really have to include a require() in my .js for every static image I want to include?

here for images I think url-loader is good since it can also render base-64 encode image links as images.

Try :

            {
                test: /\.(jpg|png|gif|eot|woff2|woff|ttf|ico|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
                loader: ["url-loader?limit=100&name=static/[name]_[hash].[ext]"]
            }

What it will do? this will take any file of type jpg|png|gif|eot|woff2|woff|ttf|ico|svg & emit to folder static(can be any name also optional) & add hash to names. It will not only emit image & fonts but also limit size of any file to 100 kb & also add unique hash each time to name of static resources making sure any change in image with same name will also refresh cache.

Pranav Singh
  • 17,079
  • 30
  • 77
  • 104
0

can you remove below line from config and check

favicon: 'frontend/binary/image/icons/iconfinder_tech_0001_4023871.png'
Shadab Ahmed
  • 556
  • 9
  • 20
0

You don't have a problem of loader but the way you are using template literals. Backticks need to wrap ${}

<div id="root">
   <img src=`${require("../binary/image/icons/iconfinder_tech_0001_4023871.png")}` alt="" />
</div>

Similarly you would have

<header>
   <img src=`${require("../../../../binary/image/sheelak/0viber-image.jpg")}` alt=""/>
</header>
Shubham Khatri
  • 270,417
  • 55
  • 406
  • 400
0

To use require in your html file templates. you need to include html-loader for .html files while you have used file-loader for it. which might have done.

so, webpack config should be something like:

{
  test: /\.(html)$/,
  include: [
    path.resolve(__dirname, './frontend/pages/')
  ],
  use: [{
    loader: 'html-loader',
    options: {
      name: '[path][name].[ext]',
      attrs: [':data-src']
    }
  }]
}


{
  test: /\.(png|jpg|jpeg|svg|gif|webp)$/,
  include: [
    path.resolve(__dirname, './frontend/binary/image/')
  ],
  use: [{
    loader: 'file-loader',
    options: {
      name: 'image/[name].[ext]',
    }
  }]
}

and then use require in img tag as below:

More about this here

Gaurav Saraswat
  • 1,353
  • 8
  • 11
  • I have already tried it, in return I get this `module.exports = "
    \r\n\t \"\"\r\n\t \r\n
    ";` And I do not know how to deal with it.
    – Air Feb 21 '19 at 05:38
  • @Air I cloned and ran your project on my machine(mac). its working smooth withoujt any 404. can you tell me what exactly is wrong? – Gaurav Saraswat Feb 21 '19 at 18:11
  • Sorry, I forgot to update the repository. You can try again – Air Feb 21 '19 at 20:03