@@ -153,12 +153,35 @@ function wp_options_connectors_wp_admin_enqueue_scripts( $hook_suffix ) {
153153 // 2. It initializes the boot module as an inline script.
154154 wp_register_script ( 'options-connectors-wp-admin-prerequisites ' , '' , $ asset ['dependencies ' ], $ asset ['version ' ], true );
155155
156- // Add inline script to initialize the app using initSinglePage (no menuItems)
156+ /*
157+ * Add inline script to initialize the app using initSinglePage (no menuItems).
158+ * The dynamic import is deferred until DOMContentLoaded so that all classic
159+ * script dependencies of @wordpress/boot (wp-private-apis, wp-components,
160+ * wp-theme, etc.) have finished parsing and executing before the boot module
161+ * evaluates. Otherwise, a modulepreloaded @wordpress/boot can win the race
162+ * against the classic-script-printing pass on fast CDN-fronted hosts in
163+ * Chrome, evaluating before wp.theme.privateApis is defined and throwing
164+ * "Cannot unlock an undefined object". See <https://core.trac.wordpress.org/ticket/65103>.
165+ */
166+ $ init_js_function = <<<'JS'
167+ ( mountId, routes ) => {
168+ const run = async () => {
169+ const mod = await import( "@wordpress/boot" );
170+ mod.initSinglePage( { mountId, routes } );
171+ };
172+ if ( document.readyState === "loading" ) {
173+ document.addEventListener( "DOMContentLoaded", run );
174+ } else {
175+ run();
176+ }
177+ }
178+ JS;
157179 wp_add_inline_script (
158180 'options-connectors-wp-admin-prerequisites ' ,
159181 sprintf (
160- 'import("@wordpress/boot").then(mod => mod.initSinglePage({mountId: "%s", routes: %s})); ' ,
161- 'options-connectors-wp-admin-app ' ,
182+ '( %s )( %s, %s ); ' ,
183+ $ init_js_function ,
184+ wp_json_encode ( 'options-connectors-wp-admin-app ' , JSON_HEX_TAG | JSON_UNESCAPED_SLASHES ),
162185 wp_json_encode ( $ routes , JSON_HEX_TAG | JSON_UNESCAPED_SLASHES )
163186 )
164187 );
0 commit comments