skip to Main Content

I am putting together a new webpack build for my project and it’s actually working pretty well. I have one problem that I’d like some help on if anyone has an idea. I have to retype all of this from my work computer so please forgive any typos.

Package.json

{
    "name": "test_webpack",
    "version": "1.0.0",
    "description": "",
    "main": "index.js",
    scripts: {
        "build": "webpack --config webpack.production.js"
        "dev": "webpack serve --config webpack.development.js"
    },
    "devDependencies": {
        "@babel/core": "^7.22.9",
        "@babel/preset-env": "^7.22.9",
        "babel-loader": "^9.1.3",
        "css-loader": "^6.8.1",
        "html-webpack-plugin": "^5.5.3",
        "mini-css-extract-plugin": "^2.7.6",
        "sass": "^1.64.1",
        "sass-loader": "^13.3.2",
        "style-loader": "^3.3.3",
        "webpack": "^5.88.2",
        "webpack-cli": "^5.1.4",
        "webpack-dev-server": "^4.15.1"
    }
}

webpack.production.js

const path = reqire('path');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');

module.exports = {
    mode: "production",
    entry: {
        "script.min": path.resolve(_dirname, 'src/js/index.js'),
        "search": path.resolve(_dirname, 'src/js/functional/modules.js'),
        "modules/carousel": path.resolve(_dirname, 'src/js/modules/carousel.js'),
        "modules/handleEmoji": path.resolve(_dirname, 'src/js/modules/handleEmoji.js'),
        "modules/modalAccordion": path.resolve(_dirname, 'src/js/modules/modalAccordion.js'),
        "modules/sliders": path.resolve(_dirname, 'src/js/modules/sliders.js'),
        "modules/tourVideo": path.resolve(_dirname, 'src/js/modules/tourVideo.js'),
        "modules/vectorSwap": path.resolve(_dirname, 'src/js/modules/vectorSwap.js')
    },
    output: {
        path: path.resolve(__dirname, 'dist'),
        filename: '[name].js',
        clean: true,
        assetModuleFilename: '[name].[ext]'
    },
    module: {
        rules: [
            {
                est:/.scss$/i,
                use: [
                    MiniCssExtractPlugin.loader, 
                    {
                        loader:'css-loader',
                        options: {url: false}
                    },
                    {loader: 'sass-loader'}
                ]
            },
            {
                test:/.js$/,
                exclude:/node_modules/,
                use: {
                    loader: 'babel-loader',
                    options: {
                        presets: ['@babel/preset-env']
                    }
                }
            },
            {
                test:/.(png|svg|jpg|jpeg|gif)$/i,
                type: 'asset/resource'
            }
        ]
    },
    plugins: [
        new MiniCssExtractPlugin({
            filename: "shared.min.css"
       })
    ]
}

question
Is there a way I can replace this…with something dynamic?:

        "modules/carousel": path.resolve(_dirname, 'src/js/modules/carousel.js'),
        "modules/handleEmoji": path.resolve(_dirname, 'src/js/modules/handleEmoji.js'),
        "modules/modalAccordion": path.resolve(_dirname, 'src/js/modules/modalAccordion.js'),
        "modules/sliders": path.resolve(_dirname, 'src/js/modules/sliders.js'),
        "modules/tourVideo": path.resolve(_dirname, 'src/js/modules/tourVideo.js'),
        "modules/vectorSwap": path.resolve(_dirname, 'src/js/modules/vectorSwap.js')

That way every file in my modules folder will individually be compiled and output. I figured out how to bundle them all together, but I need to keep them separate. For now every time we add a module, we have to add it to the webpack configuration files. Right now it outputs to a folder "modules" in the "dist" folder.

2

Answers


  1. It seems the entry option can also take in a function that returns a promise:

    {
        /**
         * The entry point(s) of the compilation.
         */
        entry: EntryNormalized;
        /**
    }
    
    /**
     * A Function returning a Promise resolving to a normalized entry.
     */
    export type EntryDynamicNormalized = () => Promise<EntryStaticNormalized>;
    /**
     * The entry point(s) of the compilation.
     */
    export type EntryNormalized = EntryDynamicNormalized | EntryStaticNormalized;
    

    In that function, you could read the files in the modules directory and generate the entry object accordingly.

    Login or Signup to reply.
  2. You can create an array of module names and then use Array.reduce() to create an object with the entry points.

    const path = require('path');
    const MiniCssExtractPlugin = require('mini-css-extract-plugin');
    
    const modules = [
      'carousel',
      'handleEmoji',
      'modalAccordion',
      'sliders',
      'tourVideo',
      'vectorSwap',
    ];
    
    const entryPoints = modules.reduce((entries, module) => {
      entries[`modules/${module}`] = path.resolve(__dirname, `src/js/modules/${module}.js`);
      return entries;
    }, {});
    
    module.exports = {
      mode: 'production',
      entry: {
        'script.min': path.resolve(__dirname, 'src/js/index.js'),
        'search': path.resolve(__dirname, 'src/js/functional/modules.js'),
        ...entryPoints, // Spread the dynamically generated entry points
      },
      output: {
        path: path.resolve(__dirname, 'dist'),
        filename: '[name].js',
        clean: true,
        assetModuleFilename: '[name].[ext]',
      },
      // Rest of the configuration remains unchanged
    };
    

    The resulting entryPoints object will look like:

    {
      "modules/carousel": "/full/path/to/src/js/modules/carousel.js",
      "modules/handleEmoji": "/full/path/to/src/js/modules/handleEmoji.js",
      "modules/modalAccordion": "/full/path/to/src/js/modules/modalAccordion.js",
      "modules/sliders": "/full/path/to/src/js/modules/sliders.js",
      "modules/tourVideo": "/full/path/to/src/js/modules/tourVideo.js",
      "modules/vectorSwap": "/full/path/to/src/js/modules/vectorSwap.js"
    }
    

    This way, you don’t have to repeat the same entry points manually, and the build configuration becomes more scalable.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search