webpack4 does not compile all HTML files

I initially did not correctly understand the essence of the problem, I edit the question 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;
}

enter a description of the image here

There is папке src - файле template.html, which has such a part of the layout

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

Which is after compilation webpack

Reincarnates in index.html в папке public I get this result

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

And all it works.

In parallel src there is a folder pages with different pages that have the same piece of layout

<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

enter a description of the image here

And then the problem require for img which in header does not work

I get an error. enter a description of the image here

Tell me, what's wrong with my webpack????

Analog of the question on StackOverflow

Author: Alexandr_TT, 2019-02-03

2 answers

The answer was easier than I thought ...

I can't write more details, because I haven't really figured it out yet...

You can see the details here in the accepted answer, everything works as it should....

       {
        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')
        ]
    }
 1
Author: Air, 2019-06-05 21:50:03

In html-webpack-plugin it is possible to generate multiple HTML pages:

plugins: [
    new HtmlWebpackPlugin(), // Generates default index.html
    new HtmlWebpackPlugin({ // Also generate a test.html
        filename: 'test.html',
        template: 'src/assets/test.html'
    })
]

You can try to create your own instance of the plugin for each page in this way, but in this case you will have to store the pages in the same directory, because I think sorting them manually is not an option, and unfortunately I will not tell you how to overcome nesting(

const HtmlWebpackPlugin = require('html-webpack-plugin');
const fs = require('fs');

    function generateHtmlPlugins(templateDir) {
        const templateFiles = fs.readdirSync(path.resolve(__dirname, templateDir));
        return templateFiles.map(item => {
            const parts = item.split('.');
            const name = parts[0];
            const extension = parts[1];
            return new HtmlWebpackPlugin({
                filename: `${name}.html`,
                template: path.resolve(__dirname, `${templateDir}/${name}.${extension}`)
            })
        })
    }

    const htmlPlugins = generateHtmlPlugins('./frontend/pages');

    module: {
        rules: [
            ...
        ]
        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',
            }),
        ].concat(htmlPlugins)
};

Apparently this will not help to solve the problem, because the files are scattered in different folders, I did not immediately pay attention to it, but it may help get close to the solution)

 0
Author: kost1k, 2019-02-12 04:23:26