20

I want to create multiple entry points for a website, which is pretty easily done in Webpack using an object for the entry property, like here.

But as the site grows (and it inevitably will) having to add each entry point seems cumbersome and prone to error. So I'd like to simply point at a directory and say "here are all the entry points."

So I've cooked this up:

var path = require('path');
var fs = require('fs');
var entryDir = path.resolve(__dirname, '../source/js');
var entries = fs.readdirSync(entryDir);
var entryMap = {};
entries.forEach(function(entry){
    var stat = fs.statSync(entryDir + '/' + entry);
    if (stat && !stat.isDirectory()) {
        var name = entry.substr(0, entry.length -1);
        entryMap[name] = entryDir + '/' + entry;
    }
});

module.exports = {
  entry: entryMap,
  output: {
    path: path.resolve(__dirname, '../static/js'),
    filename: "[name]"
  },
...

This works fine, but is there a feature or configuration option in Webpack that would handle this for me?

j boschiero
  • 480
  • 1
  • 3
  • 13
  • Does this link help? [How to load all files in a subdirectories using webpack without require statements](http://stackoverflow.com/questions/29421409/how-to-load-all-files-in-a-subdirectories-using-webpack-without-require-statemen) – Craig McKenna Feb 03 '16 at 06:43

3 Answers3

30

I think glob is the right way to go here (AFAIK webpack wont do this for you). This is what I ended up with, it will find all files in a directory and create an entry with a name matching the file:

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

module.exports = {
  entry: glob.sync('../source/js/**.js').reduce(function(obj, el){
     obj[path.parse(el).name] = el;
     return obj
  },{}),
  output: {
    path: path.resolve(__dirname, '../static/js'),
    filename: "[name]"
  },
...

adapt the search path to meet your specific needs. It might also be useful to pass in {cwd: someRoot} as the second argument to sync if you have a special scripts directory which will make this the new root of relative path searches.

undefined
  • 33,537
  • 22
  • 129
  • 198
3

In my opinion, only a little Node skill is needed, and it doesn't have to be that complicated.

const webpack = require('webpack');
const path = require('path');
const fs = require('fs');

const fileNames = fs.readdirSync('./src').reduce((acc, v) => ({ ...acc, [v]: `./src/${v}` }), {});

const config = {
  entry: fileNames,
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: '[name]',
  },
};

module.exports = config;
weiya ou
  • 2,730
  • 1
  • 16
  • 24
  • Good solution that doesn't require a dependency. The downside is that you will generate extra output files if there are non-`*.js` files in specified folder, which can be solved by additional filtering. You also have to have the path to the folder written two times, which is prone to errors, but you can have a separate constant for that – Vasiliy Artamonov Jan 13 '22 at 15:48
  • Thank you. Was searching for a way that didn't require another dependency. – Robo Mop Jun 16 '22 at 14:35
2

I have used Glob for this.

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

module.exports = {
  entry: { 'app' : glob.sync('./scripts/**/*.ts*') },
  output: {
    path: path.join(__dirname, '/wwwroot/dist'),
    filename: '[name].bundle.js',
    sourceMapFilename: '[name].map'
  },
  module: {
    rules: [
      {
        test: /\.tsx?$/,
        loader: 'ts-loader',
        exclude: /node_modules/,
      }
    ]
  },
  resolve: {
    extensions: [".ts", ".js"]
  }
};
  • This configuration will create a single entry point, which includes all the necessary files and outputs a single bundle. The question is about creating a single entry point for each `*.js` file, so that on the output there are as many bundles, as the number of source files – Vasiliy Artamonov Jan 13 '22 at 15:39