Skip to content

Commit

Permalink
feat: refactor runtime plugin hooks (#5988)
Browse files Browse the repository at this point in the history
  • Loading branch information
caohuilin committed Jul 31, 2024
1 parent db43d8e commit dc736ef
Show file tree
Hide file tree
Showing 48 changed files with 674 additions and 407 deletions.
10 changes: 10 additions & 0 deletions .changeset/tender-monkeys-attend.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
'@modern-js/plugin-router-v5': minor
'@modern-js/plugin-garfish': minor
'@modern-js/runtime': minor
'@modern-js/plugin-tailwindcss': minor
---

feat: refactor runtime plugin hooks

feat: 重构 runtime 插件钩子函数
12 changes: 12 additions & 0 deletions .changeset/tidy-toys-fold.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
---
'@modern-js/plugin-router-v5': patch
'@modern-js/plugin-garfish': patch
'@modern-js/runtime': patch
'@modern-js/runtime-utils': patch
'@modern-js/plugin-tailwindcss': patch
'@modern-js/plugin': patch
---

feat: Support Runtime Plugin Communication

feat: 支持 Runtime 插件通信
1 change: 1 addition & 0 deletions packages/cli/plugin-tailwind/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
},
"dependencies": {
"@modern-js/utils": "workspace:*",
"@modern-js/runtime-utils": "workspace:*",
"@modern-js/node-bundle-require": "workspace:*",
"babel-plugin-macros": "3.1.0",
"@swc/helpers": "0.5.3"
Expand Down
21 changes: 12 additions & 9 deletions packages/cli/plugin-tailwind/src/design-token/runtime/plugin.tsx
Original file line number Diff line number Diff line change
@@ -1,22 +1,28 @@
import type { Plugin } from '@modern-js/runtime';
import { merge } from '@modern-js/runtime-utils/merge';
import React, { useContext } from 'react';

export const DesignTokenContext = React.createContext<any>({});

export const useDesignTokens = (): IDesignTokens =>
useContext<IDesignTokens>(DesignTokenContext);

export const designTokenPlugin = (
options: {
interface DesignTokenConfig {
options?: {
token?: Record<string, any>;
useStyledComponentsThemeProvider?: boolean;
useDesignTokenContext?: boolean;
} = {},
};
}
export const designTokenPlugin = (
userConfig: DesignTokenConfig = {},
): Plugin => ({
name: '@modern-js/plugin-design-token',

setup: () => ({
hoc({ App, config }, next) {
setup: api => ({
wrapRoot(App) {
const pluginConfig: Record<string, any> = api.useRuntimeConfigContext();
const { options } = merge(pluginConfig.designToken || {}, userConfig);
const DesignTokenAppWrapper = (props: any) => {
const {
token = {},
Expand Down Expand Up @@ -50,10 +56,7 @@ export const designTokenPlugin = (
}
};

return next({
App: DesignTokenAppWrapper,
config,
});
return DesignTokenAppWrapper;
},
}),
});
Expand Down
1 change: 1 addition & 0 deletions packages/runtime/plugin-garfish/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@
},
"dependencies": {
"@modern-js/utils": "workspace:*",
"@modern-js/runtime-utils": "workspace:*",
"@modern-js/plugin": "workspace:*",
"@types/debug": "4.1.7",
"@types/react-loadable": "^5.5.6",
Expand Down
21 changes: 10 additions & 11 deletions packages/runtime/plugin-garfish/src/runtime/plugin.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import GarfishInstance from 'garfish';
import React from 'react';
import type { Plugin } from '@modern-js/runtime';
import { merge } from '@modern-js/runtime-utils/merge';
import { logger } from '../util';
import { GarfishProvider } from './utils/Context';
import setExternal from './utils/setExternal';
Expand Down Expand Up @@ -50,16 +51,17 @@ async function initOptions(manifest: Manifest = {}, options: Options) {
}

// export default garfishPlugin;
export const garfishPlugin = (config: Config): Plugin => ({
export const garfishPlugin = (userConfig: Config = {}): Plugin => ({
name: '@modern-js/garfish-plugin',
setup: () => {
setup: api => {
setExternal();

const { manifest, ...options } = config;
logger('createPlugin', config);
const promise = initOptions(manifest, options);
return {
hoc({ App, config }, next) {
wrapRoot(App) {
const pluginConfig: Record<string, any> = api.useRuntimeConfigContext();
const config = merge(pluginConfig.garfish || {}, userConfig);
const { manifest, ...options } = config;
logger('createPlugin', config);
const promise = initOptions(manifest, options);
class GetMicroFrontendApp extends React.Component {
state: {
MApp: React.FC<MicroComponentProps>;
Expand Down Expand Up @@ -120,10 +122,7 @@ export const garfishPlugin = (config: Config): Plugin => ({
}
}

return next({
App: GetMicroFrontendApp,
config,
});
return GetMicroFrontendApp;
},
};
},
Expand Down
6 changes: 3 additions & 3 deletions packages/runtime/plugin-garfish/src/runtime/provider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export function createProvider(
props: any;
appName?: string;
}) {
const ModernRoot = createRoot(null, { router: { basename } });
const ModernRoot = createRoot(null);

if (customBootstrap) {
root = await customBootstrap(ModernRoot, () =>
Expand Down Expand Up @@ -60,14 +60,14 @@ export function createProvider(
},
// 兼容旧版本
SubModuleComponent: (props: any) => {
const ModernRoot = createRoot(null, { router: { basename } });
const ModernRoot = createRoot(null);
return createPortal(
<ModernRoot basename={basename} {...props} />,
dom.querySelector(`#${id || 'root'}`) || dom,
);
},
jupiter_submodule_app_key: (props: any) => {
const ModernRoot = createRoot(null, { router: { basename } });
const ModernRoot = createRoot(null);

return createPortal(
<ModernRoot basename={basename} {...props} />,
Expand Down
99 changes: 49 additions & 50 deletions packages/runtime/plugin-router-v5/src/runtime/plugin.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import { RuntimeReactContext, isBrowser } from '@meta/runtime';
import type { Plugin } from '@modern-js/runtime';
import { parsedJSONFromElement } from '@modern-js/runtime-utils/parsed';
import { getGlobalLayoutApp, getGlobalRoutes } from '@meta/runtime/context';
import { merge } from '@modern-js/runtime-utils/merge';
import { renderRoutes, getLocation, urlJoin } from './utils';
import { modifyRoutesHook } from './hooks';

Expand Down Expand Up @@ -70,39 +71,17 @@ export type RouterConfig = Partial<HistoryConfig> & {
serverBase?: string[];
};

export const routerPlugin = ({
serverBase = [],
history: customHistory,
supportHtml5History = true,
routesConfig,
createRoutes,
historyOptions = {},
}: RouterConfig): Plugin => {
const finalRouteConfig = {
routes: getGlobalRoutes() as SingleRouteConfig[],
globalApp: getGlobalLayoutApp(),
...routesConfig,
};
const originRoutes = finalRouteConfig?.routes;
const isBrow = isBrowser();

const select = (pathname: string) =>
serverBase.find(baseUrl => pathname.search(baseUrl) === 0) || '/';

let routes: SingleRouteConfig[] = [];

if (isBrow) {
window._SERVER_DATA = parsedJSONFromElement('__MODERN_SERVER_DATA__');
}
let routes: SingleRouteConfig[] = [];

export const routerPlugin = (userConfig: RouterConfig = {}): Plugin => {
return {
name: '@modern-js/plugin-router',
registerHook: {
modifyRoutes: modifyRoutesHook,
},
setup: api => {
return {
init({ context }, next) {
beforeRender(context) {
context.router = {
useRouteMatch,
useLocation,
Expand All @@ -114,28 +93,52 @@ export const routerPlugin = ({
return routes;
},
});

return next({ context });
},
hoc: ({ App, config }, next) => {
wrapRoot: App => {
const pluginConfig: Record<string, any> =
api.useRuntimeConfigContext();
const {
serverBase = [],
history: customHistory,
supportHtml5History = true,
routesConfig,
createRoutes,
historyOptions = {},
} = merge(pluginConfig.router || {}, userConfig) as RouterConfig;
const finalRouteConfig = {
routes: getGlobalRoutes() as SingleRouteConfig[],
globalApp: getGlobalLayoutApp(),
...routesConfig,
};
const originRoutes = finalRouteConfig?.routes;
const isBrow = isBrowser();

const select = (pathname: string) =>
serverBase.find(baseUrl => pathname.search(baseUrl) === 0) || '/';
if (isBrow) {
window._SERVER_DATA = parsedJSONFromElement(
'__MODERN_SERVER_DATA__',
);
}
const getRouteApp = () => {
if (isBrow) {
const baseUrl = (
config.router?.basename ||
window._SERVER_DATA?.router.baseUrl ||
select(location.pathname)
).replace(/^\/*/, '/');
const basename =
baseUrl === '/'
? urlJoin(baseUrl, historyOptions.basename as string)
: baseUrl;
historyOptions.basename = basename;
const history =
customHistory ||
(supportHtml5History
? createBrowserHistory(historyOptions)
: createHashHistory(historyOptions));
return (props: any) => {
const runtimeContext = useContext(RuntimeReactContext);
const baseUrl = (
runtimeContext._internalRouterBaseName ||
window._SERVER_DATA?.router.baseUrl ||
select(location.pathname)
).replace(/^\/*/, '/');
const basename =
baseUrl === '/'
? urlJoin(baseUrl, historyOptions.basename as string)
: baseUrl;
historyOptions.basename = basename;
const history =
customHistory ||
(supportHtml5History
? createBrowserHistory(historyOptions)
: createHashHistory(historyOptions));
const runner = (api as any).useHookRunners();
routes = runner.modifyRoutes(originRoutes);
finalRouteConfig && (finalRouteConfig.routes = routes);
Expand Down Expand Up @@ -163,7 +166,8 @@ export const routerPlugin = ({
const routerContext = ssrContext?.redirection || {};
const request = ssrContext?.request;
const baseUrl = (
config.router?.basename || (request?.baseUrl as string)
runtimeContext._internalRouterBaseName ||
(request?.baseUrl as string)
)?.replace(/^\/*/, '/');

const basename =
Expand Down Expand Up @@ -191,12 +195,7 @@ export const routerPlugin = ({
};
};

const RouteApp = getRouteApp();

return next({
App: RouteApp,
config,
});
return getRouteApp();
},
};
},
Expand Down
10 changes: 5 additions & 5 deletions packages/runtime/plugin-router-v5/tests/router.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ describe('@modern-js/plugin-router-v5', () => {
runtime,
plugins: [
runtime.createPlugin(() => ({
hoc: ({ App: App1, config }, next) => next({ App: App1, config }),
wrapRoot: App1 => App1,
})),
createRouterPlugin({}),
],
Expand All @@ -38,7 +38,7 @@ describe('@modern-js/plugin-router-v5', () => {
runtime,
plugins: [
runtime.createPlugin(() => ({
hoc: ({ App: App1, config }, next) => next({ App: App1, config }),
wrapRoot: App1 => App1,
})),
createRouterPlugin({
routesConfig: {
Expand Down Expand Up @@ -83,7 +83,7 @@ describe('@modern-js/plugin-router-v5', () => {
runtime,
plugins: [
runtime.createPlugin(() => ({
hoc: ({ App: App1, config }, next) => next({ App: App1, config }),
wrapRoot: App1 => App1,
})),
createRouterPlugin({
routesConfig: {
Expand Down Expand Up @@ -128,7 +128,7 @@ describe('@modern-js/plugin-router-v5', () => {
runtime,
plugins: [
runtime.createPlugin(() => ({
hoc: ({ App: App1, config }, next) => next({ App: App1, config }),
wrapRoot: App1 => App1,
})),
createRouterPlugin({
routesConfig: {
Expand Down Expand Up @@ -175,7 +175,7 @@ describe('@modern-js/plugin-router-v5', () => {
runtime,
plugins: [
runtime.createPlugin(() => ({
hoc: ({ App: App1, config }, next) => next({ App: App1, config }),
wrapRoot: App1 => App1,
modifyRoutes(routes: RouteProps[]) {
return modifyFn?.(routes);
},
Expand Down
19 changes: 8 additions & 11 deletions packages/runtime/plugin-runtime/src/core/browser/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -60,16 +60,11 @@ export async function render(
) {
const runner = getGlobalRunner();
const context: RuntimeContext = getInitialContext(runner);
const runInit = (_context: RuntimeContext) =>
runner.init(
{ context: _context },
{
onLast: ({ context: context1 }) => {
const init = getGlobalAppInit();
return init?.(context1);
},
},
) as any;
const runBeforeRender = async (context: RuntimeContext) => {
await runner.beforeRender(context);
const init = getGlobalAppInit();
return init?.(context);
};

if (isClientArgs(id)) {
const ssrData = getSSRData();
Expand All @@ -93,11 +88,13 @@ export async function render(
loaderManager: createLoaderManager(initialLoadersState, {
skipStatic: true,
}),
// garfish plugin params
_internalRouterBaseName: App.props.basename,
...(ssrData ? { ssrContext: ssrData?.context } : {}),
});

context.initialData = ssrData?.data?.initialData;
const initialData = await runInit(context);
const initialData = await runBeforeRender(context);
if (initialData) {
context.initialData = initialData;
}
Expand Down
Loading

0 comments on commit dc736ef

Please sign in to comment.