Skip to content

Commit

Permalink
feat: Allow to return async template parameters
Browse files Browse the repository at this point in the history
  • Loading branch information
jantimon committed Sep 11, 2018
1 parent 74774eb commit 99f9362
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 20 deletions.
40 changes: 21 additions & 19 deletions index.js
Expand Up @@ -336,17 +336,20 @@ class HtmlWebpackPlugin {
headTags: HtmlTagObject[],
bodyTags: HtmlTagObject[]
}} assetTags
* @returns {{[key: any]: any}}
* @returns {Promise<{[key: any]: any}>}
*/
getTemplateParameters (compilation, assets, assetTags) {
if (this.options.templateParameters === false) {
return {};
const templateParameters = this.options.templateParameters;
if (templateParameters === false) {
return Promise.resolve({});
}
if (typeof this.options.templateParameters === 'function') {
return this.options.templateParameters(compilation, assets, assetTags, this.options);
if (typeof templateParameters === 'function') {
return Promise
.resolve()
.then(() => templateParameters(compilation, assets, assetTags, this.options));
}
if (typeof this.options.templateParameters === 'object') {
return this.options.templateParameters;
if (typeof templateParameters === 'object') {
return Promise.resolve(templateParameters);
}
throw new Error('templateParameters has to be either a function or an object');
}
Expand All @@ -372,18 +375,17 @@ class HtmlWebpackPlugin {
*/
executeTemplate (templateFunction, assets, assetTags, compilation) {
// Template processing
const templateParams = this.getTemplateParameters(compilation, assets, assetTags);
/** @type {string|Promise<string>} */
let html = '';
try {
html = templateFunction(templateParams);
} catch (e) {
compilation.errors.push(new Error('Template execution failed: ' + e));
return Promise.reject(e);
}
// If html is a promise return the promise
// If html is a string turn it into a promise
return Promise.resolve().then(() => html);
const templateParamsPromise = this.getTemplateParameters(compilation, assets, assetTags);
return templateParamsPromise.then((templateParams) => {
try {
// If html is a promise return the promise
// If html is a string turn it into a promise
return templateFunction(templateParams);
} catch (e) {
compilation.errors.push(new Error('Template execution failed: ' + e));
return Promise.reject(e);
}
});
}

/**
Expand Down
20 changes: 20 additions & 0 deletions spec/basic.spec.js
Expand Up @@ -1743,6 +1743,26 @@ describe('HtmlWebpackPlugin', () => {
}, ['templateParams keys: "foo"'], null, done);
});

it('should allow to set specific template parameters using a async function', done => {
testHtmlPlugin({
mode: 'production',
entry: path.join(__dirname, 'fixtures/index.js'),
output: {
path: OUTPUT_DIR,
filename: 'index_bundle.js'
},
plugins: [
new HtmlWebpackPlugin({
template: path.join(__dirname, 'fixtures/templateParam.js'),
inject: false,
templateParameters: function () {
return Promise.resolve({ 'foo': 'bar' });
}
})
]
}, ['templateParams keys: "foo"'], null, done);
});

it('should not treat templateContent set to an empty string as missing', done => {
testHtmlPlugin({
mode: 'production',
Expand Down
3 changes: 2 additions & 1 deletion typings.d.ts
Expand Up @@ -24,7 +24,8 @@ interface HtmlWebpackPluginOptions {
*/
templateParameters:
false // Pass an empty object to the template function
| ((compilation: any, assets, assetTags: { headTags: Array<HtmlTagObject>, bodyTags: Array<HtmlTagObject> }, options: HtmlWebpackPluginOptions) => {})
| ((compilation: any, assets, assetTags: { headTags: Array<HtmlTagObject>, bodyTags: Array<HtmlTagObject> }, options: HtmlWebpackPluginOptions) => {[option: string]: any})
| ((compilation: any, assets, assetTags: { headTags: Array<HtmlTagObject>, bodyTags: Array<HtmlTagObject> }, options: HtmlWebpackPluginOptions) => Promise<{[option: string]: any}>)
| {[option: string]: any}
/**
* The file to write the HTML to.
Expand Down

0 comments on commit 99f9362

Please sign in to comment.