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!
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:
npm i -D html-webpack-plugin
/index.html
as /src/main.html
Because my configs will generate a file named index.html
. Rename template as main.html
avoids possible confusions
// ... 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')
})
]
}
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!