Commit 61980b2bd23 for woocommerce
commit 61980b2bd233374df53a836533ae619ca31a198d
Author: Vlad Olaru <vlad.olaru@automattic.com>
Date: Mon Sep 21 13:37:54 2026 +0300
[dev] Fix blocks lint, dev and start scripts crashing on every run (#68836)
* fix(blocks): Accept either webpack config shape from wp-scripts
The interactivity blocks config destructured
`@wordpress/scripts/config/webpack.config` as an array. That module
only exports an array when `WP_EXPERIMENTAL_MODULES` is set, and a
bare object otherwise, so loading `webpack.config.js` without the
variable threw `TypeError: require is not a function or its return
value is not iterable`. Every entry point that reaches this config
was affected, including ESLint, whose flat config resolves imports
through the webpack resolver.
Since #56758 introduced the destructure, five pull requests have
each set the variable at one more call site rather than changing the
assumption. The variable is not needed: the only value read from the
export is `module.rules`, and both of wp-scripts' configs take it
from the same `baseConfig` object. With the flag set they are the
same object by identity, and a production build is byte-identical
either way.
Read `module.rules` through an `Array.isArray` branch so the config
loads whatever shape wp-scripts exports, and name the one value it
depends on so a later reader does not take `output` or `experiments`
from the fallback, where the two configs do differ.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix(blocks): Pass a RegExp to CircularDependencyPlugin
CircularDependencyPlugin calls `exclude.test()` on the option directly,
and its own default is a RegExp. The option was an array holding one
RegExp, which has no `test` method, so the `start` script died with
`TypeError: plugin.options.exclude.test is not a function` as soon as
the config loaded far enough to build.
`CHECK_CIRCULAR_DEPS` is set only by `start`, so this never fired
anywhere else and stayed hidden behind the config load error.
The plugin is constructed once, in `getSharedPlugins`, which every
caller including the unified editor assets config goes through, so one
change covers all of them. The other `exclude` options in this file are
webpack module rules, where a `RuleSetCondition` array is valid, and are
left alone.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* chore(blocks): Add changelog entry for the webpack config fixes
A `dev` entry with a comment and no message, so nothing lands in the
published changelog. `.distignore` excludes `/client/` and
`package.json` from the release build, so none of this reaches
merchants.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
diff --git a/plugins/woocommerce/client/blocks/bin/webpack-config-interactive-blocks.js b/plugins/woocommerce/client/blocks/bin/webpack-config-interactive-blocks.js
index 47c691ff726..2250ee96bc2 100644
--- a/plugins/woocommerce/client/blocks/bin/webpack-config-interactive-blocks.js
+++ b/plugins/woocommerce/client/blocks/bin/webpack-config-interactive-blocks.js
@@ -3,10 +3,14 @@
*/
const path = require( 'path' );
const MiniCssExtractPlugin = require( 'mini-css-extract-plugin' );
-const [
- ,
- moduleConfig,
-] = require( '@wordpress/scripts/config/webpack.config' );
+// wp-scripts exports [ scriptConfig, moduleConfig ] when WP_EXPERIMENTAL_MODULES
+// is set, and a bare scriptConfig otherwise. Both carry the same module.rules,
+// which is the only thing taken from it here, so read that one value instead of
+// depending on the export's shape.
+const wpScriptsConfig = require( '@wordpress/scripts/config/webpack.config' );
+const {
+ module: { rules: wpScriptsModuleRules },
+} = Array.isArray( wpScriptsConfig ) ? wpScriptsConfig[ 1 ] : wpScriptsConfig;
const DependencyExtractionWebpackPlugin = require( '@woocommerce/dependency-extraction-webpack-plugin' );
const {
WebpackRTLPlugin,
@@ -99,7 +103,7 @@ module.exports = {
],
module: {
rules: [
- ...moduleConfig.module.rules.filter(
+ ...wpScriptsModuleRules.filter(
( rule ) =>
! rule.test.test( '.css' ) &&
! rule.test.test( '.scss' ) &&
diff --git a/plugins/woocommerce/client/blocks/bin/webpack-configs.js b/plugins/woocommerce/client/blocks/bin/webpack-configs.js
index eae229beb69..d65028ae9ab 100644
--- a/plugins/woocommerce/client/blocks/bin/webpack-configs.js
+++ b/plugins/woocommerce/client/blocks/bin/webpack-configs.js
@@ -58,7 +58,9 @@ const getSharedPlugins = ( {
[
CHECK_CIRCULAR_DEPS === 'true' && checkCircularDeps !== false
? new CircularDependencyPlugin( {
- exclude: [ /[\/\\](node_modules|build|docs|vendor)[\/\\]/ ],
+ // This plugin calls exclude.test() directly, so it must be a
+ // single RegExp, not the array webpack's module rules accept.
+ exclude: /[\/\\](node_modules|build|docs|vendor)[\/\\]/,
cwd: process.cwd(),
failOnError: 'warn',
} )
diff --git a/plugins/woocommerce/client/blocks/changelog/fix-blocks-webpack-config-export-shape b/plugins/woocommerce/client/blocks/changelog/fix-blocks-webpack-config-export-shape
new file mode 100644
index 00000000000..933870847d2
--- /dev/null
+++ b/plugins/woocommerce/client/blocks/changelog/fix-blocks-webpack-config-export-shape
@@ -0,0 +1,3 @@
+Significance: patch
+Type: dev
+Comment: Load the blocks webpack config whatever shape @wordpress/scripts exports, so it no longer needs WP_EXPERIMENTAL_MODULES, and pass CircularDependencyPlugin a RegExp so the start script builds; developer tooling only, no production change.