Remove default plugin entrypoints for hot-reloading

Summary: As we stopped bundling plugins in D39276249, we no longer need the entry points for the bundled plugins (these entry points are always going to be empty)

Reviewed By: lblasa

Differential Revision: D39307565

fbshipit-source-id: 43751fe31c8bd962677c226b27cfe52093d3f2d4
This commit is contained in:
Andrey Goncharov
2022-09-15 10:02:19 -07:00
committed by Facebook GitHub Bot
parent 94df830dfb
commit 642a3ebf81
16 changed files with 55 additions and 164 deletions

View File

@@ -13,8 +13,5 @@ react-native/ReactNativeFlipperExample
scripts/generate-changelog.js scripts/generate-changelog.js
static/index.js static/index.js
static/defaultPlugins/* static/defaultPlugins/*
app/src/defaultPlugins/index.tsx
flipper-server-core/src/defaultPlugins/index.tsx
flipper-server-companion/src/defaultPlugins/index.tsx
generated generated
flipper-server/static flipper-server/static

4
desktop/.gitignore vendored
View File

@@ -5,10 +5,6 @@ node_modules/
/static/idb-applications /static/idb-applications
/static/themes/ /static/themes/
/static/defaultPlugins/ /static/defaultPlugins/
/app/src/defaultPlugins/index.tsx
/flipper-ui-browser/src/defaultPlugins/index.tsx
/flipper-server-core/src/defaultPlugins/index.tsx
/flipper-server-companion/src/defaultPlugins/index.tsx
/coverage /coverage
.env .env
tsc-error.log tsc-error.log

View File

@@ -1,10 +0,0 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @format
*/
export default {} as any;

View File

@@ -172,7 +172,6 @@ export async function initializeElectron(
restartFlipper(update: boolean = false) { restartFlipper(update: boolean = false) {
restart(update); restart(update);
}, },
loadDefaultPlugins: getDefaultPluginsIndex,
serverConfig: flipperServerConfig, serverConfig: flipperServerConfig,
GK(gatekeeper) { GK(gatekeeper) {
return flipperServerConfig.gatekeepers[gatekeeper] ?? false; return flipperServerConfig.gatekeepers[gatekeeper] ?? false;
@@ -207,9 +206,3 @@ export async function initializeElectron(
}, },
} as RenderHost; } as RenderHost;
} }
function getDefaultPluginsIndex() {
// eslint-disable-next-line import/no-unresolved
const index = require('../defaultPlugins');
return index.default || index;
}

View File

@@ -138,7 +138,6 @@ export interface RenderHost {
shouldUseDarkColors(): boolean; shouldUseDarkColors(): boolean;
restartFlipper(update?: boolean): void; restartFlipper(update?: boolean): void;
openLink(url: string): void; openLink(url: string): void;
loadDefaultPlugins(): Record<string, any>;
GK(gatekeeper: string): boolean; GK(gatekeeper: string): boolean;
flipperServer: FlipperServer; flipperServer: FlipperServer;
serverConfig: FlipperServerConfig; serverConfig: FlipperServerConfig;

View File

@@ -25,7 +25,6 @@ import {getRenderHostInstance} from './RenderHost';
import pMap from 'p-map'; import pMap from 'p-map';
export abstract class AbstractPluginInitializer { export abstract class AbstractPluginInitializer {
protected defaultPluginsIndex: any = null;
protected gatekeepedPlugins: Array<ActivatablePluginDetails> = []; protected gatekeepedPlugins: Array<ActivatablePluginDetails> = [];
protected disabledPlugins: Array<ActivatablePluginDetails> = []; protected disabledPlugins: Array<ActivatablePluginDetails> = [];
protected failedPlugins: Array<[ActivatablePluginDetails, string]> = []; protected failedPlugins: Array<[ActivatablePluginDetails, string]> = [];
@@ -48,7 +47,6 @@ export abstract class AbstractPluginInitializer {
} }
protected async _init(): Promise<_SandyPluginDefinition[]> { protected async _init(): Promise<_SandyPluginDefinition[]> {
this.loadDefaultPluginIndex();
this.loadMarketplacePlugins(); this.loadMarketplacePlugins();
const uninstalledPluginNames = this.loadUninstalledPluginNames(); const uninstalledPluginNames = this.loadUninstalledPluginNames();
const allLocalVersions = await this.loadAllLocalVersions( const allLocalVersions = await this.loadAllLocalVersions(
@@ -65,9 +63,6 @@ export abstract class AbstractPluginInitializer {
pluginDetails: ActivatablePluginDetails, pluginDetails: ActivatablePluginDetails,
): Promise<_SandyPluginDefinition>; ): Promise<_SandyPluginDefinition>;
protected loadDefaultPluginIndex() {
this.defaultPluginsIndex = getRenderHostInstance().loadDefaultPlugins();
}
protected loadMarketplacePlugins() {} protected loadMarketplacePlugins() {}
protected loadUninstalledPluginNames(): Set<string> { protected loadUninstalledPluginNames(): Set<string> {
return new Set(); return new Set();
@@ -75,15 +70,10 @@ export abstract class AbstractPluginInitializer {
protected async loadAllLocalVersions( protected async loadAllLocalVersions(
uninstalledPluginNames: Set<string>, uninstalledPluginNames: Set<string>,
): Promise<(BundledPluginDetails | InstalledPluginDetails)[]> { ): Promise<(BundledPluginDetails | InstalledPluginDetails)[]> {
this.bundledPlugins = Object.values(this.defaultPluginsIndex).map( const allLocalVersions = [...(await getDynamicPlugins())].filter(
(defaultPluginEntry: any) => defaultPluginEntry.description, (p) => !uninstalledPluginNames.has(p.name),
); );
const allLocalVersions = [
...(await getDynamicPlugins()),
...this.bundledPlugins,
].filter((p) => !uninstalledPluginNames.has(p.name));
return allLocalVersions; return allLocalVersions;
} }
protected async filterAllLocalVersions( protected async filterAllLocalVersions(

View File

@@ -46,7 +46,6 @@ export function initializeRenderHost(
restartFlipper() { restartFlipper() {
// TODO: // TODO:
}, },
loadDefaultPlugins: () => ({}),
serverConfig: flipperServerConfig, serverConfig: flipperServerConfig,
GK(gatekeeper) { GK(gatekeeper) {
return flipperServerConfig.gatekeepers[gatekeeper] ?? false; return flipperServerConfig.gatekeepers[gatekeeper] ?? false;

View File

@@ -1,10 +0,0 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @format
*/
export default {} as any;

View File

@@ -52,7 +52,6 @@ export function initializeRenderHost(
'Flipper settings have changed, please restart flipper server for the changes to take effect', 'Flipper settings have changed, please restart flipper server for the changes to take effect',
); );
}, },
loadDefaultPlugins: getDefaultPluginsIndex,
serverConfig: flipperServerConfig, serverConfig: flipperServerConfig,
GK(gatekeeper) { GK(gatekeeper) {
return flipperServerConfig.gatekeepers[gatekeeper] ?? false; return flipperServerConfig.gatekeepers[gatekeeper] ?? false;
@@ -87,10 +86,3 @@ export function initializeRenderHost(
}, },
} as RenderHost; } as RenderHost;
} }
function getDefaultPluginsIndex() {
// @ts-ignore
// eslint-disable-next-line import/no-unresolved
const index = require('./defaultPlugins');
return index.default || index;
}

View File

@@ -42,9 +42,6 @@ const sampleInstalledPluginDetails: InstalledPluginDetails = {
isActivatable: true, isActivatable: true,
}; };
// bind to empty default plugin index so we try fetching from flipper-server every time
const requirePlugin = requirePluginInternal.bind({}, {});
beforeEach(() => { beforeEach(() => {
loadDynamicPluginsMock = getRenderHostInstance().flipperServer.exec = loadDynamicPluginsMock = getRenderHostInstance().flipperServer.exec =
jest.fn(); jest.fn();
@@ -58,7 +55,7 @@ test('dispatcher dispatches REGISTER_PLUGINS', async () => {
}); });
test('requirePluginInternal returns null for invalid requires', async () => { test('requirePluginInternal returns null for invalid requires', async () => {
const requireFn = createRequirePluginFunction(requirePlugin)([]); const requireFn = createRequirePluginFunction(requirePluginInternal)([]);
const plugin = await requireFn({ const plugin = await requireFn({
...sampleInstalledPluginDetails, ...sampleInstalledPluginDetails,
name: 'pluginID', name: 'pluginID',
@@ -72,7 +69,7 @@ test('requirePluginInternal returns null for invalid requires', async () => {
test('requirePluginInternal loads plugin', async () => { test('requirePluginInternal loads plugin', async () => {
const name = 'pluginID'; const name = 'pluginID';
const requireFn = createRequirePluginFunction(requirePlugin)([]); const requireFn = createRequirePluginFunction(requirePluginInternal)([]);
const plugin = await requireFn({ const plugin = await requireFn({
...sampleInstalledPluginDetails, ...sampleInstalledPluginDetails,
name, name,
@@ -94,7 +91,7 @@ test('requirePluginInternal loads plugin', async () => {
test('requirePluginInternal loads valid Sandy plugin', async () => { test('requirePluginInternal loads valid Sandy plugin', async () => {
const name = 'pluginID'; const name = 'pluginID';
const requireFn = createRequirePluginFunction(requirePlugin)([]); const requireFn = createRequirePluginFunction(requirePluginInternal)([]);
const plugin = (await requireFn({ const plugin = (await requireFn({
...sampleInstalledPluginDetails, ...sampleInstalledPluginDetails,
name, name,
@@ -132,7 +129,9 @@ test('requirePluginInternal loads valid Sandy plugin', async () => {
test('requirePluginInternal errors on invalid Sandy plugin', async () => { test('requirePluginInternal errors on invalid Sandy plugin', async () => {
const name = 'pluginID'; const name = 'pluginID';
const failedPlugins: any[] = []; const failedPlugins: any[] = [];
const requireFn = createRequirePluginFunction(requirePlugin)(failedPlugins); const requireFn = createRequirePluginFunction(requirePluginInternal)(
failedPlugins,
);
await requireFn({ await requireFn({
...sampleInstalledPluginDetails, ...sampleInstalledPluginDetails,
name, name,
@@ -149,7 +148,7 @@ test('requirePluginInternal errors on invalid Sandy plugin', async () => {
test('requirePluginInternal loads valid Sandy Device plugin', async () => { test('requirePluginInternal loads valid Sandy Device plugin', async () => {
const name = 'pluginID'; const name = 'pluginID';
const requireFn = createRequirePluginFunction(requirePlugin)([]); const requireFn = createRequirePluginFunction(requirePluginInternal)([]);
const plugin = (await requireFn({ const plugin = (await requireFn({
...sampleInstalledPluginDetails, ...sampleInstalledPluginDetails,
pluginType: 'device', pluginType: 'device',

View File

@@ -8,7 +8,11 @@
*/ */
import type {Store} from '../reducers/index'; import type {Store} from '../reducers/index';
import {Logger, MarketplacePluginDetails} from 'flipper-common'; import {
InstalledPluginDetails,
Logger,
MarketplacePluginDetails,
} from 'flipper-common';
import {PluginDefinition} from '../plugin'; import {PluginDefinition} from '../plugin';
import React from 'react'; import React from 'react';
import ReactDOM from 'react-dom'; import ReactDOM from 'react-dom';
@@ -83,7 +87,7 @@ class UIPluginInitializer extends AbstractPluginInitializer {
} }
public requirePluginImpl(pluginDetails: ActivatablePluginDetails) { public requirePluginImpl(pluginDetails: ActivatablePluginDetails) {
return requirePluginInternal(this.defaultPluginsIndex, pluginDetails); return requirePluginInternal(pluginDetails);
} }
protected loadMarketplacePlugins() { protected loadMarketplacePlugins() {
@@ -123,12 +127,11 @@ export const requirePlugin = (pluginDetails: ActivatablePluginDetails) =>
)(pluginDetails); )(pluginDetails);
export const requirePluginInternal = async ( export const requirePluginInternal = async (
defaultPluginsIndex: any,
pluginDetails: ActivatablePluginDetails, pluginDetails: ActivatablePluginDetails,
): Promise<PluginDefinition> => { ): Promise<PluginDefinition> => {
let plugin = pluginDetails.isBundled let plugin = await getRenderHostInstance().requirePlugin(
? defaultPluginsIndex[pluginDetails.name].source (pluginDetails as InstalledPluginDetails).entry,
: await getRenderHostInstance().requirePlugin(pluginDetails.entry); );
if (!plugin) { if (!plugin) {
throw new Error( throw new Error(
`Failed to obtain plugin source for: ${pluginDetails.name}`, `Failed to obtain plugin source for: ${pluginDetails.name}`,

View File

@@ -139,7 +139,7 @@
"lint:tsc": "tsc && tsc -p tsc-root/tsconfig.json --noemit", "lint:tsc": "tsc && tsc -p tsc-root/tsconfig.json --noemit",
"list-plugins": "./ts-node scripts/list-plugins.tsx", "list-plugins": "./ts-node scripts/list-plugins.tsx",
"open-dist": "open ../dist/mac/Flipper.app --args --launcher=false --inspect=9229", "open-dist": "open ../dist/mac/Flipper.app --args --launcher=false --inspect=9229",
"postinstall": "patch-package && yarn --cwd plugins install --mutex network:30331 && yarn tsc -b pkg-lib/tsconfig.json && ./ts-node scripts/generate-plugin-entry-points.tsx && yarn build:tsc && yarn build:themes", "postinstall": "patch-package && yarn --cwd plugins install --mutex network:30331 && yarn tsc -b pkg-lib/tsconfig.json && ./ts-node scripts/remove-plugin-entry-points.tsx && yarn build:tsc && yarn build:themes",
"prebuild": "yarn build:tsc && yarn rm-dist && yarn build:themes", "prebuild": "yarn build:tsc && yarn rm-dist && yarn build:themes",
"predev-server": "yarn build:tsc", "predev-server": "yarn build:tsc",
"preflipper-server": "yarn build:tsc", "preflipper-server": "yarn build:tsc",

View File

@@ -24,10 +24,7 @@ import {
} from 'flipper-pkg-lib'; } from 'flipper-pkg-lib';
import getAppWatchFolders from './get-app-watch-folders'; import getAppWatchFolders from './get-app-watch-folders';
import {getSourcePlugins, getPluginSourceFolders} from 'flipper-plugin-lib'; import {getSourcePlugins, getPluginSourceFolders} from 'flipper-plugin-lib';
import type { import type {InstalledPluginDetails} from 'flipper-common';
BundledPluginDetails,
InstalledPluginDetails,
} from 'flipper-common';
import { import {
appDir, appDir,
staticDir, staticDir,
@@ -41,8 +38,6 @@ import pFilter from 'p-filter';
import child from 'child_process'; import child from 'child_process';
import pMap from 'p-map'; import pMap from 'p-map';
// eslint-disable-next-line flipper/no-relative-imports-across-packages
const {version} = require('../package.json');
const dev = process.env.NODE_ENV !== 'production'; const dev = process.env.NODE_ENV !== 'production';
// For insiders builds we bundle top 5 popular device plugins, // For insiders builds we bundle top 5 popular device plugins,
@@ -90,7 +85,6 @@ export async function prepareDefaultPlugins(isInsidersBuild: boolean = false) {
dereference: true, dereference: true,
}); });
console.log('✅ Copied the provided default plugins dir.'); console.log('✅ Copied the provided default plugins dir.');
await generateDefaultPluginEntryPoints([]); // calling it here just to generate empty indexes
} else { } else {
const sourcePlugins = process.env.FLIPPER_NO_DEFAULT_PLUGINS const sourcePlugins = process.env.FLIPPER_NO_DEFAULT_PLUGINS
? [] ? []
@@ -100,9 +94,6 @@ export async function prepareDefaultPlugins(isInsidersBuild: boolean = false) {
.filter((p) => !isInsidersBuild || hardcodedPlugins.has(p.id)); .filter((p) => !isInsidersBuild || hardcodedPlugins.has(p.id));
if (process.env.FLIPPER_NO_BUNDLED_PLUGINS) { if (process.env.FLIPPER_NO_BUNDLED_PLUGINS) {
await buildDefaultPlugins(defaultPlugins); await buildDefaultPlugins(defaultPlugins);
await generateDefaultPluginEntryPoints([]); // calling it here just to generate empty indexes
} else {
await generateDefaultPluginEntryPoints(defaultPlugins);
} }
} }
console.log('✅ Prepared default plugins.'); console.log('✅ Prepared default plugins.');
@@ -123,69 +114,6 @@ export async function buildServerAddOns(dev: boolean) {
await Promise.all(serverAddOns.map((p) => runBuild(p.dir, dev))); await Promise.all(serverAddOns.map((p) => runBuild(p.dir, dev)));
console.log('✅ Built plugins with server add-ons plugins.'); console.log('✅ Built plugins with server add-ons plugins.');
} }
function getGeneratedIndex(pluginRequires: string) {
return `
/* eslint-disable */
// THIS FILE IS AUTO-GENERATED by function "generateDefaultPluginEntryPoints" in "build-utils.ts".
declare const require: any;
// This function exists to make sure that if one require fails in its module initialisation, not everything fails
function tryRequire(module: string, fn: () => any): any {
try {
return fn();
} catch (e) {
console.error(\`Could not require \${module}: \`, e)
return {};
}
}
export default {\n${pluginRequires}\n} as any
`;
}
async function generateDefaultPluginEntryPoints(
defaultPlugins: InstalledPluginDetails[],
) {
console.log(
`⚙️ Generating entry points for ${defaultPlugins.length} bundled plugins...`,
);
const bundledPlugins = defaultPlugins.map(
(p) =>
({
...p,
isBundled: true,
version: p.version === '0.0.0' ? version : p.version,
flipperSDKVersion:
p.flipperSDKVersion === '0.0.0' ? version : p.flipperSDKVersion,
dir: undefined,
entry: undefined,
serverAddOnEntry: undefined,
} as BundledPluginDetails),
);
const pluginRequires = bundledPlugins
.map(
(x) =>
` '${x.name}': tryRequire('${x.name}', () => require('${x.name}'))`,
)
.join(',\n');
const generatedIndex = getGeneratedIndex(pluginRequires);
await fs.ensureDir(path.join(appDir, 'src', 'defaultPlugins'));
await fs.writeFile(
path.join(appDir, 'src', 'defaultPlugins', 'index.tsx'),
generatedIndex,
);
await fs.ensureDir(path.join(browserUiDir, 'src', 'defaultPlugins'));
await fs.writeFile(
path.join(browserUiDir, 'src', 'defaultPlugins', 'index.tsx'),
generatedIndex,
);
console.log('✅ Generated bundled plugin entry points.');
}
async function buildDefaultPlugins(defaultPlugins: InstalledPluginDetails[]) { async function buildDefaultPlugins(defaultPlugins: InstalledPluginDetails[]) {
if (process.env.FLIPPER_NO_REBUILD_PLUGINS) { if (process.env.FLIPPER_NO_REBUILD_PLUGINS) {
console.log( console.log(

View File

@@ -1,17 +0,0 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @format
*/
/* eslint-disable flipper/no-console-error-without-context */
import {prepareDefaultPlugins} from './build-utils';
prepareDefaultPlugins().catch((err) => {
console.error(err);
process.exit(1);
});

View File

@@ -181,9 +181,6 @@ function createStubRenderHost(): RenderHost {
restartFlipper() {}, restartFlipper() {},
openLink() {}, openLink() {},
serverConfig: stubConfig, serverConfig: stubConfig,
loadDefaultPlugins() {
return {};
},
GK(gk: string) { GK(gk: string) {
return stubConfig.gatekeepers[gk] ?? false; return stubConfig.gatekeepers[gk] ?? false;
}, },

View File

@@ -0,0 +1,35 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @format
*/
/* eslint-disable flipper/no-console-error-without-context */
import fs from 'fs-extra';
import path from 'path';
import {rootDir} from './paths';
// TODO: Remove me in 2023 when everyone who is building flipper from source have legacy plugin entry points removed by this script
(async () => {
await Promise.all(
[
path.resolve(rootDir, 'app/src/defaultPlugins'),
path.resolve(rootDir, 'flipper-server-companion/src/defaultPlugins'),
path.resolve(rootDir, 'flipper-server-core/src/defaultPlugins'),
path.resolve(rootDir, 'flipper-ui-browser/src/defaultPlugins'),
].map((dir) =>
fs.rm(dir, {
recursive: true,
force: true,
}),
),
);
})().catch((err) => {
console.error(err);
process.exit(1);
});