13

I am trying to bundle every angular module in webpack. My target is to have one app.js that will be bundled by webpack with this configuration:

entry: {
        app: "./app/app.js"
},
output: {
        path: "./build/ClientBin",
        filename: "bundle.js"
},

I will place this bundle script in my index.html so it will entry point of my app. Also I have many modules in ./app/components folder. Folder structure in like:

app
|--components
|  |
|  |--home
|  |  |
|  |  |--home.html
|  |  |--home.js
|--app.js
|--AppController.js

I have required home.html in home.js so when I load home.js all of its needed files will load. The problem is I have several components like home and I want to tell webpack to bundle each component separately and name it with its containing folder like home.

How can I config webpack to create these bundles and put them in ./build/components?

4 Answers 4

27

A simpler way:

Use globs in your webpack.config.js:

Here's an example:

var glob = require("glob");

module.exports = {
  entry: {
     js: glob.sync("./app/components/**/*.js"),  
  }
}
Sign up to request clarification or add additional context in comments.

5 Comments

Although the accepted answer uses out of the box tools, this is by far the simplest, and my preferred answer.
make sure to install webpack-glob with npm first. npm install webpack-glob --save-dev
Can anyone show what the entire webpack.config.js file would look like? For example, what should the output value be?
npm install webpack-glob --save-dev in my project produced +356 packages in node_modules and +23 vulnerabilities, 2 of which CRITICAL
Yeah DONT use webpack-glob. It is no longer maintained. You can just use glob
6

To have each file exported individually, you can use the following code snippet to do so:

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

const entryFiles = glob.sync('./app/components/**/*.js').reduce((previousValue, currentValue, currentIndex, array) => {
  return typeof previousValue === 'string' ?
    {
      [path.basename(previousValue, path.extname(previousValue))]: previousValue,
      [path.basename(currentValue, path.extname(currentValue))]: currentValue
    }
    :
    { ...previousValue, [path.basename(currentValue, path.extname(currentValue))]: currentValue }
})

module.exports = {
  entry: entryFiles,
  resolve: {
    extensions: [ '.js' ]
  },
  output: {
    filename: '[name].js',
    path: path.resolve(__dirname, 'build', 'ClientBin')
  }
}

Comments

4

You can achieve what you want like this:

entry: {
    home: './app/app.js',
    page: './page/app.js',
},
output: {
    path: './build/ClientBin',
    filename: '[name].js',
},

This will generate home.js and page.js at your output path. Tweak, generalize as needed. You'll probably want to extract those entry paths to a variable and so on.

Note that with a bit of tweaking you are likely able to output the bundles exactly where you want. I expect you would then use a path like ./app/components/[name] or so.

3 Comments

The problem is that I don't know how many entries I will have. I have edited the question to show my workaround, but I am searching for an out of the box solution.
Your solution looks good to me. Being a configuration driven tool Webpack doesn't really care how you generate the configuration as long as it's right.
Sounds logical! So how do I have to complete this question workflow? I mean I have to put that edited part to an answer?
3

I ended up defining entries programmatically. I wrote this in my webpack.config.js:

function getDirectories(srcpath) {
    return fs.readdirSync(srcpath).filter(function (file) {
        return fs.statSync(path.join(srcpath, file)).isDirectory();
    });
}

var entry = {
    app: "./app/app.ts",
    vendor: ["angular", "oclazyload", "angular-new-router", "lodash"]
};
var components = getDirectories("./app/components");
for (var i = 0; i < components.length; i++) {
    entry[components[i]] = "./app/components/" + components[i] + "/" + components[i] + ".ts";
}

And then used entry variable in config.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.