Skip to content

Commit a524e8f

Browse files
wingrunr21jantimon
authored andcommittedJan 11, 2019
feat: Add typings to package.json
See #1132
1 parent 342c4e8 commit a524e8f

File tree

5 files changed

+223
-117
lines changed

5 files changed

+223
-117
lines changed
 

‎index.js

+14-12
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
// @ts-check
22
// Import types
3-
/* eslint-disable */
4-
/// <reference path="./typings.d.ts" />
5-
/* eslint-enable */
3+
/** @typedef {import("./typings").HtmlTagObject} HtmlTagObject */
4+
/** @typedef {import("./typings").Options} HtmlWebpackOptions */
5+
/** @typedef {import("./typings").ProcessedOptions} ProcessedHtmlWebpackOptions */
6+
/** @typedef {import("./typings").TemplateParameter} TemplateParameter */
67
/** @typedef {import("webpack/lib/Compiler.js")} WebpackCompiler */
78
/** @typedef {import("webpack/lib/Compilation.js")} WebpackCompilation */
89
'use strict';
@@ -28,14 +29,14 @@ const fsReadFileAsync = promisify(fs.readFile);
2829

2930
class HtmlWebpackPlugin {
3031
/**
31-
* @param {Partial<HtmlWebpackPluginOptions>} [options]
32+
* @param {HtmlWebpackOptions} [options]
3233
*/
3334
constructor (options) {
34-
/** @type {Partial<HtmlWebpackPluginOptions>} */
35+
/** @type {HtmlWebpackOptions} */
3536
const userOptions = options || {};
3637

3738
// Default options
38-
/** @type {HtmlWebpackPluginOptions} */
39+
/** @type {ProcessedHtmlWebpackOptions} */
3940
const defaultOptions = {
4041
template: path.join(__dirname, 'default_index.ejs'),
4142
templateContent: false,
@@ -56,7 +57,7 @@ class HtmlWebpackPlugin {
5657
xhtml: false
5758
};
5859

59-
/** @type {HtmlWebpackPluginOptions} */
60+
/** @type {ProcessedHtmlWebpackOptions} */
6061
this.options = Object.assign(defaultOptions, userOptions);
6162

6263
// Default metaOptions if no template is provided
@@ -112,6 +113,7 @@ class HtmlWebpackPlugin {
112113

113114
const minify = this.options.minify;
114115
if (minify === true || (minify === undefined && isProductionLikeMode)) {
116+
/** @type { import('html-minifier').Options } */
115117
this.options.minify = {
116118
// https://github.com/kangax/html-minifier#options-quick-reference
117119
collapseWhitespace: true,
@@ -381,7 +383,7 @@ class HtmlWebpackPlugin {
381383
/**
382384
* This function renders the actual html by executing the template function
383385
*
384-
* @param {(templatePArameters) => string | Promise<string>} templateFunction
386+
* @param {(templateParameters) => string | Promise<string>} templateFunction
385387
* @param {{
386388
publicPath: string,
387389
js: Array<string>,
@@ -628,7 +630,7 @@ class HtmlWebpackPlugin {
628630
*
629631
* @param {string|false} faviconFilePath
630632
* @param {WebpackCompilation} compilation
631-
* @parma {string} publicPath
633+
* @param {string} publicPath
632634
* @returns {Promise<string|undefined>}
633635
*/
634636
getFaviconPublicPath (faviconFilePath, compilation, publicPath) {
@@ -877,7 +879,7 @@ class HtmlWebpackPlugin {
877879
/**
878880
* Helper to return the absolute template path with a fallback loader
879881
* @param {string} template
880-
* The path to the tempalate e.g. './index.html'
882+
* The path to the template e.g. './index.html'
881883
* @param {string} context
882884
* The webpack base resolution path for relative paths e.g. process.cwd()
883885
*/
@@ -920,8 +922,8 @@ class HtmlWebpackPlugin {
920922
headTags: HtmlTagObject[],
921923
bodyTags: HtmlTagObject[]
922924
}} assetTags
923-
* @param {HtmlWebpackPluginOptions} options
924-
* @returns {HtmlWebpackPluginTemplateParameter}
925+
* @param {ProcessedHtmlWebpackOptions} options
926+
* @returns {TemplateParameter}
925927
*/
926928
function templateParametersGenerator (compilation, assets, assetTags, options) {
927929
const xhtml = options.xhtml;

‎lib/hooks.js

+6-16
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
// @ts-check
2-
/* eslint-disable */
3-
/// <reference path="../typings.d.ts" />
4-
/* eslint-enable */
2+
/** @typedef {import("../typings").Hooks} HtmlWebpackPluginHooks */
53
'use strict';
64
/**
75
* This file provides access to all public htmlWebpackPlugin hooks
@@ -12,10 +10,9 @@
1210

1311
const AsyncSeriesWaterfallHook = require('tapable').AsyncSeriesWaterfallHook;
1412

15-
// The following typedef holds the API definition for all available hooks
16-
// to allow easier access when using ts-check or typescript inside plugins
17-
/** @typedef {{
18-
13+
// The following is the API definition for all available hooks
14+
// For the TypeScript definition, see the Hooks type in typings.d.ts
15+
/**
1916
beforeAssetTagGeneration:
2017
AsyncSeriesWaterfallHook<{
2118
assets: {
@@ -28,7 +25,6 @@ const AsyncSeriesWaterfallHook = require('tapable').AsyncSeriesWaterfallHook;
2825
outputName: string,
2926
plugin: HtmlWebpackPlugin
3027
}>,
31-
3228
alterAssetTags:
3329
AsyncSeriesWaterfallHook<{
3430
assetTags: {
@@ -39,15 +35,13 @@ const AsyncSeriesWaterfallHook = require('tapable').AsyncSeriesWaterfallHook;
3935
outputName: string,
4036
plugin: HtmlWebpackPlugin
4137
}>,
42-
4338
alterAssetTagGroups:
4439
AsyncSeriesWaterfallHook<{
4540
headTags: Array<HtmlTagObject | HtmlTagObject>,
4641
bodyTags: Array<HtmlTagObject | HtmlTagObject>,
4742
outputName: string,
4843
plugin: HtmlWebpackPlugin
4944
}>,
50-
5145
afterTemplateExecution:
5246
AsyncSeriesWaterfallHook<{
5347
html: string,
@@ -56,22 +50,18 @@ const AsyncSeriesWaterfallHook = require('tapable').AsyncSeriesWaterfallHook;
5650
outputName: string,
5751
plugin: HtmlWebpackPlugin,
5852
}>,
59-
6053
beforeEmit:
6154
AsyncSeriesWaterfallHook<{
6255
html: string,
6356
outputName: string,
6457
plugin: HtmlWebpackPlugin,
6558
}>,
66-
6759
afterEmit:
6860
AsyncSeriesWaterfallHook<{
6961
outputName: string,
7062
plugin: HtmlWebpackPlugin
71-
}>,
72-
73-
}} HtmlWebpackPluginHooks
74-
*/
63+
}>
64+
*/
7565

7666
/**
7767
* @type {WeakMap<WebpackCompilation, HtmlWebpackPluginHooks>}}

‎lib/html-tags.js

+1-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
// @ts-check
2-
/* eslint-disable */
3-
/// <reference path="../typings.d.ts" />
4-
/* eslint-enable */
2+
/** @typedef {import("../typings").HtmlTagObject} HtmlTagObject */
53
/**
64
* @file
75
* This file provides to helper to create html as a object repesentation as

‎package.json

+3
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
"description": "Simplifies creation of HTML files to serve your webpack bundles",
66
"author": "Jan Nicklas <j.nicklas@me.com> (https://github.com/jantimon)",
77
"main": "index.js",
8+
"types": "typings.d.ts",
89
"files": [
910
"lib/",
1011
"index.js",
@@ -27,9 +28,11 @@
2728
]
2829
},
2930
"devDependencies": {
31+
"@types/html-minifier": "^3.5.2",
3032
"@types/loader-utils": "1.1.3",
3133
"@types/node": "10.11.4",
3234
"@types/tapable": "1.0.4",
35+
"@types/webpack": "^4.0.0",
3336
"appcache-webpack-plugin": "^1.4.0",
3437
"commitizen": "3.0.2",
3538
"css-loader": "^1.0.0",

‎typings.d.ts

+199-86
Original file line numberDiff line numberDiff line change
@@ -1,139 +1,252 @@
1+
import { Plugin } from "webpack";
2+
import { AsyncSeriesWaterfallHook } from "tapable";
3+
import { Options as HtmlMinifierOptions } from "html-minifier";
14

2-
/**
3-
* The plugin options
4-
*/
5-
interface HtmlWebpackPluginOptions {
5+
// https://github.com/Microsoft/TypeScript/issues/15012#issuecomment-365453623
6+
type Required<T> = T extends object
7+
? { [P in keyof T]-?: NonNullable<T[P]> }
8+
: T;
9+
// https://stackoverflow.com/questions/48215950/exclude-property-from-type
10+
type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>;
11+
12+
export = HtmlWebpackPlugin;
13+
14+
declare class HtmlWebpackPlugin extends Plugin {
15+
constructor(options?: HtmlWebpackPlugin.Options);
16+
}
17+
18+
declare namespace HtmlWebpackPlugin {
19+
type MinifyOptions = HtmlMinifierOptions;
20+
21+
/**
22+
* The plugin options
23+
*/
24+
interface Options {
625
/**
7-
* The title to use for the generated HTML document
26+
* Emit the file only if it was changed.
27+
* Default: `true`.
828
*/
9-
title: string,
29+
cache?: boolean;
1030
/**
11-
* The `webpack` require path to the template.
12-
* @see https://github.com/jantimon/html-webpack-plugin/blob/master/docs/template-option.md
31+
* List all entries which should be injected
1332
*/
14-
template: string,
33+
chunks?: "all" | string[];
1534
/**
16-
* Allow to use a html string instead of reading from a file
35+
* Allows to control how chunks should be sorted before they are included to the html.
36+
* Default: `'auto'`.
1737
*/
18-
templateContent:
19-
false // Use the template option instead to load a file
20-
| string
21-
| Promise<string>,
38+
chunksSortMode?:
39+
| "auto"
40+
| "manual"
41+
| (((entryNameA: string, entryNameB: string) => number));
2242
/**
23-
* Allows to overwrite the parameters used in the template
43+
* List all entries which should not be injeccted
2444
*/
25-
templateParameters:
26-
false // Pass an empty object to the template function
27-
| ((compilation: any, assets, assetTags: { headTags: Array<HtmlTagObject>, bodyTags: Array<HtmlTagObject> }, options: HtmlWebpackPluginOptions) => {[option: string]: any})
28-
| ((compilation: any, assets, assetTags: { headTags: Array<HtmlTagObject>, bodyTags: Array<HtmlTagObject> }, options: HtmlWebpackPluginOptions) => Promise<{[option: string]: any}>)
29-
| {[option: string]: any}
45+
excludeChunks?: string[];
46+
/**
47+
* Path to the favicon icon
48+
*/
49+
favicon?: false | string;
3050
/**
3151
* The file to write the HTML to.
3252
* Defaults to `index.html`.
3353
* Supports subdirectories eg: `assets/admin.html`
3454
*/
35-
filename: string,
55+
filename?: string;
3656
/**
3757
* If `true` then append a unique `webpack` compilation hash to all included scripts and CSS files.
3858
* This is useful for cache busting
3959
*/
40-
hash: boolean,
60+
hash?: boolean;
4161
/**
4262
* Inject all assets into the given `template` or `templateContent`.
4363
*/
44-
inject: false // Don't inject scripts
45-
| true // Inject scripts into body
46-
| 'body' // Inject scripts into body
47-
| 'head' // Inject scripts into head
64+
inject?:
65+
| false // Don't inject scripts
66+
| true // Inject scripts into body
67+
| "body" // Inject scripts into body
68+
| "head"; // Inject scripts into head
4869
/**
49-
* Path to the favicon icon
70+
* Inject meta tags
5071
*/
51-
favicon: false | string,
72+
meta?:
73+
| false // Disable injection
74+
| {
75+
[name: string]:
76+
| string
77+
| false // name content pair e.g. {viewport: 'width=device-width, initial-scale=1, shrink-to-fit=no'}`
78+
| { [attributeName: string]: string | boolean }; // custom properties e.g. { name:"viewport" content:"width=500, initial-scale=1" }
79+
};
5280
/**
5381
* HTML Minification options
5482
* @https://github.com/kangax/html-minifier#options-quick-reference
5583
*/
56-
minify?: boolean | {},
57-
cache: boolean,
84+
minify?: boolean | MinifyOptions;
5885
/**
5986
* Render errors into the HTML page
6087
*/
61-
showErrors: boolean,
88+
showErrors?: boolean;
6289
/**
63-
* List all entries which should be injected
90+
* The `webpack` require path to the template.
91+
* @see https://github.com/jantimon/html-webpack-plugin/blob/master/docs/template-option.md
6492
*/
65-
chunks: 'all' | string[],
93+
template?: string;
6694
/**
67-
* List all entries which should not be injeccted
95+
* Allow to use a html string instead of reading from a file
6896
*/
69-
excludeChunks: string[],
70-
chunksSortMode: 'auto' | 'manual' | (((entryNameA: string, entryNameB: string) => number)),
97+
templateContent?:
98+
| false // Use the template option instead to load a file
99+
| string
100+
| Promise<string>;
71101
/**
72-
* Inject meta tags
102+
* Allows to overwrite the parameters used in the template
73103
*/
74-
meta: false // Disable injection
75-
| {
76-
[name: string]: string|false // name content pair e.g. {viewport: 'width=device-width, initial-scale=1, shrink-to-fit=no'}`
77-
| {[attributeName: string]: string|boolean} // custom properties e.g. { name:"viewport" content:"width=500, initial-scale=1" }
78-
},
104+
templateParameters?:
105+
| false // Pass an empty object to the template function
106+
| ((
107+
compilation: any,
108+
assets,
109+
assetTags: {
110+
headTags: HtmlTagObject[];
111+
bodyTags: HtmlTagObject[];
112+
},
113+
options: Options
114+
) => { [option: string]: any })
115+
| ((
116+
compilation: any,
117+
assets,
118+
assetTags: {
119+
headTags: HtmlTagObject[];
120+
bodyTags: HtmlTagObject[];
121+
},
122+
options: Options
123+
) => Promise<{ [option: string]: any }>)
124+
| { [option: string]: any };
125+
/**
126+
* The title to use for the generated HTML document
127+
*/
128+
title?: string;
79129
/**
80130
* Enforce self closing tags e.g. <link />
81131
*/
82-
xhtml: boolean
83-
132+
xhtml?: boolean;
84133
/**
85134
* In addition to the options actually used by this plugin, you can use this hash to pass arbitrary data through
86135
* to your template.
87136
*/
88137
[option: string]: any;
89-
}
138+
}
90139

91-
/**
92-
* A tag element according to the htmlWebpackPlugin object notation
93-
*/
94-
interface HtmlTagObject {
95140
/**
96-
* Attributes of the html tag
97-
* E.g. `{'disabled': true, 'value': 'demo'}`
141+
* Options interface that matches the expectations of the index.js API:
142+
* - All fields are required
143+
* - The minify property matches what html-minifier expects (eg either a MinifyOptions or undefined).
144+
* html-minifier does not accept a boolean value. As TypeScript does not allow a property to be redefined
145+
* in an extended interface we need to omit it and then define it properly
146+
*
147+
* The Required and Omit types are defined at the top of the file
98148
*/
99-
attributes: {
100-
[attributeName: string]: string|boolean
101-
},
102-
/**
103-
* Wether this html must not contain innerHTML
104-
* @see https://www.w3.org/TR/html5/syntax.html#void-elements
105-
*/
106-
voidTag: boolean,
149+
interface ProcessedOptions extends Required<Omit<Options, "minify">> {
150+
minify: MinifyOptions | undefined;
151+
}
152+
107153
/**
108-
* The tag name e.g. `'div'`
154+
* The values which are available during template execution
155+
*
156+
* Please keep in mind that the `templateParameter` options allows to change them
109157
*/
110-
tagName: string,
158+
interface TemplateParameter {
159+
compilation: any;
160+
htmlWebpackPlugin: {
161+
tags: {
162+
headTags: HtmlTagObject[];
163+
bodyTags: HtmlTagObject[];
164+
};
165+
files: {
166+
publicPath: string;
167+
js: Array<string>;
168+
css: Array<string>;
169+
manifest?: string;
170+
favicon?: string;
171+
};
172+
options: Options;
173+
};
174+
webpackConfig: any;
175+
}
176+
177+
interface Hooks {
178+
alterAssetTags: AsyncSeriesWaterfallHook<{
179+
assetTags: {
180+
scripts: HtmlTagObject[];
181+
styles: HtmlTagObject[];
182+
meta: HtmlTagObject[];
183+
};
184+
outputName: string;
185+
plugin: HtmlWebpackPlugin;
186+
}>;
187+
188+
alterAssetTagGroups: AsyncSeriesWaterfallHook<{
189+
headTags: HtmlTagObject[];
190+
bodyTags: HtmlTagObject[];
191+
outputName: string;
192+
plugin: HtmlWebpackPlugin;
193+
}>;
194+
195+
afterTemplateExecution: AsyncSeriesWaterfallHook<{
196+
html: string;
197+
headTags: HtmlTagObject[];
198+
bodyTags: HtmlTagObject[];
199+
outputName: string;
200+
plugin: HtmlWebpackPlugin;
201+
}>;
202+
203+
beforeAssetTagGeneration: AsyncSeriesWaterfallHook<{
204+
assets: {
205+
publicPath: string;
206+
js: Array<string>;
207+
css: Array<string>;
208+
favicon?: string | undefined;
209+
manifest?: string | undefined;
210+
};
211+
outputName: string;
212+
plugin: HtmlWebpackPlugin;
213+
}>;
214+
215+
beforeEmit: AsyncSeriesWaterfallHook<{
216+
html: string;
217+
outputName: string;
218+
plugin: HtmlWebpackPlugin;
219+
}>;
220+
221+
afterEmit: AsyncSeriesWaterfallHook<{
222+
outputName: string;
223+
plugin: HtmlWebpackPlugin;
224+
}>;
225+
}
226+
111227
/**
112-
* Inner HTML The
228+
* A tag element according to the htmlWebpackPlugin object notation
113229
*/
114-
innerHTML?: string
115-
}
116-
117-
/**
118-
* The values which are available during template execution
119-
*
120-
* Please keep in mind that the `templateParameter` options allows to change them
121-
*/
122-
interface HtmlWebpackPluginTemplateParameter {
123-
compilation: any,
124-
webpackConfig: any
125-
htmlWebpackPlugin: {
126-
tags: {
127-
headTags: HtmlTagObject[],
128-
bodyTags: HtmlTagObject[]
129-
},
130-
files: {
131-
publicPath: string,
132-
js: Array<string>,
133-
css: Array<string>,
134-
manifest?: string,
135-
favicon?: string
136-
},
137-
options: HtmlWebpackPluginOptions
230+
interface HtmlTagObject {
231+
/**
232+
* Attributes of the html tag
233+
* E.g. `{'disabled': true, 'value': 'demo'}`
234+
*/
235+
attributes: {
236+
[attributeName: string]: string | boolean;
237+
};
238+
/**
239+
* The tag name e.g. `'div'`
240+
*/
241+
tagName: string;
242+
/**
243+
* The inner HTML
244+
*/
245+
innerHTML?: string;
246+
/**
247+
* Whether this html must not contain innerHTML
248+
* @see https://www.w3.org/TR/html5/syntax.html#void-elements
249+
*/
250+
voidTag: boolean;
138251
}
139252
}

0 commit comments

Comments
 (0)
Please sign in to comment.