gjvatsalya
gjvatsalya

Reputation: 1169

Is it possible to dynamically create an entry point for each folder in the webpack config?

This is my current folder structure:

-- src
   -- js
      -- page 1
         -- index.js
         -- actions
         -- components
         -- reducers
      -- page 2
         -- index.js
         -- actions
         -- components
         -- reducers
      -- page 3
         -- index.js
         -- actions
         -- components
         -- reducers

And this is my webpack.config.js:

module.exports = {
    entry: {
        page1: './src/js/page1/index.js',
        page2: './src/js/page2/index.js',
        page3: './src/js/page3/index.js',
    },
    output: {
        path: './assets/javascripts',
        publicPath: '/assets/',
        filename: '[name].js'
    }
}

So every time I create a new page, I have to add another line in my entry object. This may get very big and very messy.

So is there a way to just have webpack loop through all the folders in the /src/js/ folder and automatically make the index.js in the corresponding folder the entry point?

Upvotes: 3

Views: 4424

Answers (3)

Wok Le
Wok Le

Reputation: 53

This is how I did for nested directory using glob:

const path = require('path');
const glob = require('glob')

let entries = glob.sync('./CLientApp/src/js/**/**/**/*.js').reduce((entries, entry) => {
    let arr = []    
    let entryName = ""

    const SplitPathIntoArry = (path) =>{
        let splitted = []
        splitted = path.split('/')
        if(splitted.length > 4){
            splitted.splice(0, 4)
        }
        return splitted
    }

    arr = SplitPathIntoArry(entry)

    let entryName2 = ""
    if(arr.length > 1){
        arr.forEach((o, i) => {
            entryName2 += `/${o}`
        });
    }

    if(entryName2.length > 1){
        entryName2 = entryName2.slice(0, -3)
        entryName2 = entryName2.substring(1)
        entryName = entryName2
    }else{
        entryName = path.parse(entry).name
    }

    entries[entryName] = entry

    return entries
}, {});

module.exports = {
    mode: 'development',
    entry: entries,
    output: {
        filename: 'js/[name].entry.js',
        path: path.resolve(__dirname, 'dist'),
        clean: true,
        publicPath: ""
    },
    
}

Upvotes: 0

Patrick Krawczykowski
Patrick Krawczykowski

Reputation: 29

To add to the answer above mine since I cannot comment. Using the path.basename method will give you clean, un-nested file names.

const glob = require("glob")
const path = require("path")

const entry = glob
    .sync("src/js/**/*.js")
    .reduce((acc, curr) => {
        return {...acc, [path.basename(curr, ".js")]: curr}
    })

module.exports = {
    entry,
    output: {
        path: './assets/javascripts',
        publicPath: '/assets/',
        filename: '[name].js'
    }
}

Upvotes: 2

flipchart
flipchart

Reputation: 6578

Use the glob package:

const glob = require("glob");

const entry = glob.sync("src/js/**/*.js")
    .reduce((x, y) => Object.assign(x, {
        [y]: y,
    }), {});

module.exports = {
    entry,
    output: {
        path: './assets/javascripts',
        publicPath: '/assets/',
        filename: '[name].js'
    }
}

This iterates over your whole folder structure and grabs each js file and adds it to the entry hash

Upvotes: 11

Related Questions