WebPack JavaScript File Loading Twice
Posted: May 1, 2025 | Categories: Web Development
I was playing around with my JMW Demos site the other day and noticed that when I clicked the Call Cloud Function button on the page that the code executed twice.
The effect was that the SweetAlert dialog that displayed the results opened, then closed and opened again. Monitoring the console, I saw that the button click event executed twice. Sigh, weirdness.
I recognized that this problem sometimes arises when I forget to add a preventDefault
call in my button's event handler:
event.preventDefault();
I checked my code and the preventDefault
was there, so that wasn't the problem.
I'm not going to describe all of my troubleshooting steps, but I ultimately tied the problem to a problem with WebPack.
I wrote the app in WebStorm using the HTML5 Boilerplate template. I don't know much about WebPack, but it was an easy option to build a starter project in WebStorm.
The template automatically puts JavaScript in a file called /js/app.js
so I put all my code there and built out my project. What I didn't realize is that WebPack's HTMLWebpackPlugin
automatically packages all of the site's JavaScript into the app.js
file and adds a reference to the file at the bottom of the app's main HTML file.
My project already had a reference to the app.js
file in it:
<script src="/js/app.js"></script>
A simple solution to this problem is to comment out that line of code and let WebPack put it back later.
Unfortunately, that works for production builds, but for development builds (builds executed through npm start
) I need that reference there for the app.js
file.
Looking through the forums, I learned that I could stop WebPack from doing that by adding an inject: false
in my WebPack configuration file. If I did that, I could leave the reference to app.js
in my index.html
file and it would work correctly in Dev and Prod.
I finally figured out where to add it to my file, I opened up the webpack.config.prod.js
file and added it to the HTMLWebpackPlugin plugin settings shown below:
const { merge } = require('webpack-merge');
const common = require('./webpack.common.js');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CopyPlugin = require('copy-webpack-plugin');
module.exports = merge(common, {
mode: 'production',
plugins: [
new HtmlWebpackPlugin({
template: './index.html',
inject: false,
}),
new CopyPlugin({
patterns: [
{ from: 'img', to: 'img' },
{ from: 'icon', to: 'icon' },
{ from: 'css', to: 'css' },
{ from: 'js/vendor', to: 'js/vendor' },
{ from: 'robots.txt', to: 'robots.txt' },
{ from: '404.html', to: '404.html' },
{ from: 'site.webmanifest', to: 'site.webmanifest' },
],
}),
],
});
If this post helps you in some way, please consider buying me a coffee.