@wordpress/dependency-extraction-webpack-plugin 4.31.0 → 5.0.1-next.79a6196f.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.md +1 -1
- package/README.md +128 -5
- package/lib/.eslintrc.json +0 -2
- package/lib/index.js +166 -51
- package/lib/types.d.ts +3 -0
- package/lib/util.js +22 -2
- package/package.json +5 -6
package/LICENSE.md
CHANGED
package/README.md
CHANGED
|
@@ -2,11 +2,15 @@
|
|
|
2
2
|
|
|
3
3
|
This webpack plugin serves two purposes:
|
|
4
4
|
|
|
5
|
-
- Externalize dependencies that are available as
|
|
6
|
-
- Add an asset file for each entry point that declares an object with the list of WordPress script dependencies for the entry point. The asset file also contains the current version calculated for the current source code.
|
|
5
|
+
- Externalize dependencies that are available as shared scripts or modules on WordPress sites.
|
|
6
|
+
- Add an asset file for each entry point that declares an object with the list of WordPress script or module dependencies for the entry point. The asset file also contains the current version calculated for the current source code.
|
|
7
7
|
|
|
8
8
|
This allows JavaScript bundles produced by webpack to leverage WordPress style dependency sharing without an error-prone process of manually maintaining a dependency list.
|
|
9
9
|
|
|
10
|
+
Version 5 of this plugin adds support for module bundling. [Webpack's `output.module` option](https://webpack.js.org/configuration/output/#outputmodule) should
|
|
11
|
+
be used to opt-in to this behavior. This plugin will adapt it's behavior based on the
|
|
12
|
+
`output.module` option, producing an asset file suitable for use with the WordPress Module API.
|
|
13
|
+
|
|
10
14
|
Consult the [webpack website](https://webpack.js.org) for additional information on webpack concepts.
|
|
11
15
|
|
|
12
16
|
## Installation
|
|
@@ -17,7 +21,7 @@ Install the module
|
|
|
17
21
|
npm install @wordpress/dependency-extraction-webpack-plugin --save-dev
|
|
18
22
|
```
|
|
19
23
|
|
|
20
|
-
**Note**: This package requires Node.js
|
|
24
|
+
**Note**: This package requires Node.js 18.0.0 or later. It also requires webpack 5.0.0 or newer. It is not compatible with older versions.
|
|
21
25
|
|
|
22
26
|
## Usage
|
|
23
27
|
|
|
@@ -39,7 +43,7 @@ module.exports = {
|
|
|
39
43
|
|
|
40
44
|
```js
|
|
41
45
|
const defaultConfig = require( '@wordpress/scripts/config/webpack.config' );
|
|
42
|
-
const
|
|
46
|
+
const webpackConfig = {
|
|
43
47
|
...defaultConfig,
|
|
44
48
|
plugins: [
|
|
45
49
|
...defaultConfig.plugins.filter(
|
|
@@ -56,7 +60,9 @@ const config = {
|
|
|
56
60
|
};
|
|
57
61
|
```
|
|
58
62
|
|
|
59
|
-
|
|
63
|
+
### Behavior with scripts
|
|
64
|
+
|
|
65
|
+
Each entry point in the webpack bundle will include an asset file that declares the WordPress script dependencies that should be enqueued. This file also contains the unique version hash calculated based on the file content.
|
|
60
66
|
|
|
61
67
|
For example:
|
|
62
68
|
|
|
@@ -88,6 +94,68 @@ By default, the following module requests are handled:
|
|
|
88
94
|
|
|
89
95
|
This plugin is compatible with `externals`, but they may conflict. For example, adding `{ externals: { '@wordpress/blob': 'wp.blob' } }` to webpack configuration will effectively hide the `@wordpress/blob` module from the plugin and it will not be included in dependency lists.
|
|
90
96
|
|
|
97
|
+
### Behavior with modules
|
|
98
|
+
|
|
99
|
+
**Warning:** Modules support is considered experimental at this time.
|
|
100
|
+
|
|
101
|
+
This section describes the behavior of this package to bundle ECMAScript modules and generate asset
|
|
102
|
+
files suitable for use with the WordPress Modules API.
|
|
103
|
+
|
|
104
|
+
Some of this plugin's options change, and webpack requires configuration to output modules. Refer to
|
|
105
|
+
[webpack's documentation](https://webpack.js.org/configuration/output/#outputmodule) for up-to-date details.
|
|
106
|
+
|
|
107
|
+
```js
|
|
108
|
+
const webpackConfig = {
|
|
109
|
+
...defaultConfig,
|
|
110
|
+
|
|
111
|
+
// These lines are necessary to enable module compilation at time-of-writing:
|
|
112
|
+
output: { module: true },
|
|
113
|
+
experiments: { outputModule: true },
|
|
114
|
+
|
|
115
|
+
plugins: [
|
|
116
|
+
...defaultConfig.plugins.filter(
|
|
117
|
+
( plugin ) =>
|
|
118
|
+
plugin.constructor.name !== 'DependencyExtractionWebpackPlugin'
|
|
119
|
+
),
|
|
120
|
+
new DependencyExtractionWebpackPlugin( {
|
|
121
|
+
// With modules, we use `requestToExternalModule`:
|
|
122
|
+
requestToExternalModule( request ) {
|
|
123
|
+
if ( request === 'my-registered-module' ) {
|
|
124
|
+
return request;
|
|
125
|
+
}
|
|
126
|
+
},
|
|
127
|
+
} ),
|
|
128
|
+
],
|
|
129
|
+
};
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
Each entry point in the webpack bundle will include an asset file that declares the WordPress module dependencies that should be enqueued. This file also contains the unique version hash calculated based on the file content.
|
|
133
|
+
|
|
134
|
+
For example:
|
|
135
|
+
|
|
136
|
+
```
|
|
137
|
+
// Source file entrypoint.js
|
|
138
|
+
import { store, getContext } from '@wordpress/interactivity';
|
|
139
|
+
|
|
140
|
+
// Webpack will produce the output output/entrypoint.js
|
|
141
|
+
/* bundled JavaScript output */
|
|
142
|
+
|
|
143
|
+
// Webpack will also produce output/entrypoint.asset.php declaring script dependencies
|
|
144
|
+
<?php return array('dependencies' => array('@wordpress/interactivity'), 'version' => 'dd4c2dc50d046ed9d4c063a7ca95702f');
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
By default, the following module requests are handled:
|
|
148
|
+
|
|
149
|
+
| Request |
|
|
150
|
+
| ---------------------------- |
|
|
151
|
+
| `@wordpress/interactivity ` |
|
|
152
|
+
|
|
153
|
+
(`@wordpress/interactivity` is currently the only available WordPress module.)
|
|
154
|
+
|
|
155
|
+
**Note:** This plugin overlaps with the functionality provided by [webpack `externals`](https://webpack.js.org/configuration/externals). This plugin is intended to extract module handles from bundle compilation so that a list of module dependencies does not need to be manually maintained. If you don't need to extract a list of module dependencies, use the `externals` option directly.
|
|
156
|
+
|
|
157
|
+
This plugin is compatible with `externals`, but they may conflict. For example, adding `{ externals: { '@wordpress/blob': 'wp.blob' } }` to webpack configuration will effectively hide the `@wordpress/blob` module from the plugin and it will not be included in dependency lists.
|
|
158
|
+
|
|
91
159
|
#### Options
|
|
92
160
|
|
|
93
161
|
An object can be passed to the constructor to customize the behavior, for example:
|
|
@@ -142,6 +210,8 @@ Pass `useDefaults: false` to disable the default request handling.
|
|
|
142
210
|
|
|
143
211
|
Force `wp-polyfill` to be included in each entry point's dependency list. This would be the same as adding `import '@wordpress/polyfill';` to each entry point.
|
|
144
212
|
|
|
213
|
+
**Note**: This option is not available with modules.
|
|
214
|
+
|
|
145
215
|
##### `externalizedReport`
|
|
146
216
|
|
|
147
217
|
- Type: boolean | string
|
|
@@ -152,6 +222,8 @@ You can provide a filename, or set it to `true` to report to a default `external
|
|
|
152
222
|
|
|
153
223
|
##### `requestToExternal`
|
|
154
224
|
|
|
225
|
+
**Note**: This option is not available with modules. See [`requestToExternalModule`](#requestToExternalModule) for module usage.
|
|
226
|
+
|
|
155
227
|
- Type: function
|
|
156
228
|
|
|
157
229
|
`requestToExternal` allows the module handling to be customized. The function should accept a module request string and may return a string representing the global variable to use. An array of strings may be used to access globals via an object path, e.g. `wp.i18n` may be represented as `[ 'wp', 'i18n' ]`.
|
|
@@ -179,8 +251,46 @@ module.exports = {
|
|
|
179
251
|
};
|
|
180
252
|
```
|
|
181
253
|
|
|
254
|
+
##### `requestToExternalModule`
|
|
255
|
+
|
|
256
|
+
**Note**: This option is only available with modules. See [`requestToExternal`](#requestToExternal) for script usage.
|
|
257
|
+
|
|
258
|
+
- Type: function
|
|
259
|
+
|
|
260
|
+
`requestToExternalModule` allows the module handling to be customized. The function should accept a module request string and may return a string representing the module to use. Often, the module will have the same name.
|
|
261
|
+
|
|
262
|
+
`requestToExternalModule` provided via configuration has precedence over default external handling. Unhandled requests will be handled by the default unless `useDefaults` is set to `false`.
|
|
263
|
+
|
|
264
|
+
```js
|
|
265
|
+
/**
|
|
266
|
+
* Externalize 'my-module'
|
|
267
|
+
*
|
|
268
|
+
* @param {string} request Requested module
|
|
269
|
+
*
|
|
270
|
+
* @return {(string|boolean|undefined)} Module ID
|
|
271
|
+
*/
|
|
272
|
+
function requestToExternalModule( request ) {
|
|
273
|
+
// Handle imports like `import myModule from 'my-module'`
|
|
274
|
+
if ( request === 'my-module' ) {
|
|
275
|
+
// Import should be of the form `import { something } from "myModule";` in the final bundle.
|
|
276
|
+
return 'myModule';
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
// If the Module ID in source is the same as the external module, we can return `true`.
|
|
280
|
+
return request === 'external-module-id-no-change-required';
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
module.exports = {
|
|
284
|
+
plugins: [
|
|
285
|
+
new DependencyExtractionWebpackPlugin( { requestToExternalModule } ),
|
|
286
|
+
],
|
|
287
|
+
};
|
|
288
|
+
```
|
|
289
|
+
|
|
182
290
|
##### `requestToHandle`
|
|
183
291
|
|
|
292
|
+
**Note**: This option is not available with modules. It has no corresponding module configuration.
|
|
293
|
+
|
|
184
294
|
- Type: function
|
|
185
295
|
|
|
186
296
|
All of the external modules handled by the plugin are expected to be WordPress script dependencies
|
|
@@ -233,6 +343,19 @@ $script_url = plugins_url( $script_path, __FILE__ );
|
|
|
233
343
|
wp_enqueue_script( 'script', $script_url, $script_asset['dependencies'], $script_asset['version'] );
|
|
234
344
|
```
|
|
235
345
|
|
|
346
|
+
Or with modules (the Module API is not yet stable):
|
|
347
|
+
|
|
348
|
+
```php
|
|
349
|
+
$module_path = 'path/to/module.js';
|
|
350
|
+
$module_asset_path = 'path/to/module.asset.php';
|
|
351
|
+
$module_asset = file_exists( $module_asset_path )
|
|
352
|
+
? require( $module_asset_path )
|
|
353
|
+
: array( 'dependencies' => array(), 'version' => filemtime( $module_path ) );
|
|
354
|
+
$module_url = plugins_url( $module_path, __FILE__ );
|
|
355
|
+
wp_register_module( 'my-module', $module_url, $module_asset['dependencies'], $module_asset['version'] );
|
|
356
|
+
wp_enqueue_module( 'my-module' );
|
|
357
|
+
```
|
|
358
|
+
|
|
236
359
|
## Contributing to this package
|
|
237
360
|
|
|
238
361
|
This is an individual package that's part of the Gutenberg project. The project is organized as a monorepo. It's made up of multiple self-contained software packages, each with a specific purpose. The packages in this monorepo are published to [npm](https://www.npmjs.com/) and used by [WordPress](https://make.wordpress.org/core/) as well as other software projects.
|
package/lib/.eslintrc.json
CHANGED
package/lib/index.js
CHANGED
|
@@ -3,10 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
const path = require( 'path' );
|
|
5
5
|
const webpack = require( 'webpack' );
|
|
6
|
-
// In webpack 5 there is a `webpack.sources` field but for webpack 4 we have to fallback to the `webpack-sources` package.
|
|
7
|
-
const { RawSource } = webpack.sources || require( 'webpack-sources' );
|
|
8
6
|
const json2php = require( 'json2php' );
|
|
9
|
-
const isWebpack4 = webpack.version.startsWith( '4.' );
|
|
10
7
|
const { createHash } = webpack.util;
|
|
11
8
|
|
|
12
9
|
/**
|
|
@@ -14,9 +11,13 @@ const { createHash } = webpack.util;
|
|
|
14
11
|
*/
|
|
15
12
|
const {
|
|
16
13
|
defaultRequestToExternal,
|
|
14
|
+
defaultRequestToExternalModule,
|
|
17
15
|
defaultRequestToHandle,
|
|
18
16
|
} = require( './util' );
|
|
19
17
|
|
|
18
|
+
const { RawSource } = webpack.sources;
|
|
19
|
+
const { AsyncDependenciesBlock } = webpack;
|
|
20
|
+
|
|
20
21
|
const defaultExternalizedReportFileName = 'externalized-dependencies.json';
|
|
21
22
|
|
|
22
23
|
class DependencyExtractionWebpackPlugin {
|
|
@@ -34,29 +35,40 @@ class DependencyExtractionWebpackPlugin {
|
|
|
34
35
|
options
|
|
35
36
|
);
|
|
36
37
|
|
|
37
|
-
|
|
38
|
+
/**
|
|
38
39
|
* Track requests that are externalized.
|
|
39
40
|
*
|
|
40
41
|
* Because we don't have a closed set of dependencies, we need to track what has
|
|
41
42
|
* been externalized so we can recognize them in a later phase when the dependency
|
|
42
43
|
* lists are generated.
|
|
44
|
+
*
|
|
45
|
+
* @type {Set<string>}
|
|
43
46
|
*/
|
|
44
47
|
this.externalizedDeps = new Set();
|
|
45
48
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
49
|
+
/**
|
|
50
|
+
* Should we use modules. This will be set later to match webpack's
|
|
51
|
+
* output.module option.
|
|
52
|
+
*
|
|
53
|
+
* @type {boolean}
|
|
54
|
+
*/
|
|
55
|
+
this.useModules = false;
|
|
53
56
|
}
|
|
54
57
|
|
|
55
|
-
|
|
58
|
+
/**
|
|
59
|
+
* @param {webpack.ExternalItemFunctionData} data
|
|
60
|
+
* @param { ( err?: null | Error, result?: string | string[] ) => void } callback
|
|
61
|
+
*/
|
|
62
|
+
externalizeWpDeps( { request }, callback ) {
|
|
56
63
|
let externalRequest;
|
|
57
64
|
|
|
58
|
-
// Handle via options.requestToExternal
|
|
59
|
-
if (
|
|
65
|
+
// Handle via options.requestToExternal(Module) first.
|
|
66
|
+
if ( this.useModules ) {
|
|
67
|
+
if ( typeof this.options.requestToExternalModule === 'function' ) {
|
|
68
|
+
externalRequest =
|
|
69
|
+
this.options.requestToExternalModule( request );
|
|
70
|
+
}
|
|
71
|
+
} else if ( typeof this.options.requestToExternal === 'function' ) {
|
|
60
72
|
externalRequest = this.options.requestToExternal( request );
|
|
61
73
|
}
|
|
62
74
|
|
|
@@ -65,7 +77,13 @@ class DependencyExtractionWebpackPlugin {
|
|
|
65
77
|
typeof externalRequest === 'undefined' &&
|
|
66
78
|
this.options.useDefaults
|
|
67
79
|
) {
|
|
68
|
-
externalRequest =
|
|
80
|
+
externalRequest = this.useModules
|
|
81
|
+
? defaultRequestToExternalModule( request )
|
|
82
|
+
: defaultRequestToExternal( request );
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
if ( this.useModules && externalRequest === true ) {
|
|
86
|
+
externalRequest = request;
|
|
69
87
|
}
|
|
70
88
|
|
|
71
89
|
if ( externalRequest ) {
|
|
@@ -77,10 +95,10 @@ class DependencyExtractionWebpackPlugin {
|
|
|
77
95
|
return callback();
|
|
78
96
|
}
|
|
79
97
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
98
|
+
/**
|
|
99
|
+
* @param {string} request
|
|
100
|
+
* @return {string} Mapped dependency name
|
|
101
|
+
*/
|
|
84
102
|
mapRequestToDependency( request ) {
|
|
85
103
|
// Handle via options.requestToHandle first.
|
|
86
104
|
if ( typeof this.options.requestToHandle === 'function' ) {
|
|
@@ -102,6 +120,10 @@ class DependencyExtractionWebpackPlugin {
|
|
|
102
120
|
return request;
|
|
103
121
|
}
|
|
104
122
|
|
|
123
|
+
/**
|
|
124
|
+
* @param {any} asset Asset Data
|
|
125
|
+
* @return {string} Stringified asset data suitable for output
|
|
126
|
+
*/
|
|
105
127
|
stringify( asset ) {
|
|
106
128
|
if ( this.options.outputFormat === 'php' ) {
|
|
107
129
|
return `<?php return ${ json2php(
|
|
@@ -112,30 +134,37 @@ class DependencyExtractionWebpackPlugin {
|
|
|
112
134
|
return JSON.stringify( asset );
|
|
113
135
|
}
|
|
114
136
|
|
|
137
|
+
/** @type {webpack.WebpackPluginInstance['apply']} */
|
|
115
138
|
apply( compiler ) {
|
|
139
|
+
this.useModules = Boolean( compiler.options.output?.module );
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Offload externalization work to the ExternalsPlugin.
|
|
143
|
+
* @type {webpack.ExternalsPlugin}
|
|
144
|
+
*/
|
|
145
|
+
this.externalsPlugin = new webpack.ExternalsPlugin(
|
|
146
|
+
this.useModules ? 'import' : 'window',
|
|
147
|
+
this.externalizeWpDeps.bind( this )
|
|
148
|
+
);
|
|
149
|
+
|
|
116
150
|
this.externalsPlugin.apply( compiler );
|
|
117
151
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
},
|
|
132
|
-
() => this.addAssets( compilation )
|
|
133
|
-
);
|
|
134
|
-
}
|
|
135
|
-
);
|
|
136
|
-
}
|
|
152
|
+
compiler.hooks.thisCompilation.tap(
|
|
153
|
+
this.constructor.name,
|
|
154
|
+
( compilation ) => {
|
|
155
|
+
compilation.hooks.processAssets.tap(
|
|
156
|
+
{
|
|
157
|
+
name: this.constructor.name,
|
|
158
|
+
stage: compiler.webpack.Compilation
|
|
159
|
+
.PROCESS_ASSETS_STAGE_ANALYSE,
|
|
160
|
+
},
|
|
161
|
+
() => this.addAssets( compilation )
|
|
162
|
+
);
|
|
163
|
+
}
|
|
164
|
+
);
|
|
137
165
|
}
|
|
138
166
|
|
|
167
|
+
/** @param {webpack.Compilation} compilation */
|
|
139
168
|
addAssets( compilation ) {
|
|
140
169
|
const {
|
|
141
170
|
combineAssets,
|
|
@@ -174,28 +203,53 @@ class DependencyExtractionWebpackPlugin {
|
|
|
174
203
|
for ( const chunk of entrypointChunks ) {
|
|
175
204
|
const chunkFiles = Array.from( chunk.files );
|
|
176
205
|
|
|
177
|
-
const
|
|
206
|
+
const jsExtensionRegExp = this.useModules ? /\.m?js$/i : /\.js$/i;
|
|
207
|
+
|
|
208
|
+
const chunkJSFile = chunkFiles.find( ( f ) =>
|
|
209
|
+
jsExtensionRegExp.test( f )
|
|
210
|
+
);
|
|
178
211
|
if ( ! chunkJSFile ) {
|
|
179
212
|
// There's no JS file in this chunk, no work for us. Typically a `style.css` from cache group.
|
|
180
213
|
continue;
|
|
181
214
|
}
|
|
182
215
|
|
|
183
|
-
|
|
216
|
+
/** @type {Set<string>} */
|
|
217
|
+
const chunkStaticDeps = new Set();
|
|
218
|
+
/** @type {Set<string>} */
|
|
219
|
+
const chunkDynamicDeps = new Set();
|
|
220
|
+
|
|
184
221
|
if ( injectPolyfill ) {
|
|
185
|
-
|
|
222
|
+
chunkStaticDeps.add( 'wp-polyfill' );
|
|
186
223
|
}
|
|
187
224
|
|
|
188
|
-
|
|
225
|
+
/**
|
|
226
|
+
* @param {webpack.Module} m
|
|
227
|
+
*/
|
|
228
|
+
const processModule = ( m ) => {
|
|
229
|
+
const { userRequest } = m;
|
|
189
230
|
if ( this.externalizedDeps.has( userRequest ) ) {
|
|
190
|
-
|
|
231
|
+
if ( this.useModules ) {
|
|
232
|
+
const isStatic =
|
|
233
|
+
DependencyExtractionWebpackPlugin.hasStaticDependencyPathToRoot(
|
|
234
|
+
compilation,
|
|
235
|
+
m
|
|
236
|
+
);
|
|
237
|
+
|
|
238
|
+
( isStatic ? chunkStaticDeps : chunkDynamicDeps ).add(
|
|
239
|
+
m.request
|
|
240
|
+
);
|
|
241
|
+
} else {
|
|
242
|
+
chunkStaticDeps.add(
|
|
243
|
+
this.mapRequestToDependency( userRequest )
|
|
244
|
+
);
|
|
245
|
+
}
|
|
191
246
|
}
|
|
192
247
|
};
|
|
193
248
|
|
|
194
249
|
// Search for externalized modules in all chunks.
|
|
195
|
-
const
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
for ( const chunkModule of modulesIterable ) {
|
|
250
|
+
for ( const chunkModule of compilation.chunkGraph.getChunkModulesIterable(
|
|
251
|
+
chunk
|
|
252
|
+
) ) {
|
|
199
253
|
processModule( chunkModule );
|
|
200
254
|
// Loop through submodules of ConcatenatedModule.
|
|
201
255
|
if ( chunkModule.modules ) {
|
|
@@ -224,11 +278,20 @@ class DependencyExtractionWebpackPlugin {
|
|
|
224
278
|
.slice( 0, hashDigestLength );
|
|
225
279
|
|
|
226
280
|
const assetData = {
|
|
227
|
-
|
|
228
|
-
|
|
281
|
+
dependencies: [
|
|
282
|
+
// Sort these so we can produce a stable, stringified representation.
|
|
283
|
+
...Array.from( chunkStaticDeps ).sort(),
|
|
284
|
+
...Array.from( chunkDynamicDeps )
|
|
285
|
+
.sort()
|
|
286
|
+
.map( ( id ) => ( { id, type: 'dynamic' } ) ),
|
|
287
|
+
],
|
|
229
288
|
version: contentHash,
|
|
230
289
|
};
|
|
231
290
|
|
|
291
|
+
if ( this.useModules ) {
|
|
292
|
+
assetData.type = 'module';
|
|
293
|
+
}
|
|
294
|
+
|
|
232
295
|
if ( combineAssets ) {
|
|
233
296
|
combinedAssetsData[ chunkJSFile ] = assetData;
|
|
234
297
|
continue;
|
|
@@ -246,14 +309,14 @@ class DependencyExtractionWebpackPlugin {
|
|
|
246
309
|
'.asset.' + ( outputFormat === 'php' ? 'php' : 'json' );
|
|
247
310
|
assetFilename = compilation
|
|
248
311
|
.getPath( '[file]', { filename: chunkJSFile } )
|
|
249
|
-
.replace( /\.js$/i, suffix );
|
|
312
|
+
.replace( /\.m?js$/i, suffix );
|
|
250
313
|
}
|
|
251
314
|
|
|
252
315
|
// Add source and file into compilation for webpack to output.
|
|
253
316
|
compilation.assets[ assetFilename ] = new RawSource(
|
|
254
317
|
this.stringify( assetData )
|
|
255
318
|
);
|
|
256
|
-
chunk.files
|
|
319
|
+
chunk.files.add( assetFilename );
|
|
257
320
|
}
|
|
258
321
|
|
|
259
322
|
if ( combineAssets ) {
|
|
@@ -275,6 +338,58 @@ class DependencyExtractionWebpackPlugin {
|
|
|
275
338
|
);
|
|
276
339
|
}
|
|
277
340
|
}
|
|
341
|
+
|
|
342
|
+
/**
|
|
343
|
+
* Can we trace a line of static dependencies from an entry to a module
|
|
344
|
+
*
|
|
345
|
+
* @param {webpack.Compilation} compilation
|
|
346
|
+
* @param {webpack.DependenciesBlock} block
|
|
347
|
+
*
|
|
348
|
+
* @return {boolean} True if there is a static import path to the root
|
|
349
|
+
*/
|
|
350
|
+
static hasStaticDependencyPathToRoot( compilation, block ) {
|
|
351
|
+
const incomingConnections = [
|
|
352
|
+
...compilation.moduleGraph.getIncomingConnections( block ),
|
|
353
|
+
].filter(
|
|
354
|
+
( connection ) =>
|
|
355
|
+
// Library connections don't have a dependency, this is a root
|
|
356
|
+
connection.dependency &&
|
|
357
|
+
// Entry dependencies are another root
|
|
358
|
+
connection.dependency.constructor.name !== 'EntryDependency'
|
|
359
|
+
);
|
|
360
|
+
|
|
361
|
+
// If we don't have non-entry, non-library incoming connections,
|
|
362
|
+
// we've reached a root of
|
|
363
|
+
if ( ! incomingConnections.length ) {
|
|
364
|
+
return true;
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
const staticDependentModules = incomingConnections.flatMap(
|
|
368
|
+
( connection ) => {
|
|
369
|
+
const { dependency } = connection;
|
|
370
|
+
const parentBlock =
|
|
371
|
+
compilation.moduleGraph.getParentBlock( dependency );
|
|
372
|
+
|
|
373
|
+
return parentBlock.constructor.name !==
|
|
374
|
+
AsyncDependenciesBlock.name
|
|
375
|
+
? [ compilation.moduleGraph.getParentModule( dependency ) ]
|
|
376
|
+
: [];
|
|
377
|
+
}
|
|
378
|
+
);
|
|
379
|
+
|
|
380
|
+
// All the dependencies were Async, the module was reached via a dynamic import
|
|
381
|
+
if ( ! staticDependentModules.length ) {
|
|
382
|
+
return false;
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
// Continue to explore any static dependencies
|
|
386
|
+
return staticDependentModules.some( ( parentStaticDependentModule ) =>
|
|
387
|
+
DependencyExtractionWebpackPlugin.hasStaticDependencyPathToRoot(
|
|
388
|
+
compilation,
|
|
389
|
+
parentStaticDependentModule
|
|
390
|
+
)
|
|
391
|
+
);
|
|
392
|
+
}
|
|
278
393
|
}
|
|
279
394
|
|
|
280
395
|
module.exports = DependencyExtractionWebpackPlugin;
|
package/lib/types.d.ts
CHANGED
|
@@ -13,6 +13,9 @@ declare interface DependencyExtractionWebpackPluginOptions {
|
|
|
13
13
|
outputFormat?: 'php' | 'json';
|
|
14
14
|
outputFilename?: string | Function;
|
|
15
15
|
requestToExternal?: ( request: string ) => string | string[] | undefined;
|
|
16
|
+
requestToExternalModule?: (
|
|
17
|
+
request: string
|
|
18
|
+
) => string | boolean | undefined;
|
|
16
19
|
requestToHandle?: ( request: string ) => string | undefined;
|
|
17
20
|
combinedOutputFile?: string | null;
|
|
18
21
|
combineAssets?: boolean;
|
package/lib/util.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
const WORDPRESS_NAMESPACE = '@wordpress/';
|
|
2
2
|
const BUNDLED_PACKAGES = [
|
|
3
|
+
'@wordpress/dataviews',
|
|
3
4
|
'@wordpress/icons',
|
|
4
5
|
'@wordpress/interface',
|
|
5
|
-
'@wordpress/undo-manager',
|
|
6
6
|
'@wordpress/sync',
|
|
7
|
-
'@wordpress/
|
|
7
|
+
'@wordpress/undo-manager',
|
|
8
8
|
];
|
|
9
9
|
|
|
10
10
|
/**
|
|
@@ -56,6 +56,25 @@ function defaultRequestToExternal( request ) {
|
|
|
56
56
|
}
|
|
57
57
|
}
|
|
58
58
|
|
|
59
|
+
/**
|
|
60
|
+
* Default request to external module transformation
|
|
61
|
+
*
|
|
62
|
+
* Currently only @wordpress/interactivity
|
|
63
|
+
*
|
|
64
|
+
* @param {string} request Module request (the module name in `import from`) to be transformed
|
|
65
|
+
* @return {string|undefined} The resulting external definition. Return `undefined`
|
|
66
|
+
* to ignore the request. Return `string` to map the request to an external. This may simply be returning the request, e.g. `@wordpress/interactivity` maps to the external `@wordpress/interactivity`.
|
|
67
|
+
*/
|
|
68
|
+
function defaultRequestToExternalModule( request ) {
|
|
69
|
+
if ( request === '@wordpress/interactivity' ) {
|
|
70
|
+
// This is a special case. Interactivity does not support dynamic imports at this
|
|
71
|
+
// time. We add the external "module" type to indicate that webpack should
|
|
72
|
+
// externalize this as a module (instead of our default `import()` external type)
|
|
73
|
+
// which forces @wordpress/interactivity imports to be hoisted to static imports.
|
|
74
|
+
return `module ${ request }`;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
59
78
|
/**
|
|
60
79
|
* Default request to WordPress script handle transformation
|
|
61
80
|
*
|
|
@@ -101,5 +120,6 @@ function camelCaseDash( string ) {
|
|
|
101
120
|
module.exports = {
|
|
102
121
|
camelCaseDash,
|
|
103
122
|
defaultRequestToExternal,
|
|
123
|
+
defaultRequestToExternalModule,
|
|
104
124
|
defaultRequestToHandle,
|
|
105
125
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wordpress/dependency-extraction-webpack-plugin",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "5.0.1-next.79a6196f.0",
|
|
4
4
|
"description": "Extract WordPress script dependencies from webpack bundles.",
|
|
5
5
|
"author": "The WordPress Contributors",
|
|
6
6
|
"license": "GPL-2.0-or-later",
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
"url": "https://github.com/WordPress/gutenberg/issues"
|
|
21
21
|
},
|
|
22
22
|
"engines": {
|
|
23
|
-
"node": ">=
|
|
23
|
+
"node": ">=18"
|
|
24
24
|
},
|
|
25
25
|
"files": [
|
|
26
26
|
"lib",
|
|
@@ -29,14 +29,13 @@
|
|
|
29
29
|
"main": "lib/index.js",
|
|
30
30
|
"types": "lib/types.d.ts",
|
|
31
31
|
"dependencies": {
|
|
32
|
-
"json2php": "^0.0.7"
|
|
33
|
-
"webpack-sources": "^3.2.2"
|
|
32
|
+
"json2php": "^0.0.7"
|
|
34
33
|
},
|
|
35
34
|
"peerDependencies": {
|
|
36
|
-
"webpack": "^
|
|
35
|
+
"webpack": "^5.0.0"
|
|
37
36
|
},
|
|
38
37
|
"publishConfig": {
|
|
39
38
|
"access": "public"
|
|
40
39
|
},
|
|
41
|
-
"gitHead": "
|
|
40
|
+
"gitHead": "1e74b942ac0119a22ceaaf5c9594263f3ec516ab"
|
|
42
41
|
}
|