Search code examples
javascriptwebpackconfigchunks

How to properly setup webpack config to include common chunks used in multiple page (and entry) app?


Imagine having below structure of html files:

./home.html
./settings.html
./contact.html

Also having below js files

./nav.js <-- common - used in all html files
./home.js <-- used only in home.html, below follow the same rule
./settings.js
./contact.js

And some modules from node_modules:

"jquery" "moment"

that are being imported as if when required:

./home.js
import $ from "jquery";
(...)

I have setup webpack to have each entry point as each file name. Now what would be the way to include common js files such as `./nav.js" into each file?

entry: {
  home: "./resources/js/sections/home.js",
  settings: "./resources/js/sections/settings.js",
  (...)
} 
(...)
output: {
  filename: '[name].js',
}

// Option A

Import raw nav.js like another module in every subpage (home.js, contact.js, settings.js)

import nav from ./nav.js
nav();

// Option B

create another entry for ./nav.js and manually add bundled nav.js to each html alongside other bundled files.

entry: {
  (...)
  nav: "./resources/js/sections/nav.js"
}

Solution

  • You may use HtmlWebPackPlugin in order to append scripts dynamically to your HTML pages.

    First of all install the plugin:

    npm install html-loader html-webpack-plugin --save-dev
    

    Then use the config:

    const HtmlWebPackPlugin = require("html-webpack-plugin");
    
    module.exports = {
      entry: {
        nav: './resources/js/sections/nav.js',
        home: './resources/js/sections/home.js',
        settings: './resources/js/sections/settings.js',
        contact: './resources/js/sections/contact.js',
      },
      output: {
        filename: '[name].js',
        path: path.resolve(__dirname, 'dist'), // folder where all tranformed files will be placed
      },
      rules: [
        {
          test: /\.html$/,
          use: [{ 
            loader: "html-loader", 
            options: { minimize: true } 
          }]
        }
      ],
      plugins: [
        // create an instance of HtmlWebPackPlugin for every page of a multipage website
        new HtmlWebPackPlugin({
          template: "./resources/html/home.html", // take html from this path
          filename: "./home.html", // name it 'home.html' and insert to the root of output folder
          chunks: ['nav', 'home'] // insert dymamically nav.js and home.js to home.html
        }),
        new HtmlWebPackPlugin({
          template: "./resources/html/settings.html",
          filename: "./settings.html",
          chunks: ['nav', 'settings']
        }),
        new HtmlWebPackPlugin({
          template: "./resources/html/contact.html",
          filename: "./contact.html",
          chunks: ['nav', 'contact']
        }),
      ]
    }