Skip to content

Commit

Permalink
Use DEWP's new auto-wp-polyfill support (#39629)
Browse files Browse the repository at this point in the history
`@wordpress/dependency-extraction-webpack-plugin` has added the ability
to detect a magic `/* wp:polyfill */` comment and only add `wp-polyfill`
as a dependency if that is found. Since `wp-polyfill` is just a custom
build of `core-js`, the intention is that
`babel-plugin-polyfill-corejs3` (maybe via `@babel/preset-env`) would be
used and then a custom Babel plugin would replace the `core-js` imports
with the magic comment.

This updates our Babel config to do just that, and removes the blanket
addition of `wp-polyfill` via `injectPolyfill` or otherwise.
  • Loading branch information
anomiex authored and gogdzl committed Oct 25, 2024
1 parent 4a9e683 commit 395d809
Show file tree
Hide file tree
Showing 66 changed files with 321 additions and 135 deletions.
15 changes: 6 additions & 9 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

18 changes: 16 additions & 2 deletions projects/js-packages/webpack-config/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ This provides all of the plugins listed below. The `options` object can be used
plugins: {
...StandardPlugins( {
DuplicatePackageCheckerPlugin: false,
DependencyExtractionPlugin: { injectPolyfill: true },
DependencyExtractionPlugin: { requestMap: { foo: {} },
} ),
}
```
Expand All @@ -162,6 +162,14 @@ You can pass any additional defines as the `defines` parameter. Note it is not n
This provides an instance of [@wordpress/dependency-extraction-webpack-plugin](https://www.npmjs.com/package/@wordpress/dependency-extraction-webpack-plugin). The `options` are passed to the plugin.
By default, the following additional dependencies are extracted:
- `@automattic/jetpack-script-data`: Handle `jetpack-script-data` provided by PHP package [automattic/jetpack-assets](https://packagist.org/packages/automattic/jetpack-assets).
- `@automattic/jetpack-connection`: Handle `jetpack-connection` provided by PHP package [automattic/jetpack-connection](https://packagist.org/packages/automattic/jetpack-connection).
One additional option is recognized:
- `requestMap`: An easier way to specify additional dependencies to extract, rather than redefining `requestToHandle` and `requestToExternal`. Key is the dependency, value is an object with `handle` and `external` keys corresponding to the return values of `requestToHandle` and `requestToExternal`.
##### `DuplicatePackageCheckerPlugin( options )`
This provides an instance of [@cerner/duplicate-package-checker-webpack-plugin](https://www.npmjs.com/package/@cerner/duplicate-package-checker-webpack-plugin). The `options` are passed to the plugin.
Expand Down Expand Up @@ -284,11 +292,17 @@ The options passed to the preset allow you to exclude (by passing false) or amen
The options and corresponding components are:
- `targets`: Set targets for various plugins. Default is your browserslist config if available, otherwise [@wordpress/browserslist-config](https://www.npmjs.com/package/@wordpress/browserslist-config).
- `autoWpPolyfill`: Set false to disable use of [babel-plugin-polyfill-corejs3](https://www.npmjs.com/package/babel-plugin-polyfill-corejs3) to produce magic `/* wp:polyfill */` comments that [@wordpress/dependency-extraction-webpack-plugin](https://www.npmjs.com/package/@wordpress/dependency-extraction-webpack-plugin) will use to add a dep on `wp-polyfill`.
Options include:
- `exclude`: Core-js polyfills to ignore. Defaults to exclude 'es.array.push' and 'web.immediate'.
- `targets`: Override top-level `targets`.
- `presetEnv`: Corresponds to [@babel/preset-env](https://www.npmjs.com/package/@babel/preset-env).
Note the following options that are different from `@babel/preset-env`'s defaults:
- `exclude`: Set to `[ 'transform-typeof-symbol' ]`, as that [apparently makes all code slower](https://github.com/facebook/create-react-app/pull/5278).
- `targets`: Set to your browserslist config if available, otherwise set to [@wordpress/browserslist-config](https://www.npmjs.com/package/@wordpress/browserslist-config).
- `targets`: Set based on top-level `targets`.
- `presetReact`: Corresponds to [@babel/preset-react](https://www.npmjs.com/package/@babel/preset-react).
- `presetTypescript`: Corresponds to [@babel/preset-typescript](https://www.npmjs.com/package/@babel/preset-typescript).
- `pluginReplaceTextdomain`: Corresponds to [@automattic/babel-plugin-replace-textdomain](https://www.npmjs.com/package/@automattic/babel-plugin-replace-textdomain).
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: patch
Type: fixed

Babel preset: Fix `pluginPreserveI18n` option.
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: minor
Type: added

Babel preset: Add default for base `targets` option, replacing default `.presetEnv.targets`.
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: minor
Type: added

Babel preset: Add `autoWpPolyfill` option.
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: patch
Type: fixed

Update documentation for `DependencyExtractionPlugin` after #38877 and #38430.
2 changes: 2 additions & 0 deletions projects/js-packages/webpack-config/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,9 @@
"@wordpress/browserslist-config": "6.9.0",
"@wordpress/dependency-extraction-webpack-plugin": "6.9.0",
"babel-loader": "9.1.2",
"babel-plugin-polyfill-corejs3": "0.10.6",
"browserslist": "4.23.1",
"core-js": "3.38.1",
"css-loader": "6.5.1",
"css-minimizer-webpack-plugin": "5.0.1",
"fork-ts-checker-webpack-plugin": "9.0.2",
Expand Down
82 changes: 62 additions & 20 deletions projects/js-packages/webpack-config/src/babel-preset.js
Original file line number Diff line number Diff line change
@@ -1,33 +1,70 @@
const path = require( 'path' );

const PresetEnv = ( options = {} ) => {
if ( typeof options.targets === 'undefined' ) {
module.exports = ( api, opts = {} ) => {
const ret = {
sourceType: opts.sourceType || 'unambiguous',
presets: [],
plugins: [],
};

let targets = opts.targets;
if ( ! targets ) {
const browserslist = require( 'browserslist' );
const localBrowserslistConfig = browserslist.findConfig( '.' ) || {};
options.targets = browserslist(
targets = browserslist(
localBrowserslistConfig.defaults || require( '@wordpress/browserslist-config' )
);
}

return [
require.resolve( '@babel/preset-env' ),
{
// Exclude transforms that make all code slower, see https://github.com/facebook/create-react-app/pull/5278
exclude: [ 'transform-typeof-symbol' ],
...options,
},
];
};
if ( opts.autoWpPolyfill !== false ) {
if ( opts.presetEnv?.useBuiltIns ) {
throw new Error( 'Cannot use autoWpPolyfill along with presetEnv.useBuiltIns' );
}
if ( opts.pluginTransformRuntime?.corejs ) {
throw new Error( 'Cannot use autoWpPolyfill along with pluginTransformRuntime.corejs' );
}

module.exports = ( api, opts = {} ) => {
const ret = {
sourceType: opts.sourceType || 'unambiguous',
presets: [],
plugins: [],
};
const importDir = opts.autoWpPolyfill?.absoluteImports ?? path.dirname( __dirname );
ret.plugins.push(
[
require.resolve( 'babel-plugin-polyfill-corejs3' ),
{
method: 'usage-global',
version: require( 'core-js/package.json' ).version,
absoluteImports: importDir,
targets: opts.autoWpPolyfill?.targets ?? targets,
exclude: opts.autoWpPolyfill?.exclude ?? [
// Ignore excessively strict polyfilling of `Array.prototype.push` to work
// around an obscure bug involving non-writable arrays.
// See https://issues.chromium.org/issues/42202623 for the details of the
// bug that leads to the polyfilling, and which we are choosing to ignore.
'es.array.push',

// This is an IE-only feature which we don't use, and don't want to polyfill.
// @see https://github.com/WordPress/gutenberg/pull/49234
'web.immediate',
],
},
],
[
require.resolve( './babel/replace-polyfills.js' ),
{
absoluteImports: importDir,
},
]
);
}

if ( opts.presetEnv !== false ) {
ret.presets.push( PresetEnv( opts.presetEnv ) );
ret.presets.push( [
require.resolve( '@babel/preset-env' ),
{
targets,
// Exclude transforms that make all code slower, see https://github.com/facebook/create-react-app/pull/5278
exclude: [ 'transform-typeof-symbol' ],
...opts.presetEnv,
},
] );
}
if ( opts.presetReact !== false ) {
ret.presets.push( [ require.resolve( '@babel/preset-react' ), opts.presetReact ] );
Expand All @@ -43,18 +80,23 @@ module.exports = ( api, opts = {} ) => {
] );
}
if ( opts.pluginTransformRuntime !== false ) {
// babel-plugin-polyfill-corejs3 from autoWpPolyfill otherwise makes it want @babel/runtime-corejs3
const optModuleName =
opts.autoWpPolyfill !== false ? { moduleName: '@babel/runtime' } : undefined;

ret.plugins.push( [
require.resolve( '@babel/plugin-transform-runtime' ),
{
corejs: false, // We polyfill so we don't need core-js.
regenerator: false,
absoluteRuntime: path.dirname( __dirname ), // Required when workspace projects are symlinked.
version: require( '@babel/runtime/package.json' )?.version,
...optModuleName,
...opts.pluginTransformRuntime,
},
] );
}
if ( opts.pluginCalypsoOptimizeI18n !== false ) {
if ( opts.pluginPreserveI18n !== false ) {
ret.plugins.push( [
require.resolve( '@automattic/babel-plugin-preserve-i18n' ),
opts.pluginPreserveI18n,
Expand Down
74 changes: 74 additions & 0 deletions projects/js-packages/webpack-config/src/babel/replace-polyfills.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
const npath = require( 'path' );

/**
* Babel plugin that looks for `core-js` imports (or requires)
* and replaces them with magic comments to mark the file as
* depending on wp-polyfill.
*
* Based on https://github.com/WordPress/gutenberg/blob/28f1b5b308a62098f0e1e253cb734c83b2fa1356/packages/babel-preset-default/replace-polyfills.js
*
* @param {object} babel - Babel object.
* @param {object} opts - Options from Babel config.
* @return {object} Babel plugin.
*/
module.exports = ( babel, opts ) => {
const { types: t } = babel;
const coreJsPrefix = opts.absoluteImports
? npath.dirname(
require.resolve( 'core-js/package.json', { paths: [ opts.absoluteImports ] } )
) + '/'
: 'core-js/';

return {
name: 'replacePolyfills',
pre() {
this.hasAddedPolyfills = false;
},
visitor: {
Program: {
exit( path ) {
if ( this.hasAddedPolyfills ) {
// Add magic comment to top of file.
path.addComment( 'leading', ' wp:polyfill ' );
}
},
},

// Handle `import` syntax.
ImportDeclaration( path ) {
const source = path.node.source;
const name = source.value || '';

// Look for imports from `core-js`.
if ( name.startsWith( coreJsPrefix ) ) {
// Replace import.
path.replaceWith( t.noop() );
path.addComment( 'leading', ` wp:polyfill ${ npath.basename( name, '.js' ) } ` );
this.hasAddedPolyfills = true;
}
},

// Handle `require` syntax.
ExpressionStatement( path ) {
const expression = path.node.expression;
if ( ! t.isCallExpression( expression ) ) {
return;
}

const callee = expression.callee;
const arg = expression.arguments[ 0 ];
if (
t.isIdentifier( callee ) &&
callee.name === 'require' &&
t.isStringLiteral( arg ) &&
arg.value.startsWith( coreJsPrefix )
) {
// Replace require.
path.replaceWith( t.noop() );
path.addComment( 'leading', ` wp:polyfill ${ npath.basename( arg.value, '.js' ) } ` );
this.hasAddedPolyfills = true;
}
},
},
};
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: patch
Type: changed

Only include `wp-polyfill` as a script dependency when needed.
6 changes: 1 addition & 5 deletions projects/packages/backup/webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,7 @@ module.exports = [
...jetpackWebpackConfig.resolve,
},
node: false,
plugins: [
...jetpackWebpackConfig.StandardPlugins( {
DependencyExtractionPlugin: { injectPolyfill: true },
} ),
],
plugins: [ ...jetpackWebpackConfig.StandardPlugins() ],
module: {
strictExportPresence: true,
rules: [
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: patch
Type: changed

Only include `wp-polyfill` as a script dependency when needed.
6 changes: 1 addition & 5 deletions projects/packages/blaze/webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,7 @@ module.exports = [
optimization: {
...jetpackWebpackConfig.optimization,
},
plugins: [
...jetpackWebpackConfig.StandardPlugins( {
DependencyExtractionPlugin: { injectPolyfill: true },
} ),
],
plugins: [ ...jetpackWebpackConfig.StandardPlugins() ],
resolve: {
...jetpackWebpackConfig.resolve,
},
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Significance: patch
Type: removed
Comment: Remove unnecessary JS dep on `@wordpress/dependency-extraction-webpack-plugin`


1 change: 0 additions & 1 deletion projects/packages/classic-theme-helper/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@
"@babel/core": "7.24.7",
"@csstools/postcss-global-data": "2.1.1",
"@wordpress/browserslist-config": "6.9.0",
"@wordpress/dependency-extraction-webpack-plugin": "6.9.0",
"autoprefixer": "10.4.14",
"glob": "10.4.1",
"postcss": "8.4.31",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: patch
Type: changed

Only include `wp-polyfill` as a script dependency when needed.
6 changes: 1 addition & 5 deletions projects/packages/explat/webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,7 @@ module.exports = [
...jetpackWebpackConfig.resolve,
},
node: false,
plugins: [
...jetpackWebpackConfig.StandardPlugins( {
DependencyExtractionPlugin: { injectPolyfill: true },
} ),
],
plugins: [ ...jetpackWebpackConfig.StandardPlugins() ],
module: {
strictExportPresence: true,
rules: [
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: patch
Type: changed

Only include `wp-polyfill` as a script dependency when needed.
6 changes: 1 addition & 5 deletions projects/packages/forms/tools/webpack.config.blocks.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,7 @@ const sharedWebpackConfig = {
...jetpackWebpackConfig.resolve,
},
node: {},
plugins: [
...jetpackWebpackConfig.StandardPlugins( {
DependencyExtractionPlugin: { injectPolyfill: true },
} ),
],
plugins: [ ...jetpackWebpackConfig.StandardPlugins() ],
externals: {
...jetpackWebpackConfig.externals,
jetpackConfig: JSON.stringify( {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: patch
Type: changed

Only include `wp-polyfill` as a script dependency when needed.
Loading

0 comments on commit 395d809

Please sign in to comment.