Reputation: 20172
For some reason, I end up with two scripts in index.html outputted to my dist. Not sure what part of my webpack script is doing this.
index.html (before webpack is run)
<!DOCTYPE html>
<html lang="en">
<head>
<title>My Title</title>
<meta charset="utf-8">
<link rel="stylesheet" type="text/css" href="https://ink.global.ssl.fastly.net/3.1.10/css/ink.min.css">
<script src="https://ink.global.ssl.fastly.net/3.1.10/js/ink-all.min.js"></script>
<script src="https://ink.global.ssl.fastly.net/3.1.10/js/autoload.js"></script>
<!--[if lt IE 9 ]>
<link rel="stylesheet" href="ink-ie.min.css" type="text/css">
<![endif]-->
<link rel="stylesheet" type="text/css" href="/lib/css/master.css" />
</head>
<body>
<div id="app"></div>
<script src="/scripts/app.bundle.js"></script>
</body>
</html>
index.html (generated by webpack - notice there are now two scripts at the end for bundle. One with a hash, one without)
<!doctype html><html lang="en"><head><title>My Title</title><meta charset="utf-8"><link rel="stylesheet" href="https://ink.global.ssl.fastly.net/3.1.10/css/ink.min.css"><script src="https://ink.global.ssl.fastly.net/3.1.10/js/ink-all.min.js"></script><script src="https://ink.global.ssl.fastly.net/3.1.10/js/autoload.js"></script><!--[if lt IE 9 ]>
<link rel="stylesheet" href="ink-ie.min.css" type="text/css">
<![endif]--><link rel="stylesheet" href="/lib/css/master.css"/><link href="/lib/css/main.19f6cefd31f76cb95333.css?19f6cefd31f76cb95333" rel="stylesheet"></head><body><div id="app"></div><script src="/scripts/app.bundle.js"></script><script src="app.19f6cefd31f76cb95333.bundle.js?19f6cefd31f76cb95333"></script></body></html>
webpack.config.js
const path = require('path');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const TerserJSPlugin = require('terser-webpack-plugin');
const HtmlWebPackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
const CopyPlugin = require('copy-webpack-plugin');
const isProduction = process.env.NODE_ENV === 'production';
const html = () => {
return new HtmlWebPackPlugin({
template: './src/client/index.html',
filename: './index.html',
hash: true,
});
};
const copyAllOtherDistFiles = () => {
return new CopyPlugin({
patterns: [
{ from: 'src/client/assets', to: 'assets' },
{ from: 'src/server.js', to: './' },
{ from: 'src/api.js', to: './' },
{ from: 'package.json', to: './' },
{
from: 'src/shared',
to: './shared',
globOptions: {
ignore: ['**/*supressed.json'],
},
},
],
});
};
module.exports = {
entry: './src/client/index.js',
output: {
filename: 'app.[hash].bundle.js',
path: path.resolve(__dirname, 'dist'),
},
devServer: {
writeToDisk: true,
},
target: 'web',
devtool: 'source-map',
optimization: {
minimizer: [new TerserJSPlugin({}), new OptimizeCSSAssetsPlugin({})],
splitChunks: {
cacheGroups: {
styles: {
name: 'styles',
test: /\.css$/,
chunks: 'all',
enforce: true,
},
},
},
},
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
},
},
{
test: /\.html$/,
use: [
{
loader: 'html-loader',
},
],
},
{
test: /\.less$/,
use: [
isProduction ? MiniCssExtractPlugin.loader : 'style-loader',
'css-loader',
'less-loader',
],
},
{
test: /\.css$/i,
use: [
{ loader: 'style-loader', options: { injectType: 'linkTag' } },
'css-loader',
],
},
{
test: /\.(png|svg|jpg|gif)$/,
use: ['url-loader'],
},
],
},
plugins: isProduction
? [
new CleanWebpackPlugin(),
new MiniCssExtractPlugin({
filename: isProduction ? '/lib/css/main.[hash].css' : 'main.css',
}),
html(),
copyAllOtherDistFiles(),
]
: [new CleanWebpackPlugin(), html(), copyAllOtherDistFiles()],
};
Upvotes: 0
Views: 949
Reputation: 116
The reason you get two scripts at the end of your bundle because you added it once in your template file and once as your webpack entry file.
In your template file:
<body>
<div id="app"></div>
<!-- You should remove the next line -->
<script src="/scripts/app.bundle.js"></script>
</body>
In your webpack config:
module.exports = {
// Webpack will automatically import it in your HTML template.
entry: './src/client/index.js',
output: {
filename: 'app.[hash].bundle.js',
path: path.resolve(__dirname, 'dist'),
},
...
I recommend you to remove the script tag in the template file so you conserve the file hash.
If we take look at the repo of the plugin, in the usage section :
The plugin will generate an HTML5 file for you that includes all your webpack bundles in the body using script tags. Just add the plugin to your webpack ...
Upvotes: 1