1

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 2

0

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.

Sign up to request clarification or add additional context in comments.

2 Comments

The only piece of this that I am missing is getting the files from the modules directory unfortunately. Any thoughts on that?
@idontwantnoscrubs I was thinking you could read the folder by getting its path like path.resolve(_dirname, 'src/js/modules)` and then use readdir() on that path. Or perhaps am I missing something?
0

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.

1 Comment

This did not work, it’s saying entries is undefined. But also it does not solve the problem of not having to edit the config file every time we add a new module. Any thoughts?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.