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(); + }); +};