Using webpack with multiple file output

CSS

Using webpack with multiple file output

With default configuration if you use webpack you will endup creating single JS and CSS file. But there are situations where you need to create multiple output files to avoid loading unnecessary files to the client side. For example you have a backend portal / dashboard and public website. Packing all the assets in single file can be unnecessary as you are increasing the loading time even for public users.

I was doing some search on how to configure this and couldn’t find any quick article matching my search. So I explored using the configurations and found two ways to achieve this. I prefer the second approach as I only need to maintain one config file.

Approach 1

Using multiple webpack config files for each modules and passing the config file while running the webpack command.

npx webpack --mode production --config .\webpack.games.js

Here we pass the config file name which has got the configurations for packaging files related to the games.

In this approach you just clone the default webpack.config.js file with the name you want and modify the source and output file paths. Below is the code I have used with the above file.

const path = require("path");
const TerserPlugin = require("terser-webpack-plugin"); // For minifying the JS
const mode = process.env.NODE_ENV || "development";

module.exports = {
  entry: {
    main: [
      // "./application/modules/play/js/word-data.js",
      "./application/modules/play/js/word-quiz-source.js",
    ], // Merge all JS files for the main bundle
  },

  // Output: Specify the name and location of the bundled file
  output: {
    filename: "word-quiz.js", // Output file for the word quiz
    path: path.resolve(__dirname, "./application/modules/play/js"), // Output directory for word-quiz-source.js
  },

  // Minification configuration for production builds
  optimization: {
    minimize: true,
    minimizer: [
      new TerserPlugin({
        terserOptions: {
          compress: {
            drop_console: true, // Optionally remove console logs in production
          },
        },
      }),
    ],
  },

  // Resolve extensions (optional)
  resolve: {
    extensions: [".js"], // Resolve .js files automatically
  },

  // Mode (development or production)
  mode: mode, // Enable optimizations (minification, etc.)
};

Approach 2

In this approach we will use single webpack file with different configurations.

const path = require("path");
const TerserPlugin = require("terser-webpack-plugin"); // For minifying the JS
const mode = process.env.NODE_ENV || "development";
const MiniCssExtractPlugin = require("mini-css-extract-plugin"); // For extracting CSS

module.exports = {
  entry: {
    main: [
      "./assets/css/mystyle.css",
      "./application/modules/blog/assets/style.css",
    ], 
    "question-components": [
      "./application/modules/exam/js/question-components.js",
    ],
  },

  // Output: Specify the name and location of the bundled file
  output: {
    filename: "js/[name].min.js", // Minified output file
    path: path.resolve(__dirname, "./assets/"), // Output directory
  },

  // Minification configuration for production builds
  optimization: {
    minimize: true,
    minimizer: [
      new TerserPlugin({
        terserOptions: {
          compress: {
            drop_console: true, // Optionally remove console logs in production
          },
        },
      }),
    ],
  },

  module: {
    rules: [
      {
        test: /\.css$/i,
        use: [MiniCssExtractPlugin.loader, "css-loader"], // Extract CSS
      },
    ],
  },

  plugins: [
    new MiniCssExtractPlugin({
      filename: "css/mystyles.min.css", // This will output CSS files with the same name as the entry key
      // path: path.resolve(__dirname, "./assets/css"), // Output directory
    }),
  ],

  // Resolve extensions (optional)
  resolve: {
    extensions: [".js", ".css"], // Resolve .js and .css files automatically
  },

  // Mode (development or production)
  mode: mode, // Enable optimizations (minification, etc.)
};

If you can see inside the entry blog we have added two attributes called main and question-components and each contain the list of entry files. Also if you see the output blog we use the output file name as “js/[name].min.js” for js files. Also inside MiniCssExtractPlugin plugin block we have defined output file name as  “css/mystyles.min.css”. In this example we use dynamic file name for JS file output and single filename for css file output. So when we run the webpack command we will see three files. Also in the file name we have given sub directories as js and css the files will be created inside two sub directories based on the file type.

npx webpack --mode production

I wanted to document this as this has helped me to achive what I wanted in my project and documented here as this could help you as well.

A full stack developer learning a developing web applications since my university time for more than 20 years now and Pega Certified Lead System Architect (since 2013) with nearly 16 years experience in Pega.

Leave a Reply

Your email address will not be published. Required fields are marked *

Back To Top