Skip to content

Commit 016a531

Browse files
authored
Dependency Extraction Webpack Plugin: Add types (WordPress#22498)
* Type package * Add node eslint config * Add changelog * Update util path in build scripts
1 parent 2116931 commit 016a531

File tree

11 files changed

+210
-24
lines changed

11 files changed

+210
-24
lines changed

package-lock.json

+76
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+2
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,8 @@
9898
"@types/requestidlecallback": "0.3.1",
9999
"@types/sprintf-js": "1.1.2",
100100
"@types/uuid": "7.0.2",
101+
"@types/webpack": "4.41.16",
102+
"@types/webpack-sources": "0.1.7",
101103
"@wordpress/babel-plugin-import-jsx-pragma": "file:packages/babel-plugin-import-jsx-pragma",
102104
"@wordpress/babel-plugin-makepot": "file:packages/babel-plugin-makepot",
103105
"@wordpress/babel-preset-default": "file:packages/babel-preset-default",

packages/dependency-extraction-webpack-plugin/CHANGELOG.md

+4
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22

33
## Unreleased
44

5+
### New feature
6+
7+
- Include TypeScript type declarations ([#22498](https://github.com/WordPress/gutenberg/pull/22498))
8+
59
## 2.5.0 (2020-04-01)
610

711
### New Features
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
// Use the default eslint parser. Prevent babel transforms.
3+
"parser": "espree",
4+
"env": {
5+
"node": true
6+
}
7+
}

packages/dependency-extraction-webpack-plugin/index.js renamed to packages/dependency-extraction-webpack-plugin/lib/index.js

+103-10
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,12 @@
22
* External dependencies
33
*/
44
const { createHash } = require( 'crypto' );
5-
const json2php = require( 'json2php' );
65
const path = require( 'path' );
76
const { ExternalsPlugin } = require( 'webpack' );
87
const { RawSource } = require( 'webpack-sources' );
8+
// Ignore reason: json2php is untyped
9+
// @ts-ignore
10+
const json2php = require( 'json2php' );
911

1012
/**
1113
* Internal dependencies
@@ -15,8 +17,53 @@ const {
1517
defaultRequestToHandle,
1618
} = require( './util' );
1719

20+
/**
21+
* Map module request to an external.
22+
*
23+
* @callback RequestToExternal
24+
*
25+
* @param {string} request Module request.
26+
*
27+
* @return {string|string[]|void} Return `undefined` to ignore the request.
28+
* Return `string|string[]` to map the request to an external.
29+
*/
30+
31+
/**
32+
* Map module request to a script handle.
33+
*
34+
* @callback RequestToHandle
35+
*
36+
* @param {string} request Module request.
37+
*
38+
* @return {string|void} Return `undefined` to use the same name as the module.
39+
* Return `string` to map the request to a specific script handle.
40+
*/
41+
42+
/**
43+
* @typedef AssetData
44+
*
45+
* @property {string} version String representing a particular build
46+
* @property {string[]} dependencies The script dependencies
47+
*/
48+
49+
/**
50+
* @typedef Options
51+
*
52+
* @property {boolean} injectPolyfill Force wp-polyfill to be included in each entry point's dependency list. This is like importing `@wordpress/polyfill` for each entry point.
53+
* @property {boolean} useDefaults Set to `false` to disable the default WordPress script request handling.
54+
* @property {'php'|'json'} outputFormat The output format for the generated asset file.
55+
* @property {RequestToExternal|undefined} [requestToExternal] Map module requests to an external.
56+
* @property {RequestToHandle|undefined} [requestToHandle] Map module requests to a script handle.
57+
* @property {string|null} combinedOutputFile This option is useful only when the combineAssets option is enabled. It allows providing a custom output file for the generated single assets file. It's possible to provide a path that is relative to the output directory.
58+
* @property {boolean|undefined} combineAssets By default, one asset file is created for each entry point. When this flag is set to true, all information about assets is combined into a single assets.(json|php) file generated in the output directory.
59+
*/
60+
1861
class DependencyExtractionWebpackPlugin {
62+
/**
63+
* @param {Partial<Options>} options
64+
*/
1965
constructor( options ) {
66+
/** @type {Options} */
2067
this.options = Object.assign(
2168
{
2269
combineAssets: false,
@@ -28,11 +75,15 @@ class DependencyExtractionWebpackPlugin {
2875
options
2976
);
3077

31-
// Track requests that are externalized.
32-
//
33-
// Because we don't have a closed set of dependencies, we need to track what has
34-
// been externalized so we can recognize them in a later phase when the dependency
35-
// lists are generated.
78+
/**
79+
* Track requests that are externalized.
80+
*
81+
* Because we don't have a closed set of dependencies, we need to track what has
82+
* been externalized so we can recognize them in a later phase when the dependency
83+
* lists are generated.
84+
*
85+
* @type {Set<string>}
86+
*/
3687
this.externalizedDeps = new Set();
3788

3889
// Offload externalization work to the ExternalsPlugin.
@@ -42,7 +93,14 @@ class DependencyExtractionWebpackPlugin {
4293
);
4394
}
4495

45-
externalizeWpDeps( context, request, callback ) {
96+
/* eslint-disable jsdoc/valid-types */
97+
/**
98+
* @param {Parameters<WebpackExternalsFunction>[0]} _context
99+
* @param {Parameters<WebpackExternalsFunction>[1]} request
100+
* @param {Parameters<WebpackExternalsFunction>[2]} callback
101+
*/
102+
externalizeWpDeps( _context, request, callback ) {
103+
/* eslint-enable jsdoc/valid-types */
46104
let externalRequest;
47105

48106
// Handle via options.requestToExternal first
@@ -67,6 +125,10 @@ class DependencyExtractionWebpackPlugin {
67125
return callback();
68126
}
69127

128+
/**
129+
* @param {string} request
130+
* @return {string} Transformed request
131+
*/
70132
mapRequestToDependency( request ) {
71133
// Handle via options.requestToHandle first
72134
if ( typeof this.options.requestToHandle === 'function' ) {
@@ -88,6 +150,10 @@ class DependencyExtractionWebpackPlugin {
88150
return request;
89151
}
90152

153+
/**
154+
* @param {Object} asset
155+
* @return {string} Stringified asset
156+
*/
91157
stringify( asset ) {
92158
if ( this.options.outputFormat === 'php' ) {
93159
return `<?php return ${ json2php(
@@ -98,11 +164,19 @@ class DependencyExtractionWebpackPlugin {
98164
return JSON.stringify( asset );
99165
}
100166

167+
/**
168+
* @param {WebpackCompiler} compiler
169+
* @return {void}
170+
*/
101171
apply( compiler ) {
102172
this.externalsPlugin.apply( compiler );
103173

104-
const { output } = compiler.options;
105-
const { filename: outputFilename } = output;
174+
// Assert the `string` type for output filename.
175+
// The type indicates the option may be `undefined`.
176+
// However, at this point in compilation, webpack has filled the options in if
177+
// they were not provided.
178+
const outputFilename = /** @type {{filename:string}} */ ( compiler
179+
.options.output ).filename;
106180

107181
compiler.hooks.emit.tap( this.constructor.name, ( compilation ) => {
108182
const {
@@ -111,13 +185,16 @@ class DependencyExtractionWebpackPlugin {
111185
injectPolyfill,
112186
outputFormat,
113187
} = this.options;
188+
189+
/** @type {Record<string, AssetData>} */
114190
const combinedAssetsData = {};
115191

116192
// Process each entry point independently.
117193
for ( const [
118194
entrypointName,
119195
entrypoint,
120196
] of compilation.entrypoints.entries() ) {
197+
/** @type {Set<string>} */
121198
const entrypointExternalizedWpDeps = new Set();
122199
if ( injectPolyfill ) {
123200
entrypointExternalizedWpDeps.add( 'wp-polyfill' );
@@ -139,6 +216,7 @@ class DependencyExtractionWebpackPlugin {
139216

140217
const runtimeChunk = entrypoint.getRuntimeChunk();
141218

219+
/** @type {AssetData} */
142220
const assetData = {
143221
// Get a sorted array so we can produce a stable, stringified representation.
144222
dependencies: Array.from(
@@ -179,7 +257,13 @@ class DependencyExtractionWebpackPlugin {
179257
}
180258

181259
if ( combineAssets ) {
182-
const outputFolder = compiler.options.output.path;
260+
// Assert the `string` type for output path.
261+
// The type indicates the option may be `undefined`.
262+
// However, at this point in compilation, webpack has filled the options in if
263+
// they were not provided.
264+
const outputFolder = /** @type {{path:string}} */ ( compiler
265+
.options.output ).path;
266+
183267
const assetsFilePath = path.resolve(
184268
outputFolder,
185269
combinedOutputFile ||
@@ -199,6 +283,10 @@ class DependencyExtractionWebpackPlugin {
199283
}
200284
}
201285

286+
/**
287+
* @param {string} name
288+
* @return {string} Basename
289+
*/
202290
function basename( name ) {
203291
if ( ! name.includes( '/' ) ) {
204292
return name;
@@ -207,3 +295,8 @@ function basename( name ) {
207295
}
208296

209297
module.exports = DependencyExtractionWebpackPlugin;
298+
299+
/**
300+
* @typedef {import('webpack').Compiler} WebpackCompiler
301+
* @typedef {import('webpack').ExternalsFunctionElement} WebpackExternalsFunction
302+
*/

packages/dependency-extraction-webpack-plugin/util.js renamed to packages/dependency-extraction-webpack-plugin/lib/util.js

+3-9
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,7 @@ const BUNDLED_PACKAGES = [ '@wordpress/icons', '@wordpress/interface' ];
99
* request `@wordpress/api-fetch` becomes `wp.apiFetch`
1010
* request `@wordpress/i18n` becomes `wp.i18n`
1111
*
12-
* @param {string} request Requested module
13-
*
14-
* @return {(string|string[]|undefined)} Script global
12+
* @type {import('.').RequestToExternal}
1513
*/
1614
function defaultRequestToExternal( request ) {
1715
switch ( request ) {
@@ -55,9 +53,7 @@ function defaultRequestToExternal( request ) {
5553
* request `@wordpress/i18n` becomes `wp-i18n`
5654
* request `@wordpress/escape-html` becomes `wp-escape-html`
5755
*
58-
* @param {string} request Requested module
59-
*
60-
* @return {(string|undefined)} Script handle
56+
* @type {import('.').RequestToHandle}
6157
*/
6258
function defaultRequestToHandle( request ) {
6359
switch ( request ) {
@@ -84,9 +80,7 @@ function defaultRequestToHandle( request ) {
8480
* @return {string} Camel-cased string.
8581
*/
8682
function camelCaseDash( string ) {
87-
return string.replace( /-([a-z])/g, ( match, letter ) =>
88-
letter.toUpperCase()
89-
);
83+
return string.replace( /-([a-z])/g, ( _, letter ) => letter.toUpperCase() );
9084
}
9185

9286
module.exports = {

0 commit comments

Comments
 (0)