Skip to content

Commit c5beb4b

Browse files
committed
feat: filename can now be a function
1 parent 7e2b208 commit c5beb4b

File tree

4 files changed

+54
-10
lines changed

4 files changed

+54
-10
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ Allowed values are as follows:
142142
|Name|Type|Default|Description|
143143
|:--:|:--:|:-----:|:----------|
144144
|**`title`**|`{String}`|`Webpack App`|The title to use for the generated HTML document|
145-
|**`filename`**|`{String}`|`'index.html'`|The file to write the HTML to. Defaults to `index.html`. You can specify a subdirectory here too (eg: `assets/admin.html`)|
145+
|**`filename`**|`{String\|Function}`|`'index.html'`|The file to write the HTML to. Defaults to `index.html`. You can specify a subdirectory here too (eg: `assets/admin.html`). The `[name]` placeholder will be replaced with the entry name. Can also be a function e.g. `(entryName) => entryName + '.html'`. |
146146
|**`template`**|`{String}`|``|`webpack` relative or absolute path to the template. By default it will use `src/index.ejs` if it exists. Please see the [docs](https://github.com/jantimon/html-webpack-plugin/blob/master/docs/template-option.md) for details|
147147
|**`templateContent`**|`{string\|Function\|false}`|false| Can be used instead of `template` to provide an inline template - please read the [Writing Your Own Templates](https://github.com/jantimon/html-webpack-plugin#writing-your-own-templates) section |
148148
|**`templateParameters`**|`{Boolean\|Object\|Function}`| `false`| Allows to overwrite the parameters used in the template - see [example](https://github.com/jantimon/html-webpack-plugin/tree/master/examples/template-parameters) |

index.js

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -84,16 +84,23 @@ class HtmlWebpackPlugin {
8484
options.meta = Object.assign({}, options.meta, defaultMeta, userOptions.meta);
8585
}
8686

87-
// Get all filenNames to support [name]
88-
const multipleOptions = options.filename.includes('[name]')
89-
? Object.keys(compiler.options.entry).map((entryName) => ({
90-
...options,
91-
filename: options.filename.replace(/\[name\]/g, entryName)
92-
}))
93-
: [options];
87+
// entryName to fileName conversion
88+
const filenameFunction = typeof options.filename === 'function'
89+
? options.filename
90+
// Replace '[name]' with entry name
91+
: (entryName) => options.filename.replace(/\[name\]/g, entryName);
92+
93+
/** output filenames for the given entry names */
94+
const outputFileNames = new Set(Object.keys(compiler.options.entry).map(filenameFunction));
95+
96+
/** Option for every entry point */
97+
const entryOptions = Array.from(outputFileNames).map((filename) => ({
98+
...options,
99+
filename
100+
}));
94101

95102
// Hook all options into the webpack compiler
96-
multipleOptions.forEach((instanceOptions) => {
103+
entryOptions.forEach((instanceOptions) => {
97104
hookIntoCompiler(compiler, instanceOptions, this);
98105
});
99106
});

spec/basic.spec.js

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,40 @@ describe('HtmlWebpackPlugin', () => {
240240
['<script src="app_bundle.js', 'Some unique text'], null, done);
241241
});
242242

243+
it('allows to use a function to map entry names to filenames', done => {
244+
testHtmlPlugin({
245+
mode: 'production',
246+
entry: {
247+
app: path.join(__dirname, 'fixtures/index.js')
248+
},
249+
output: {
250+
path: OUTPUT_DIR,
251+
filename: '[name]_bundle.js'
252+
},
253+
plugins: [new HtmlWebpackPlugin({
254+
filename: (entry) => `${entry}.html`
255+
})]
256+
},
257+
['<script defer="defer" src="app_bundle.js'], 'app.html', done);
258+
});
259+
260+
it('allows to use [name] for file names', done => {
261+
testHtmlPlugin({
262+
mode: 'production',
263+
entry: {
264+
app: path.join(__dirname, 'fixtures/index.js')
265+
},
266+
output: {
267+
path: OUTPUT_DIR,
268+
filename: '[name]_bundle.js'
269+
},
270+
plugins: [new HtmlWebpackPlugin({
271+
filename: '[name].html'
272+
})]
273+
},
274+
['<script defer="defer" src="app_bundle.js'], 'app.html', done);
275+
});
276+
243277
it('picks up src/index.ejs by default', done => {
244278
testHtmlPlugin({
245279
mode: 'production',

typings.d.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,9 +60,12 @@ declare namespace HtmlWebpackPlugin {
6060
/**
6161
* The file to write the HTML to.
6262
* Supports subdirectories eg: `assets/admin.html`
63+
* [name] will be replaced by the entry name
64+
* Supports a function to generate the name
65+
*
6366
* @default 'index.html'
6467
*/
65-
filename: string;
68+
filename: string | ((entryName: string) => string);
6669
/**
6770
* By default the public path is set to `auto` - that way the html-webpack-plugin will try
6871
* to set the publicPath according to the current filename and the webpack publicPath setting

0 commit comments

Comments
 (0)