Skip to content

Commit cfa6648

Browse files
authored
fix: Configure fetch requests occurring during editor initialization (#168)
* fix: Authenticate fetch requests occurring during the loading sequence Some modules perform fetch requests immediately when loaded. To ensure these requests use GutenbergKit's fetch configuration, we must load and configure the `@wordpress/api-fetch` module before loading all others. * refactor: Rename remote-editor to editor-loader The module focuses on loading editor assets. * refactor: Reorganize initialization logic to improve testability * refactor: Abstract shared editor styles * test: Assert remote editor loading sequence
1 parent 2224ad2 commit cfa6648

File tree

11 files changed

+485
-164
lines changed

11 files changed

+485
-164
lines changed

src/index.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
</head>
1111
<body class="gutenberg-kit wp-embed-responsive">
1212
<div id="root" class="gutenberg-kit-root"></div>
13-
<script type="module" src="/index.jsx"></script>
13+
<script type="module" src="/index.js"></script>
1414
<div
1515
id="popover-fallback-container"
1616
class="components-popover__fallback-container"

src/index.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
/**
2+
* Internal dependencies
3+
*/
4+
import { initializeBundledEditor } from './utils/bundled-editor';
5+
import './index.scss';
6+
7+
initializeBundledEditor();

src/index.jsx

Lines changed: 0 additions & 64 deletions
This file was deleted.

src/remote.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
</head>
1111
<body class="gutenberg-kit wp-embed-responsive">
1212
<div id="root" class="gutenberg-kit-root"></div>
13-
<script type="module" src="/remote.jsx"></script>
13+
<script type="module" src="/remote.js"></script>
1414
<div
1515
id="popover-fallback-container"
1616
class="components-popover__fallback-container"

src/remote.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
/**
2+
* Internal dependencies
3+
*/
4+
import { initializeRemoteEditor } from './utils/remote-editor';
5+
import './index.scss';
6+
7+
initializeRemoteEditor();

src/remote.jsx

Lines changed: 0 additions & 98 deletions
This file was deleted.

src/utils/bundled-editor.jsx

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
/**
2+
* WordPress dependencies
3+
*/
4+
import { createRoot, StrictMode } from '@wordpress/element';
5+
6+
/**
7+
* Internal dependencies
8+
*/
9+
import { initializeApiFetch } from './api-fetch';
10+
import { awaitGBKitGlobal, editorLoaded } from './bridge';
11+
import { configureLocale } from './localization';
12+
import EditorLoadError from '../components/editor-load-error';
13+
import { error } from './logger';
14+
import './editor-styles.js';
15+
16+
/**
17+
* Initialize the bundled editor by loading assets and configuring modules
18+
* in the correct sequence.
19+
*
20+
* @return {Promise} Promise that resolves when initialization is complete
21+
*/
22+
export function initializeBundledEditor() {
23+
// Rely upon promises rather than async/await to avoid timeouts caused by
24+
// circular dependencies. Addressing the circular dependencies is quite
25+
// challenging due to Vite's preload helpers and bugs in `manualChunks`
26+
// configuration.
27+
//
28+
// See:
29+
// - https://github.com/vitejs/vite/issues/18551
30+
// - https://github.com/vitejs/vite/issues/13952
31+
// - https://github.com/vitejs/vite/issues/5189#issuecomment-2175410148
32+
return awaitGBKitGlobal()
33+
.then( initializeApiAndLocale )
34+
.then( importEditor )
35+
.then( initializeEditor )
36+
.catch( handleError );
37+
}
38+
39+
function initializeApiAndLocale() {
40+
initializeApiFetch();
41+
return configureLocale();
42+
}
43+
44+
function importEditor() {
45+
return import( './editor' );
46+
}
47+
48+
function initializeEditor( editorModule ) {
49+
const { initializeEditor: _initializeEditor } = editorModule;
50+
_initializeEditor();
51+
}
52+
53+
function handleError( err ) {
54+
error( 'Error initializing editor', err );
55+
const root = document.getElementById( 'root' );
56+
createRoot( root ).render(
57+
<StrictMode>
58+
<EditorLoadError error={ err } />
59+
</StrictMode>
60+
);
61+
editorLoaded();
62+
}
File renamed without changes.

src/utils/editor-styles.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
/**
2+
* WordPress dependencies
3+
*/
4+
// Default styles that are needed for the editor.
5+
import '@wordpress/components/build-style/style.css';
6+
import '@wordpress/block-editor/build-style/style.css';
7+
// Default styles that are needed for the core blocks.
8+
import '@wordpress/block-library/build-style/style.css';
9+
import '@wordpress/block-library/build-style/editor.css';
10+
import '@wordpress/block-library/build-style/theme.css';
11+
import '@wordpress/format-library/build-style/style.css';
12+
import '@wordpress/block-editor/build-style/content.css';
13+
import '@wordpress/editor/build-style/style.css';

src/utils/remote-editor.jsx

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
/**
2+
* Internal dependencies
3+
*/
4+
import { awaitGBKitGlobal } from './bridge';
5+
import { loadEditorAssets } from './editor-loader';
6+
import { initializeVideoPressAjaxBridge } from './videopress-bridge';
7+
import { error, warn } from './logger';
8+
import { isDevMode } from './dev-mode';
9+
import './editor-styles.js';
10+
11+
const I18N_PACKAGES = [ 'i18n', 'hooks' ];
12+
const API_FETCH_PACKAGES = [ 'api-fetch', 'url' ];
13+
14+
/**
15+
* Initialize the remote editor by loading assets and configuring modules
16+
* in the correct sequence.
17+
*
18+
* @return {Promise} Promise that resolves when initialization is complete
19+
*/
20+
export function initializeRemoteEditor() {
21+
// Rely upon promises rather than async/await to avoid timeouts caused by
22+
// circular dependencies. Addressing the circular dependencies is quite
23+
// challenging due to Vite's preload helpers and bugs in `manualChunks`
24+
// configuration.
25+
//
26+
// See:
27+
// - https://github.com/vitejs/vite/issues/18551
28+
// - https://github.com/vitejs/vite/issues/13952
29+
// - https://github.com/vitejs/vite/issues/5189#issuecomment-2175410148
30+
return awaitGBKitGlobal()
31+
.then( initializeApiAndLoadI18n )
32+
.then( importL10n )
33+
.then( configureLocale ) // Configure locale before loading modules with strings
34+
.then( loadApiFetch )
35+
.then( initializeApiFetch ) // Configure API fetch before loading remaining modules
36+
.then( loadRemainingAssets )
37+
.then( initializeEditor )
38+
.catch( handleError );
39+
}
40+
41+
function initializeApiAndLoadI18n() {
42+
return loadEditorAssets( { allowedPackages: I18N_PACKAGES } );
43+
}
44+
45+
function importL10n() {
46+
return import( './localization' );
47+
}
48+
49+
function configureLocale( localeModule ) {
50+
const { configureLocale: _configureLocale } = localeModule;
51+
return _configureLocale();
52+
}
53+
54+
function loadApiFetch() {
55+
return loadEditorAssets( { allowedPackages: API_FETCH_PACKAGES } );
56+
}
57+
58+
function loadRemainingAssets() {
59+
return loadEditorAssets( {
60+
disallowedPackages: [ ...I18N_PACKAGES, ...API_FETCH_PACKAGES ],
61+
} );
62+
}
63+
64+
function initializeApiFetch( assetsResult ) {
65+
return import( './api-fetch' ).then(
66+
( { initializeApiFetch: _initializeApiFetch } ) => {
67+
_initializeApiFetch();
68+
return assetsResult;
69+
}
70+
);
71+
}
72+
73+
function initializeEditor( assetsResult ) {
74+
initializeVideoPressAjaxBridge();
75+
76+
const { allowedBlockTypes } = assetsResult;
77+
return import( './editor' ).then(
78+
( { initializeEditor: _initializeEditor } ) => {
79+
_initializeEditor( { allowedBlockTypes } );
80+
}
81+
);
82+
}
83+
84+
function handleError( err ) {
85+
error( 'Error initializing editor', err );
86+
if ( isDevMode() ) {
87+
warn( 'Dev mode disabled automatic redirect to the local editor.' );
88+
} else {
89+
// Fallback to the local editor and display a notice. Because the remote
90+
// editor loading failed, it is more practical to rely upon the local
91+
// editor's scripts and styles for displaying the notice.
92+
window.location.href = 'index.html?error=gbkit_global_unavailable';
93+
}
94+
}

0 commit comments

Comments
 (0)