diff --git a/.changeset/angry-hairs-bathe.md b/.changeset/angry-hairs-bathe.md
new file mode 100644
index 000000000000..05b220b86c80
--- /dev/null
+++ b/.changeset/angry-hairs-bathe.md
@@ -0,0 +1,7 @@
+---
+'@modern-js/plugin-garfish': patch
+---
+
+fix: garfish plugin use custom bootstrap not work
+
+fix: 修复 garfish 插件使用 custom bootstrap 不生效问题
diff --git a/packages/runtime/plugin-garfish/src/cli/code.ts b/packages/runtime/plugin-garfish/src/cli/code.ts
index 59762ab7e66b..5ad2129760cf 100644
--- a/packages/runtime/plugin-garfish/src/cli/code.ts
+++ b/packages/runtime/plugin-garfish/src/cli/code.ts
@@ -25,7 +25,8 @@ export const generateCode = async (
appContext;
await Promise.all(
entrypoints.map(async entrypoint => {
- const { entryName, isAutoMount, entry, customEntry } = entrypoint;
+ const { entryName, isAutoMount, entry, customEntry, customBootstrap } =
+ entrypoint;
const appendCode = await appendEntryCode({ entrypoint });
if (isAutoMount) {
@@ -37,6 +38,7 @@ export const generateCode = async (
entry,
entryName,
customEntry,
+ customBootstrap,
mountId,
appendCode,
});
diff --git a/packages/runtime/plugin-garfish/src/cli/template.ts b/packages/runtime/plugin-garfish/src/cli/template.ts
index 5025bb588be8..89ee236914a0 100644
--- a/packages/runtime/plugin-garfish/src/cli/template.ts
+++ b/packages/runtime/plugin-garfish/src/cli/template.ts
@@ -1,9 +1,12 @@
+import { formatImportPath } from '@modern-js/utils';
+
const genRenderCode = ({
srcDirectory,
internalSrcAlias,
metaName,
entry,
customEntry,
+ customBootstrap,
mountId,
}: {
srcDirectory: string;
@@ -11,6 +14,7 @@ const genRenderCode = ({
metaName: string;
entry: string;
customEntry?: boolean;
+ customBootstrap?: string | false;
mountId?: string;
}) =>
customEntry
@@ -18,9 +22,18 @@ const genRenderCode = ({
export * from '${entry.replace(srcDirectory, internalSrcAlias)}'`
: `import { garfishRender, createProvider } from '@${metaName}/plugin-garfish/runtime';
-garfishRender('${mountId || 'root'}' )
+${
+ customBootstrap
+ ? `import customBootstrap from '${formatImportPath(
+ customBootstrap.replace(srcDirectory, internalSrcAlias),
+ )}';`
+ : 'let customBootstrap;'
+}
+garfishRender('${mountId || 'root'}', customBootstrap)
-export const provider = createProvider();
+export const provider = createProvider(undefined, ${
+ customBootstrap ? 'customBootstrap' : undefined
+ });
`;
export const index = ({
srcDirectory,
@@ -29,6 +42,7 @@ export const index = ({
entry,
entryName,
customEntry,
+ customBootstrap,
mountId,
appendCode = [],
}: {
@@ -38,6 +52,7 @@ export const index = ({
entry: string;
entryName: string;
customEntry?: boolean;
+ customBootstrap?: string | false;
mountId?: string;
appendCode?: string[];
}) =>
@@ -48,6 +63,7 @@ export const index = ({
metaName,
entry,
customEntry,
+ customBootstrap,
mountId,
})}
${appendCode.join('\n')}
diff --git a/packages/runtime/plugin-garfish/src/runtime/provider.tsx b/packages/runtime/plugin-garfish/src/runtime/provider.tsx
index e0158282b939..fce4d1f980c8 100644
--- a/packages/runtime/plugin-garfish/src/runtime/provider.tsx
+++ b/packages/runtime/plugin-garfish/src/runtime/provider.tsx
@@ -3,7 +3,13 @@ import type { Root } from 'react-dom/client';
import { createPortal, unmountComponentAtNode } from 'react-dom';
import { garfishRender } from './render';
-export function createProvider(id?: string) {
+export function createProvider(
+ id?: string,
+ customBootstrap?: (
+ App: React.ComponentType,
+ render: () => void,
+ ) => HTMLElement | null,
+) {
return ({ basename, dom }: { basename: string; dom: HTMLElement }) => {
let root: HTMLElement | Root | null = null;
return {
@@ -18,7 +24,7 @@ export function createProvider(id?: string) {
props: any;
appName?: string;
}) {
- root = await garfishRender(id || 'root', {
+ root = await garfishRender(id || 'root', customBootstrap, {
basename,
dom,
props,
diff --git a/packages/runtime/plugin-garfish/src/runtime/render.tsx b/packages/runtime/plugin-garfish/src/runtime/render.tsx
index d672deeb0032..b89185bb9950 100644
--- a/packages/runtime/plugin-garfish/src/runtime/render.tsx
+++ b/packages/runtime/plugin-garfish/src/runtime/render.tsx
@@ -38,13 +38,25 @@ function canContinueRender({
}
}
-export async function garfishRender(mountId?: string, _params?: any) {
+export async function garfishRender(
+ mountId?: string,
+ customBootstrap?: (
+ App: React.ComponentType,
+ render: () => void,
+ ) => HTMLElement | null,
+ _params?: any,
+) {
const { basename, props, dom, appName } =
// eslint-disable-next-line prefer-rest-params
- (typeof arguments[1] === 'object' && arguments[1]) || {};
+ (typeof arguments[2] === 'object' && arguments[2]) || {};
if (canContinueRender({ dom, appName })) {
const ModernRoot = createRoot(null, { router: { basename } });
- return await render(
+ if (customBootstrap) {
+ return customBootstrap(ModernRoot, () =>
+ render(, dom || mountId),
+ );
+ }
+ return render(
,
dom || mountId,
);
diff --git a/tests/integration/garfish/app-dashboard/src/index.tsx b/tests/integration/garfish/app-dashboard/src/index.tsx
new file mode 100644
index 000000000000..afeac4e2287f
--- /dev/null
+++ b/tests/integration/garfish/app-dashboard/src/index.tsx
@@ -0,0 +1,12 @@
+const sleep = () =>
+ new Promise(resolve => {
+ console.log('custom bootstrap');
+ setTimeout(resolve, 300);
+ });
+
+export default (_App: React.ComponentType, bootstrap: () => void) => {
+ // do something before bootstrap...
+ sleep().then(() => {
+ bootstrap();
+ });
+};