diff --git a/packages/dependency-extraction-webpack-plugin/README.md b/packages/dependency-extraction-webpack-plugin/README.md index 0885a38e1c8251..4c3d9f4ac7260d 100644 --- a/packages/dependency-extraction-webpack-plugin/README.md +++ b/packages/dependency-extraction-webpack-plugin/README.md @@ -64,10 +64,10 @@ For example: // Source file entrypoint.js import { Component } from '@wordpress/element'; -// Webpack will produce the output output/entrypoint.js +// Webpack will produce the output `output/path/name.ext` /* bundled JavaScript output */ -// Webpack will also produce output/entrypoint.asset.php declaring script dependencies +// Webpack will also produce `output/path/name.asset.php` declaring script dependencies array('wp-element'), 'version' => 'dd4c2dc50d046ed9d4c063a7ca95702f'); ``` @@ -135,6 +135,22 @@ This option is useful only when the `combineAssets` option is enabled. It allows Pass `useDefaults: false` to disable the default request handling. +##### `excludedExternals` + +- Type: `array` +- Default: `[ '@wordpress/icons', '@wordpress/interface' ]` + +The list of dependencies to exclude from externalizing. The packages listed here will not reach `requestToExternal` callback. +You can provide a new or extend that list with +```javascript +new DependencyExtractionWebpackPlugin( { + excludedExternals: [ + ...DependencyExtractionWebpackPlugin.excludedExternals, + '@wordpress/components' + ] +} ) +``` + ##### `injectPolyfill` - Type: boolean diff --git a/packages/dependency-extraction-webpack-plugin/lib/index.js b/packages/dependency-extraction-webpack-plugin/lib/index.js index 581274c3684f93..6f259373ec1246 100644 --- a/packages/dependency-extraction-webpack-plugin/lib/index.js +++ b/packages/dependency-extraction-webpack-plugin/lib/index.js @@ -13,6 +13,7 @@ const { createHash } = webpack.util; * Internal dependencies */ const { + EXCLUDED_EXTERNALS, defaultRequestToExternal, defaultRequestToHandle, } = require( './util' ); @@ -23,6 +24,7 @@ class DependencyExtractionWebpackPlugin { constructor( options ) { this.options = Object.assign( { + excludedExternals: this.constructor.excludedExternals, combineAssets: false, combinedOutputFile: null, externalizedReport: false, @@ -53,6 +55,9 @@ class DependencyExtractionWebpackPlugin { } externalizeWpDeps( _context, request, callback ) { + if ( this.options.excludedExternals.includes( request ) ) { + return callback(); + } let externalRequest; // Handle via options.requestToExternal first. @@ -277,4 +282,10 @@ class DependencyExtractionWebpackPlugin { } } +// Define a static member in the eslint's ES supported way. +/** + * Set of packages to be bundled regardless of `requestToExternal` result. + */ +DependencyExtractionWebpackPlugin.excludedExternals = EXCLUDED_EXTERNALS; + module.exports = DependencyExtractionWebpackPlugin; diff --git a/packages/dependency-extraction-webpack-plugin/lib/util.js b/packages/dependency-extraction-webpack-plugin/lib/util.js index a22837af6a72e9..33d7c3616f5ff0 100644 --- a/packages/dependency-extraction-webpack-plugin/lib/util.js +++ b/packages/dependency-extraction-webpack-plugin/lib/util.js @@ -1,5 +1,5 @@ const WORDPRESS_NAMESPACE = '@wordpress/'; -const BUNDLED_PACKAGES = [ '@wordpress/icons', '@wordpress/interface' ]; +const EXCLUDED_EXTERNALS = [ '@wordpress/icons', '@wordpress/interface' ]; /** * Default request to global transformation @@ -38,10 +38,6 @@ function defaultRequestToExternal( request ) { return 'ReactRefreshRuntime'; } - if ( BUNDLED_PACKAGES.includes( request ) ) { - return undefined; - } - if ( request.startsWith( WORDPRESS_NAMESPACE ) ) { return [ 'wp', @@ -93,6 +89,7 @@ function camelCaseDash( string ) { } module.exports = { + EXCLUDED_EXTERNALS, camelCaseDash, defaultRequestToExternal, defaultRequestToHandle, diff --git a/packages/dependency-extraction-webpack-plugin/test/__snapshots__/build.js.snap b/packages/dependency-extraction-webpack-plugin/test/__snapshots__/build.js.snap index 0e4ff9e63a10a6..52a8cbbe38e03a 100644 --- a/packages/dependency-extraction-webpack-plugin/test/__snapshots__/build.js.snap +++ b/packages/dependency-extraction-webpack-plugin/test/__snapshots__/build.js.snap @@ -1,5 +1,28 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`DependencyExtractionWebpackPlugin Webpack \`bundled-packages\` should produce expected output: Asset file 'index.min.asset.php' should match snapshot 1`] = ` +" array('react', 'wp-blob'), 'version' => '8df4ae5a12b83b01dbc3'); +" +`; + +exports[`DependencyExtractionWebpackPlugin Webpack \`bundled-packages\` should produce expected output: External modules should match snapshot 1`] = ` +[ + { + "externalType": "window", + "request": "React", + "userRequest": "react", + }, + { + "externalType": "window", + "request": [ + "wp", + "blob", + ], + "userRequest": "@wordpress/blob", + }, +] +`; + exports[`DependencyExtractionWebpackPlugin Webpack \`combine-assets\` should produce expected output: Asset file 'assets.php' should match snapshot 1`] = ` " array('dependencies' => array('lodash', 'wp-blob'), 'version' => 'cbe985cf6e1a25d848e5'), 'fileB.js' => array('dependencies' => array('wp-token-list'), 'version' => '7f3970305cf0aecb54ab')); " diff --git a/packages/dependency-extraction-webpack-plugin/test/fixtures/bundled-packages/index.js b/packages/dependency-extraction-webpack-plugin/test/fixtures/bundled-packages/index.js new file mode 100644 index 00000000000000..6d61f0e8bd10b4 --- /dev/null +++ b/packages/dependency-extraction-webpack-plugin/test/fixtures/bundled-packages/index.js @@ -0,0 +1,11 @@ +/** + * External dependencies + */ +import { ReactDOM } from 'react-dom'; + +/** + * WordPress dependencies + */ +import { isBlobURL } from '@wordpress/blob'; + +isBlobURL( ReactDOM.version ); diff --git a/packages/dependency-extraction-webpack-plugin/test/fixtures/bundled-packages/webpack.config.js b/packages/dependency-extraction-webpack-plugin/test/fixtures/bundled-packages/webpack.config.js new file mode 100644 index 00000000000000..a2633dbe7b292e --- /dev/null +++ b/packages/dependency-extraction-webpack-plugin/test/fixtures/bundled-packages/webpack.config.js @@ -0,0 +1,15 @@ +/** + * Internal dependencies + */ +const DependencyExtractionWebpackPlugin = require( '../../..' ); + +module.exports = { + output: { + filename: 'index.min.js', + }, + plugins: [ + new DependencyExtractionWebpackPlugin( { + excludedExternals: [ 'react-dom' ], + } ), + ], +}; diff --git a/packages/dependency-extraction-webpack-plugin/test/statics.js b/packages/dependency-extraction-webpack-plugin/test/statics.js new file mode 100644 index 00000000000000..6ed2dd376d5d6b --- /dev/null +++ b/packages/dependency-extraction-webpack-plugin/test/statics.js @@ -0,0 +1,13 @@ +/** + * Internal dependencies + */ +const DependencyExtractionWebpackPlugin = require( '../lib/index' ); + +describe( 'DependencyExtractionWebpackPlugin', () => { + test( 'should have .excludedExternals static property', () => { + expect( DependencyExtractionWebpackPlugin ).toHaveProperty( + 'excludedExternals', + [ '@wordpress/icons', '@wordpress/interface' ] + ); + } ); +} );