3

How can I get the chunkhash value generated by webpack4 so that I can use it inside my index.html to set properly the script src?

Brief context: Hope it not to be a stupid question because I am completely newcomer in webpack, started to learn today. I know how to config, extract js, css, minify them, and maybe all the very basic operations.

This is my webpack.config.js:

const path = require('path')
const webpack = require('webpack')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const OptmizerCssAssetsPlugin = require('optimize-css-assets-webpack-plugin')
const TerserPlugin = require('terser-webpack-plugin')

module.exports = {
    entry: './src/index.js',

    output: {
        path: path.resolve('dist'),
        filename: '[chunkhash].bundle.js' // <<<<<<
    },

    mode: 'development',

    optimization: {
        minimizer: [
            new TerserPlugin({}),
            new OptmizerCssAssetsPlugin({})
        ],
        splitChunks: {
            chunks: 'all'
        }
    },

    module: {
        rules: [
            {
                test: /\.js$/,
                exclude: /node_modules/,
                use: {
                    loader: 'babel-loader',
                    options: {
                        cacheDirectory: true
                    }
                }
            },
            {
                test: /\.css$/,
                use: [
                    { loader: MiniCssExtractPlugin.loader },
                    'css-loader'
                ]
            }
        ]
    },

    plugins: [
        new webpack.ProvidePlugin({
            cowsay: 'cowsay-browser'
        }),
        new MiniCssExtractPlugin({
            filename: 'css/[name].css'
        })
    ]
}

The relevant part is in filename: '[chunkhash].bundle.js' that will produce a filename like 6f9e5dd33686783a5ff8.bundle.js.

I can use that name in my html like <script src="dist/6f9e5dd33686783a5ff8.bundle.js"></script> but I would have to change it everytime the code was updated/regenerated.

I was able to use filename: '[name].bundle.js' instead of the chunkhash but it is not good for caching porpouses.

So, is there any way I can get the chunkhash value and use it to set my script src filename in my index.html automatically everytime I build the project?

Any valid advice will be wellcome!

1 Answer 1

1

Ok, I found a way.

I used the plugin below because it let me use my html as a template file. I just had to remove link and script tags and let it insert them in final html that it will generate.

This is how I done:

1 - Install html-webpack-plugin

npm i -D html-webpack-plugin

2 - Move my /index.html as /src/main.html

Because my configs will generate a file named index.html. Rename template as main.html avoids possible confusions

3 - Add it to plugins secion of webpack.config.js

// ... other imports here ... //

const HtmlPlugin = require('html-webpack-plugin')

module.exports = {
    entry: './src/index.js',

    output: {
        path: path.resolve('dist'),
        filename: '[chunkhash].bundle.js' // **** using chunkhash
    },

    mode: 'development',

    optimization: {
        minimizer: [
            new TerserPlugin({}),
            new OptmizerCssAssetsPlugin({})
        ],
        splitChunks: {
            chunks: 'all' // **** config the WebPack SplitChunksPlugin
        }
    },

    module: {
        rules: [
            {
                test: /\.js$/,
                exclude: /node_modules/,
                use: {
                    loader: 'babel-loader',
                    options: {
                        cacheDirectory: true
                    }
                }
            },
            {
                test: /\.css$/,
                use: [
                    { loader: MiniCssExtractPlugin.loader },
                    'css-loader'
                ]
            }
        ]
    },

    plugins: [
        new webpack.ProvidePlugin({
            cowsay: 'cowsay-browser'
        }),
        new MiniCssExtractPlugin({
            filename: 'css/[contenthash].css' // **** using contenthash
        }),

// **** new config: 
        new HtmlPlugin({
            filename: 'index.html',
            template: path.resolve('src', 'main.html')
        })
    ]
}

4 - That is all!

Now, when I build my project, my /src/main.html is parsed, all css link tags and script js tags are inserted automatically in a new /dist/index.html file (see below):

<!DOCTYPE html>
<!--[if lt IE 7]>      <html class="no-js lt-ie9 lt-ie8 lt-ie7"> <![endif]-->
<!--[if IE 7]>         <html class="no-js lt-ie9 lt-ie8"> <![endif]-->
<!--[if IE 8]>         <html class="no-js lt-ie9"> <![endif]-->
<!--[if gt IE 8]><!--> <html class="no-js"> <!--<![endif]-->
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <title>Vacapack</title>
        <meta name="description" content="">
        <meta name="viewport" content="width=device-width, initial-scale=1">
    <!-- LOOK THIS: //-->
    <link href="css/7358f9abc5c8cea68707.css" rel="stylesheet"></head>
    <body>
        <pre id="caixa"></pre>
    <!-- AND THESE: //-->
    <script type="text/javascript" src="b6183f7997b49195d1f8.bundle.js"></script>
    <script type="text/javascript" src="0e374d6ca9b34e89e18f.bundle.js"></script></body>
</html>

Hope it can help some one else!

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.