diff --git a/desktop/app/src/init.tsx b/desktop/app/src/init.tsx index dbd76b8e0..c9f105cb5 100644 --- a/desktop/app/src/init.tsx +++ b/desktop/app/src/init.tsx @@ -37,6 +37,7 @@ import { parseEnvironmentVariables, setLoggerInstance, Settings, + wrapRequire, } from 'flipper-common'; import constants from './fb-stubs/constants'; import {initializeElectron} from './electron/initializeElectron'; @@ -48,7 +49,9 @@ import {KeytarModule} from 'flipper-server-core/src/utils/keytar'; import {initCompanionEnv} from 'flipper-server-companion'; import ReconnectingWebSocket from 'reconnecting-websocket'; import WS from 'ws'; +import {Module} from 'module'; +Module.prototype.require = wrapRequire(Module.prototype.require); enableMapSet(); async function getKeytarModule(staticPath: string): Promise { diff --git a/desktop/flipper-common/src/plugin-external-modules.tsx b/desktop/flipper-common/src/plugin-external-modules.tsx index a337ff844..15468468c 100644 --- a/desktop/flipper-common/src/plugin-external-modules.tsx +++ b/desktop/flipper-common/src/plugin-external-modules.tsx @@ -7,7 +7,7 @@ * @format */ -// This list should match `dispatcher/plugins.tsx` and `builtInModules` in `desktop/.eslintrc.js` +// This list should match `flipper-frontend-core/src/globalObject.tsx` and `builtInModules` in `desktop/.eslintrc.js` export const pluginExternalModules = { flipper: 'Flipper', 'flipper-plugin': 'FlipperPlugin', @@ -19,6 +19,8 @@ export const pluginExternalModules = { immer: 'Immer', '@emotion/styled': 'emotion_styled', '@ant-design/icons': 'antdesign_icons', + // Used by "bloks-logger" (see its bundle's content) + 'react/jsx-runtime': 'ReactJsxRuntime', }; export const wrapRequire = any>(require: T): T => diff --git a/desktop/flipper-frontend-core/src/globalObject.tsx b/desktop/flipper-frontend-core/src/globalObject.tsx index 8489daf8f..52d0eca7d 100644 --- a/desktop/flipper-frontend-core/src/globalObject.tsx +++ b/desktop/flipper-frontend-core/src/globalObject.tsx @@ -19,6 +19,7 @@ export interface GlobalObject { antd: any; emotion_styled: any; antdesign_icons: any; + ReactJsxRuntime: any; } declare module globalThis { @@ -32,6 +33,7 @@ declare module globalThis { let antd: any; let emotion_styled: any; let antdesign_icons: any; + let ReactJsxRuntime: any; } export const setGlobalObject = (replacements: GlobalObject) => { diff --git a/desktop/flipper-server-companion/src/init.tsx b/desktop/flipper-server-companion/src/init.tsx index 7bc422548..10954758d 100644 --- a/desktop/flipper-server-companion/src/init.tsx +++ b/desktop/flipper-server-companion/src/init.tsx @@ -39,6 +39,7 @@ export const initCompanionEnv = async ( antd: {}, emotion_styled: {default: styled}, antdesign_icons: {}, + ReactJsxRuntime: {}, }); Module.prototype.require = wrapRequire(Module.prototype.require); diff --git a/desktop/flipper-ui-browser/src/initializeRenderHost.tsx b/desktop/flipper-ui-browser/src/initializeRenderHost.tsx index d70ac3a6d..fa65e8eff 100644 --- a/desktop/flipper-ui-browser/src/initializeRenderHost.tsx +++ b/desktop/flipper-ui-browser/src/initializeRenderHost.tsx @@ -7,9 +7,29 @@ * @format */ -import {FlipperServer, FlipperServerConfig, isProduction} from 'flipper-common'; +import { + FlipperServer, + FlipperServerConfig, + isProduction, + wrapRequire, +} from 'flipper-common'; import type {RenderHost} from 'flipper-ui-core'; +declare module globalThis { + let require: any; +} + +// Whenever we bundle plugins, we assume that they are going to share some modules - React, React-DOM, ant design and etc. +// It allows us to decrease the bundle size and not to create separate React roots for every plugin +// To tell a plugin that a module is going to be provided externally, we add the module to the list of externals (see https://esbuild.github.io/api/#external). +// As a result, esbuild does not bundle hte contents of the module. Instead, it wraps the module name with `require(...)`. +// `require` does not exist ion the browser environment, so we substitute it here to feed the plugin our global module. +globalThis.require = wrapRequire((module: string) => { + throw new Error( + `Dynamic require is not supported in browser envs. Tried to require: ${module}`, + ); +}); + export function initializeRenderHost( flipperServer: FlipperServer, flipperServerConfig: FlipperServerConfig, diff --git a/desktop/flipper-ui-core/src/dispatcher/plugins.tsx b/desktop/flipper-ui-core/src/dispatcher/plugins.tsx index 30e9debb8..f968bf350 100644 --- a/desktop/flipper-ui-core/src/dispatcher/plugins.tsx +++ b/desktop/flipper-ui-core/src/dispatcher/plugins.tsx @@ -12,10 +12,10 @@ import { InstalledPluginDetails, Logger, MarketplacePluginDetails, - wrapRequire, } from 'flipper-common'; import {PluginDefinition} from '../plugin'; import React from 'react'; +import * as ReactJsxRuntime from 'react/jsx-runtime'; import ReactDOM from 'react-dom'; import ReactDOMClient from 'react-dom/client'; import ReactIs from 'react-is'; @@ -101,10 +101,6 @@ class UIPluginInitializer extends AbstractPluginInitializer { } } -declare module globalThis { - let require: any; -} - let uiPluginInitializer: UIPluginInitializer; export default async (store: Store, _logger: Logger) => { setGlobalObject({ @@ -118,21 +114,8 @@ export default async (store: Store, _logger: Logger) => { antd, emotion_styled, antdesign_icons, + ReactJsxRuntime, }); - // Whenever we bundle plugins, we assume that they are going to share some modules - React, React-DOM, ant design and etc. - // It allows us to decrease the bundle size and not to create separate React roots for every plugin - // To tell a plugin that a module is going to be provided externally, we add the module to the list of externals (see https://esbuild.github.io/api/#external). - // As a result, esbuild does not bundle hte contents of the module. Instead, it wraps the module name with `require(...)`. - // `require` does not exist ion the browser environment, so we substitute it here to feed the plugin our global module. - globalThis.require = wrapRequire( - // globalThis.require might exist in the electron build - globalThis.require ?? - ((module: string) => { - throw new Error( - `Dynamic require is not supported in browser envs. Tried to require: ${module}`, - ); - }), - ); uiPluginInitializer = new UIPluginInitializer(store); await uiPluginInitializer.init();