Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multiple dynamic entry scripts in webpack?

Let's say I have an app structure like this

app/
   modules/
      module1/
         <other files>
         script.js
      module2/
         <other files>
         script.js
      module3/
         <other files>
         script.js
   lib/
      <some common/shared scripts to import from>
public/
   js/

How can I configure webpack to bundle and output each script.js (which will be importing various libs/utilities from the common lib folder) into a structure like this?

e.g.

public/js/module1/script.js
public/js/module2/script.js

But without individually defining each entry file? Something like gulp does with /**/*.js syntax?

My goal is NOT to have to maintain my webpack.config.js file each time I add a new module/component.

like image 834
AgmLauncher Avatar asked Jun 14 '16 01:06

AgmLauncher


People also ask

Can webpack have multiple entry points?

webpack.config.jsWe can also pass an array of file paths to the entry property which creates what is known as a "multi-main entry". This is useful when you would like to inject multiple dependent files together and graph their dependencies into one "chunk".

How do I bundle multiple js files in webpack?

How do I bundle multiple js files in webpack? You can bundle your JavaScript using the CLI command by providing an entry file and output path. Webpack will automatically resolve all dependencies from import and require and bundle them into a single output together with your app's script.

How does webpack handle dynamic imports?

Whenever you import a file in your code, Webpack will look for it in the project directory and copy it to the build folder with a new name, then Webpack replaces the import code in your bundled JavaScript file with the path to the newly copied file.

What is __ Dirname in webpack?

The __dirname in a node script returns the path of the folder where the current JavaScript file resides. __filename and __dirname are used to get the filename and directory name of the currently executing file.


1 Answers

You need glob package and set entry and output in your webpack.config.js. Example when webpack.config.js in root dir.

var webpack = require('webpack');
var glob = require('glob');

//Generate object for webpack entry
//rename './app/modules/module1/script.js' -> 'module1/script'
var entryObject = glob.sync('./app/modules/**/script.js').reduce(
    function (entries, entry) {
        var matchForRename = /^\.\/app\/modules\/([\w\d_]+\/script)\.js$/g.exec(entry);

        if (matchForRename !== null && typeof matchForRename[1] !== 'undefined') {
            entries[matchForRename[1]] = entry;
        }

        return entries;
    }, 
    {}
);

module.exports = {
    ...
    entry: entryObject,//{'moduleName/script': './app/modules/moduleName/script.js', ...}
    output: {
        path: __dirname + '/public/js',
        filename: '[name].js'//'moduleName/script.js', [name] - key from entryObject
    }
    ...
};

If you will have error with fs like " can't resolve 'fs' " add option

node: {
    fs: "empty"
}

Also, you can bundle your files from <other files> into public script.js using other entryObject.

var entryObject = glob.sync('./app/modules/**/*.js').reduce(
    function (entries, entry) {
        var matchForRename = /^\.\/app\/modules\/([\w\d_]+)\/.+\.js$/g.exec(entry);

        if (matchForRename !== null && typeof matchForRename[1] !== 'undefined') {
            var entryName = matchForRename[1] + '/script';

            if (typeof entries[entryName] !== 'undefined') {
                entries[entryName].push(entry);
            } else {
                entries[entryName] = [entry];
            }

        }

        return entries;
    },
    {}
);
like image 121
Vlad Latish Avatar answered Sep 17 '22 13:09

Vlad Latish