Bundle A Static Website Using Webpack

Intro and Preparation

Let’s bundle that static website you have using webpack, to minimize the number of HTTP request and increase its performance. The goal is straight forward, to have this:

<html>
    <head>
        ...
    </head>

    <body>
        ...
        <script src="./dist/bundle.js"></script>
    </body>
</html>

instead of this:

<html>
    <head>
        <link rel="stylesheet" href="./assets/main.css">
    </head>

    <body>
        ...
        <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
        <script src="./assets/main.js"></script>
    </body>
</html>

I’ll start with the following simple project structure:

project
|__ index.html
|__ assets
    |__ main.css
    |__ main.js

You can see the content of those files here. The project requires jQuery as an external library and at the end the project looks like this:

project
|__ index.html
|__ assets
|   |__ main.css
|   |__ main.js
|__dist
|   |__ bundle.js
|__ node_modules
|   |__ *modules-for-development*
|__ app.js
|__ package.json
|__ package-lock.json
|__ webpack.config.js

HOWEVER, we’re going to use only index.html and dist/bundle.js for the final static website.

The Steps

  1. Go the project directory
  2. Install webpack and jQuery
    npm i -D webpack webpack-cli jquery
    
  3. Install style-loader and css-loader to handle css
    npm i -D style-loader css-loader
    
  4. Create webpack.config.js
    // webpack.config.js
    const webpack = require('webpack')
    
    module.exports = {
        entry: './app.js', // the entry point, see step #4
        mode: 'production',
        output: {
            path: `${__dirname}/dist`,
            filename: 'bundle.js',
        },
        module: {
            rules: [
                {
                    test: /\.css$/,
                    use: [
                        'style-loader', // inject CSS to page
                        'css-loader', // translates CSS into CommonJS modules
                    ],
                },
            ],
        },
        plugins: [
            new webpack.ProvidePlugin({
                $: "jquery", // to make sure jquery is globally accessable
                jQuery: "jquery",
            })
        ]
    };
    
  5. Create app.js as the entry point to bundle the website. Remember, the order is important. Since main.js requires jQuery, it must be put after jQuery.
    // app.js
    require('./assets/main.css')
    window.$ = require('jquery');
    require('./assets/main.js')
    
  6. Add build script to package.json
    // package.json
    {
        "scripts": {
            "build": "webpack"
        },
        "devDependencies": {
            "css-loader": "^6.7.1",
            "jquery": "^3.6.0",
            "style-loader": "^3.3.1",
            "webpack": "^5.73.0",
            "webpack-cli": "^4.10.0"
        }
    }
    
  7. Build the project
    npm run build
    
    If everything runs well, webpack bundles assets/main.css, assets/main.js, and jQuery all together into a single file called bundle.js. The generated file should appear under a directory called dist.
  8. Update index.html by removing the references to assets/main.css, assets/main.js and jQuery, and put a new reference to dist/bundle.js
  9. DONE. Now you just need to put index.html and dist/bundle.js to your web hosting and keep the rest for the development.

Git: https://github.com/TheMaggieSimpson/bundle-staticweb-webpack/tree/master/css-js-jquery

References: