How to set multiple file entry and output in project with webpack?

Javascriptnode.jsWebpack

Javascript Problem Overview


How to set multiple file entry/output in project with webpack?

I follow http://webpack.github.io/docs/tutorials/getting-started/ success compile if only one file in one entry/output...

directory

app
webpack.config.js
./assets
././javascripts/Administrator/Article/Create/Base.js
././javascripts/Administrator/Article/Edit/Base.js
././javascripts/Account/Index/Base.js
././javascripts/Contact/Index/Base.js
...

how to output like this?

././javascripts/Administrator/Article/Create/bundle.js
././javascripts/Administrator/Article/Edit/bundle.js
././javascripts/Account/Index/bundle.js
././javascripts/Contact/Index/bundle.js

webpack.config.js

module.exports = {
  entry: {
    'AdministratorArticleCreate':['./assets/javascripts/Administrator/Article/Create/Base.js']
  },
  output: {
    path: 
  }
   
    // if only one file
    // entry: "./assets/javascripts/Administrator/Article/Create/Base.js",
    // output: {
    //     // path: __dirname,
    //     path: "./assets/javascripts/Administrator/Article/Create/",
    //     filename: "bundle.js"
    // }
};

Javascript Solutions


Solution 1 - Javascript

For many entry points use arrays as a value of entry property:

entry: {
  app: ['./app/main.js', '.lib/index.js'],
  vendors: ['react']
}

app and vendors are arrays, so you can put there as many file paths as you need.

For output case:

output: {
  path: staticPath,
  filename: '[name].js'
}

The [name] is taken from entry properties, so if we have app and vendors as properties, we got 2 output files - app.js and vendors.js.

Documentation link

Solution 2 - Javascript

If you want to output to multiple directories, you can use the path as the entry name. For example if you want this directory structure:

apps
├── dir1
│   └── js
│       ├── main.js [entry 1]
│       └── bundle.js [output 1]
└── dir2
    ├── index.js [entry 2]
    └── foo.js [output 2]

Then try this in your module.exports:

{
  entry: {
    'dir1/js/bundle': path.resolve(__dirname, '/apps/dir1/js/main.js'),
    'dir2/foo' : path.resolve(__dirname, '/apps/dir2/index.js')
  },
  output: {
    path: path.resolve(__dirname, '/apps'),
    filename: '[name].js'
  },
  ...
}

Solution 3 - Javascript

what really solved it for me was this:

entry:  {
    app : __dirname + "/app/views/app/app.js",
    admin : __dirname + "/app/views/admin/admin.js"
}

output: {
    path: __dirname + "/public",
    filename: "[name].js"
},

Solution 4 - Javascript

You can detect multiple entries and generate separate output files by using glob sync patterns.

Put this into your webpack.config.js (without the ...)

const glob = require("glob");
...
module.exports = (env, options) => ({
  ...
  entry: glob.sync("./javascripts/**/*.js").reduce((acc, item) => {
    const path = item.split("/");
    path.pop();
    const name = path.join('/');
    acc[name] = item;
    return acc;
  }, {}),
  output: {
    filename: "[name]/bundle.js",
    path: path.resolve(__dirname, "")
  },
  ...
});

This "should" give you the desired output.

Solution 5 - Javascript

What if you want to get output files as foo.css and bar.js at the same time? the answers above seem incapable to handle this.

The sane way is to use multi-compiler. One input file one config object one output file. From this answer.

Solution 6 - Javascript

this webpack plugin web-webpack-plugin can resolve it in a sample way.

AutoWebPlugin can find all page entry in an directory,then auto config an WebPlugin for every page to output an html file,you can use it as below:

webpack config

module.exports = {
    plugins: [
        new AutoWebPlugin(
            // the directory hold all pages
            './src/', 
            {
            // the template file path used by all pages
            template: './src/template.html',
            // javascript main file for current page,if it is null will use index.js in current page directory as main file
            entity: null,
            // extract common chunk for all pages and then put it into a file named common,if it is null then not do extract action
            // achieve by CommonsChunkPlugin
            commonsChunk: 'common',
            // pre append to all page's entry
            preEntrys:['./path/to/file1.js'],
            // post append to all page's entry
            postEntrys:['./path/to/file2.js'],
        }),
    ]
};

src directory

── src
│   ├── home
│   │   └── index.js
│   ├── ie_polyfill.js
│   ├── login
│   │   └── index.js
│   ├── polyfill.js
│   ├── signup
│   │   └── index.js
│   └── template.html

output directory

├── dist
│   ├── common.js
│   ├── home.html
│   ├── home.js
│   ├── ie_polyfill.js
│   ├── login.html
│   ├── login.js
│   ├── polyfill.js
│   ├── signup.html
│   └── signup.js

AutoWebPlugin find all page home login signup directory in ./src/,for this three page home login signup will use index.js as main file and output three html file home.html login.html signup.html`

see doc:auto detect html entry

Solution 7 - Javascript

This question is 2 years old so I think the author has almost certainly moved on from this issue, but to anyone landing here more recently I had a really similar need and was able to write my own plugin to allow for dynamic output paths/names from known and/or unknown entry points.

My problem and thought process for the solution can be found here.

And the Node package itself here.

Solution 8 - Javascript

For my use case I actually needed to use different templates based on environment. To achieve this I passed in the NODE_ENV variable

module.exports = (env, argv) => {
  const ENVIRONMENT = env.NODE_ENV;
  let INDEX_HTML = 'index.html';
  if (ENVIRONMENT === 'staging') {
    INDEX_HTML = 'index-stg.html';
  }

Then:

if (NODE_ENV === 'staging') {
   INDEX_HTML = 'index-stg.html';
}

In the output:

output: {
      path: process.cwd() + '/build',
      filename: `[name].js`,
      chunkFilename: `[${HASH_MODE}].[name].js`
    },

plugins:

new HtmlWebpackPlugin({
        inject: true,
        template: `app/${INDEX_HTML}`,
      }),

Solution 9 - Javascript

Using the following, I was able to get webpack to search for typescript and sass files.

...
entry: glob
  .sync("./src/{sass,js}/**/*.{ts,scss}")
  .reduce(function (obj, el) {
    obj[path.parse(el).name] = el;
    return obj;
  }, {}),
...

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionuser1775888View Question on Stackoverflow
Solution 1 - JavascriptKaniaView Answer on Stackoverflow
Solution 2 - JavascriptPeter TsengView Answer on Stackoverflow
Solution 3 - JavascriptJoão GomesView Answer on Stackoverflow
Solution 4 - JavascriptPeterView Answer on Stackoverflow
Solution 5 - JavascripttcpiperView Answer on Stackoverflow
Solution 6 - Javascript吴浩麟View Answer on Stackoverflow
Solution 7 - JavascriptsanjsanjView Answer on Stackoverflow
Solution 8 - JavascriptllamacornView Answer on Stackoverflow
Solution 9 - JavascriptBayoView Answer on Stackoverflow