Quantcast
Channel: Webkul Blog
Viewing all articles
Browse latest Browse all 5490

Dynamic entries in WebPack

$
0
0

Why?

Why we need dynamic entries?
Assuming that we have a file structure for a project is something.

Project
--  Modules
|    -- Modules_1
|        -- Assets
|            -- Js
|                -- a.js
|                -- b.js
|    -- Module_2
|        -- Assets
|            -- Js
|                -- c.js
|                -- d.js

We have to create entry for each of the Js file and every time we add any new file.

Solution

We can create a single entry in webpack.config.js which will include every assets file.
We can create dynamic entries all because of the entry property of Webpack config.
entry property can accept:

  • String :
    './Modules/Modules_1/Assets/Js/a.js'
  • Array of Strings:
    [
    './Modules/Modules_1/Assets/Js/a.js',
    './Modules/Modules_1/Assets/Js/b.js'
    ]

  • Object:
    {
    'js/a': './Modules/Modules_1/Assets/Js/a.js',
    'js/b': './Modules/Modules_1/Assets/Js/b.js'
    }

Now, coming to the dynamic part

We use ‘glob’ for this, When passed a string, Glob will attempt to find each file that matches the path given and return each path to the file as string array.

webpack.config.js

var Encore = require('@symfony/webpack-encore');
/**
 * When passed a string, Glob will attempt to find each file that matches the
 * path given and return each path to the file as string[]
 */
const glob = require('glob')

Encore
    // the project directory where compiled assets will be stored
    .setOutputPath('public/resource/')
    .setPublicPath('/resource')
    .enableSourceMaps(!Encore.isProduction())

   // dynamic entry
   glob.sync('./Modules/**/assets/js/**/*.js').reduce((acc, item) => {
       /**
         * The "[name]" placeholder in the "output" property will be replaced
         * with each key name in our "name" object. We replace .js so that we can use    
         * our js file with its name. ex path/a.js as path/a
         */
       var name = item.replace(/\.\/Modules\/|\.js/gi, '');
       acc[name] = item;
       // add entry for each js file 
       Encore.addEntry(name, item);
       return acc;
   }, {});

  // module.exports = Encore.getWebpackConfig();
  const config = Encore.getWebpackConfig();
  
  // Export the final configuration
  module.exports = config;

The above code is used for dynamic entry in symfony/webpack-encore
Similarly we can use in core webpack using below code for entry

entry: glob.sync('./Modules/**/assets/js/**/*.js').reduce((acc, path) => {
        /**
         * The "[name]" placeholder in the "output" property will be replaced
         * with each key name in our "name" object. We replace .js so that we can use    
         * our js file with its name. ex path/a.js as path/a
         */
        var name = item.replace(/\.\/Modules\/|\.js/gi, '');
        /**
         * each js file in the directory will be added to object
         */
        acc[name] = item;
        return acc
    }, {}),

Explanation

  • Glob plays an important role here, we pass a string ‘./Modules/**/assets/js/**/*.js’ this string tells glob to search for .js file in assets/js directory inside Modules
  • Glob return each matched file path.
  • Then we replace .js extension as to define the path with the same name as our file name.
  • create entry.

That’s all to create dynamic entry with WebPack.


Viewing all articles
Browse latest Browse all 5490

Trending Articles