webpackhtml-webpack-pluginmini-css-extract-plugin

Separate JS code for multiple webpack entries


I want to create 2 separate entries in Webpack config (e.g. app1.js and app2.js) so that each entry point has its own JS and CSS code.

There are following files:

app1.js

import('./app1.css');

console.debug('App1 loaded.');

app1.css

body { background-color: #777; }

app2.js

import('./app2.css');

console.debug('App2 loaded.');

app2.css

body { background-color: #ccc; }

And the following webpack config:

const path = require('path');
const HtmlWebpackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");

module.exports = {
    entry: {
        app1: './src/app1.js',
        app2: './src/app2.js',
    },
    output: {
        filename: 'js/[name].[contenthash].js',
        path: path.resolve(__dirname, 'dist'),
    },
    module: {
        rules: [
            {
                test: /\.css$/i,
                use: [
                    MiniCssExtractPlugin.loader,
                    'css-loader',
                ],
            },
        ],
    },
    plugins: [
        new MiniCssExtractPlugin(),
        new HtmlWebpackPlugin({
            template: "template.html",
            filename: (entryName) => entryName + '.html',
            inject: 'body',
        }),
    ],
    optimization: {
        splitChunks: {
            chunks: 'all',
        },
    },
};

Webpack generates 2 HTML files app1.html and app2.html, but both contain the same JS code:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <title>Demo</title>
</head>
<body>
    <h1>Demo</h1>
    <script defer src="js/app1.aaa2969fbc38b295163c.js"></script>
    <script defer src="js/app2.bd06324edc7919ec11c8.js"></script>
</body>
</html>

so when I open the HTML file, JS code from both app1.js and app2.js is executed.

What am I doing wrong?

And one more question - why is there no tag inserted to the HTML files for CSS?

Github repo with the sample code to reproduce the issue: https://github.com/AlexeyKosov/test-webpack


Solution

  • I have edited your webpack config file from the repo to have:

    const path = require('path'); 
    const HtmlWebpackPlugin = require("html-webpack-plugin"); 
    const MiniCssExtractPlugin = require("mini-css-extract-plugin"); 
     
    module.exports = { 
        entry: { 
            app1: './src/app1.js', 
            app2: './src/app2.js', 
        }, 
        output: { 
            filename: 'js/[name].[contenthash].js', 
            path: path.resolve(__dirname, 'dist'), 
        }, 
        module: { 
            rules: [ 
                { 
                    test: /\.css$/i, 
                    use: [ 
                        MiniCssExtractPlugin.loader, 
                        'css-loader', 
                    ], 
                }, 
            ], 
        }, 
        plugins: [ 
            new MiniCssExtractPlugin(), 
            new HtmlWebpackPlugin({ 
                template: "template.html", 
                filename: "app1.html", 
                chunks: ["app1"], 
            }), 
            new HtmlWebpackPlugin({ 
                template: "template.html", 
                filename: "app2.html", 
                chunks: ["app2"], 
            }), 
        ], 
        optimization: { 
            splitChunks: { 
                chunks: 'all',
            },
        },
    };
    

    Now you should have the dist folder where app1.html contains only js/app1.<contenthash>.js script and app2.html contains only js/app2.<contenthash>.js