How to set multiple file entry and output in project with webpack?
Javascriptnode.jsWebpackJavascript 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
.
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`
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.
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;
}, {}),
...