Fix fb-stubs replacement for plugin bundling

Reviewed By: nikoant

Differential Revision: D39765543

fbshipit-source-id: 14cbf8a9bdf35031e636bbbde3dbc955faedb66b
This commit is contained in:
Andrey Goncharov
2022-09-23 05:50:28 -07:00
committed by Facebook GitHub Bot
parent 61a8fe09e9
commit dd7ba2d6fc
11 changed files with 71 additions and 19 deletions

View File

@@ -18,5 +18,6 @@ export * from './server/attachSocketServer';
export * from './server/startFlipperServer'; export * from './server/startFlipperServer';
export * from './server/startServer'; export * from './server/startServer';
export * from './server/utilities'; export * from './server/utilities';
export {isFBBuild} from './fb-stubs/constants';
export {WEBSOCKET_MAX_MESSAGE_SIZE} from './comms/ServerWebSocket'; export {WEBSOCKET_MAX_MESSAGE_SIZE} from './comms/ServerWebSocket';

View File

@@ -16,6 +16,7 @@ import {WebSocketServer} from 'ws';
import pFilter from 'p-filter'; import pFilter from 'p-filter';
import {homedir} from 'os'; import {homedir} from 'os';
import {InstalledPluginDetails} from 'flipper-common'; import {InstalledPluginDetails} from 'flipper-common';
import {isFBBuild} from 'flipper-server-core';
// This file is heavily inspired by scripts/start-dev-server.ts! // This file is heavily inspired by scripts/start-dev-server.ts!
// part of that is done by start-flipper-server-dev (compiling "main"), // part of that is done by start-flipper-server-dev (compiling "main"),
@@ -153,6 +154,7 @@ export async function attachDevServer(
await startWatchPlugins( await startWatchPlugins(
process.env.FLIPPER_RELEASE_CHANNEL === 'insiders', process.env.FLIPPER_RELEASE_CHANNEL === 'insiders',
isFBBuild && !process.env.FLIPPER_FORCE_PUBLIC_BUILD,
(changedPlugins: InstalledPluginDetails[]) => { (changedPlugins: InstalledPluginDetails[]) => {
socket.clients.forEach((client) => { socket.clients.forEach((client) => {
client.send( client.send(

View File

@@ -18,6 +18,7 @@ const defaultPluginsDir = path.join(__dirname, '../../static/defaultPlugins');
export async function buildDefaultPlugins( export async function buildDefaultPlugins(
defaultPlugins: InstalledPluginDetails[], defaultPlugins: InstalledPluginDetails[],
dev: boolean, dev: boolean,
intern: boolean,
) { ) {
if (process.env.FLIPPER_NO_REBUILD_PLUGINS) { if (process.env.FLIPPER_NO_REBUILD_PLUGINS) {
console.log( console.log(
@@ -36,7 +37,7 @@ export async function buildDefaultPlugins(
console.log( console.log(
`⚙️ Building plugin ${plugin.id} to include it into the default plugins list...`, `⚙️ Building plugin ${plugin.id} to include it into the default plugins list...`,
); );
await runBuild(plugin.dir, dev); await runBuild(plugin.dir, dev, intern);
} }
await fs.ensureSymlink( await fs.ensureSymlink(
plugin.dir, plugin.dir,

View File

@@ -10,7 +10,21 @@
import path from 'path'; import path from 'path';
import fs from 'fs-extra'; import fs from 'fs-extra';
import {getInstalledPluginDetails} from 'flipper-plugin-lib'; import {getInstalledPluginDetails} from 'flipper-plugin-lib';
import {build} from 'esbuild'; import {build, Plugin} from 'esbuild';
// https://github.com/evanw/esbuild/issues/1979#issuecomment-1026988439
const resolveFbStubsToFbPlugin: Plugin = {
name: 'resolve-fb-stubs-to-fb',
setup({onResolve}) {
onResolve({filter: /fb-stubs/}, (args) => {
return {
path: require.resolve(args.path.replace('fb-stubs', 'fb'), {
paths: [args.resolveDir],
}),
};
});
},
};
interface RunBuildConfig { interface RunBuildConfig {
pluginDir: string; pluginDir: string;
@@ -19,6 +33,7 @@ interface RunBuildConfig {
dev: boolean; dev: boolean;
node?: boolean; node?: boolean;
sourceMapPath?: string; sourceMapPath?: string;
intern: boolean;
} }
async function runBuild({ async function runBuild({
@@ -28,6 +43,7 @@ async function runBuild({
dev, dev,
node, node,
sourceMapPath, sourceMapPath,
intern,
}: RunBuildConfig) { }: RunBuildConfig) {
await build({ await build({
entryPoints: [path.join(pluginDir, entry)], entryPoints: [path.join(pluginDir, entry)],
@@ -52,6 +68,7 @@ async function runBuild({
], ],
sourcemap: 'external', sourcemap: 'external',
minify: !dev, minify: !dev,
plugins: intern ? [resolveFbStubsToFbPlugin] : undefined,
}); });
const sourceMapUrl = `${out}.map`; const sourceMapUrl = `${out}.map`;
@@ -73,6 +90,7 @@ type Options = {
export default async function bundlePlugin( export default async function bundlePlugin(
pluginDir: string, pluginDir: string,
dev: boolean, dev: boolean,
intern: boolean,
options?: Options, options?: Options,
) { ) {
const stat = await fs.lstat(pluginDir); const stat = await fs.lstat(pluginDir);
@@ -103,6 +121,7 @@ export default async function bundlePlugin(
out: plugin.entry, out: plugin.entry,
dev, dev,
sourceMapPath: options?.sourceMapPath, sourceMapPath: options?.sourceMapPath,
intern,
}); });
if ( if (
@@ -118,6 +137,7 @@ export default async function bundlePlugin(
dev, dev,
node: true, node: true,
sourceMapPath: options?.sourceMapPathServerAddOn, sourceMapPath: options?.sourceMapPathServerAddOn,
intern,
}); });
} }

View File

@@ -20,9 +20,9 @@ import {InstalledPluginDetails} from 'flipper-common';
import {getDefaultPlugins} from './getDefaultPlugins'; import {getDefaultPlugins} from './getDefaultPlugins';
import {buildDefaultPlugins} from './buildDefaultPlugins'; import {buildDefaultPlugins} from './buildDefaultPlugins';
async function rebuildPlugin(pluginPath: string) { async function rebuildPlugin(pluginPath: string, intern: boolean) {
try { try {
await runBuild(pluginPath, true); await runBuild(pluginPath, true, intern);
console.info(chalk.green('Rebuilt plugin'), pluginPath); console.info(chalk.green('Rebuilt plugin'), pluginPath);
} catch (e) { } catch (e) {
console.error( console.error(
@@ -36,6 +36,7 @@ async function rebuildPlugin(pluginPath: string) {
export default async function startWatchPlugins( export default async function startWatchPlugins(
isInsidersBuild: boolean, isInsidersBuild: boolean,
intern: boolean,
onChanged?: ( onChanged?: (
changedPlugins: InstalledPluginDetails[], changedPlugins: InstalledPluginDetails[],
) => void | Promise<void>, ) => void | Promise<void>,
@@ -74,7 +75,7 @@ export default async function startWatchPlugins(
} }
dirPath = path.resolve(dirPath, '..'); dirPath = path.resolve(dirPath, '..');
} }
await rebuildPlugin(dirPath); await rebuildPlugin(dirPath, intern);
return dirPath; return dirPath;
}), }),
); );
@@ -85,7 +86,7 @@ export default async function startWatchPlugins(
} catch (e) { } catch (e) {
if (e instanceof Error && e.message === 'REBUILD_ALL') { if (e instanceof Error && e.message === 'REBUILD_ALL') {
const defaultPlugins = await getDefaultPlugins(isInsidersBuild); const defaultPlugins = await getDefaultPlugins(isInsidersBuild);
await buildDefaultPlugins(defaultPlugins, true); await buildDefaultPlugins(defaultPlugins, true, intern);
onChanged?.(defaultPlugins); onChanged?.(defaultPlugins);
return; return;
} }

View File

@@ -39,23 +39,35 @@ export default class Bundle extends Command {
'Force env.NODE_ENV=production, enable minification and disable producing source maps.', 'Force env.NODE_ENV=production, enable minification and disable producing source maps.',
default: false, default: false,
}), }),
intern: flags.boolean({
description: 'Force inten build which replaces fb-stubs with fb.',
default: false,
}),
}; };
public async run() { public async run() {
const {args, flags} = this.parse(Bundle); const {args, flags} = this.parse(Bundle);
const inputDirectory: string = path.resolve(process.cwd(), args.directory); const inputDirectory: string = path.resolve(process.cwd(), args.directory);
const success = await runBuildOnce(inputDirectory, !flags.production); const success = await runBuildOnce(
inputDirectory,
!flags.production,
flags.intern,
);
if (!flags.watch) { if (!flags.watch) {
process.exit(success ? 0 : 1); process.exit(success ? 0 : 1);
} else { } else {
enterWatchMode(inputDirectory, !flags.production); enterWatchMode(inputDirectory, !flags.production, flags.intern);
} }
} }
} }
async function runBuildOnce(inputDirectory: string, dev: boolean) { async function runBuildOnce(
inputDirectory: string,
dev: boolean,
intern: boolean,
) {
try { try {
await runBuild(inputDirectory, dev); await runBuild(inputDirectory, dev, intern);
console.log('✅ Build succeeded'); console.log('✅ Build succeeded');
return true; return true;
} catch (e) { } catch (e) {
@@ -65,7 +77,7 @@ async function runBuildOnce(inputDirectory: string, dev: boolean) {
} }
} }
function enterWatchMode(inputDirectory: string, dev: boolean) { function enterWatchMode(inputDirectory: string, dev: boolean, intern: boolean) {
console.log(`⏳ Waiting for changes...`); console.log(`⏳ Waiting for changes...`);
let isBuilding = false; let isBuilding = false;
let pendingChanges = false; let pendingChanges = false;
@@ -82,7 +94,7 @@ function enterWatchMode(inputDirectory: string, dev: boolean) {
isBuilding = true; isBuilding = true;
while (pendingChanges) { while (pendingChanges) {
pendingChanges = false; pendingChanges = false;
await runBuildOnce(inputDirectory, dev); await runBuildOnce(inputDirectory, dev, intern);
} }
isBuilding = false; isBuilding = false;
console.log(`⏳ Waiting for changes...`); console.log(`⏳ Waiting for changes...`);

View File

@@ -40,6 +40,10 @@ export default class Pack extends Command {
'Force env.NODE_ENV=production, enable minification and disable producing source maps.', 'Force env.NODE_ENV=production, enable minification and disable producing source maps.',
default: false, default: false,
}), }),
intern: flags.boolean({
description: 'Force inten build which replaces fb-stubs with fb.',
default: false,
}),
}; };
public static args: args.IArg[] = [ public static args: args.IArg[] = [
@@ -115,7 +119,7 @@ export default class Pack extends Command {
cli.action.stop(); cli.action.stop();
cli.action.start(`Compiling`); cli.action.start(`Compiling`);
await runBuild(inputDirectory, parsedFlags.production); await runBuild(inputDirectory, parsedFlags.production, parsedFlags.intern);
cli.action.stop(); cli.action.stop();
cli.action.start(`Packing to ${outputFile}`); cli.action.start(`Packing to ${outputFile}`);

View File

@@ -16,6 +16,7 @@ import yargs from 'yargs';
import tmp from 'tmp'; import tmp from 'tmp';
import {execSync} from 'child_process'; import {execSync} from 'child_process';
import {promisify} from 'util'; import {promisify} from 'util';
import isFB from './isFB';
const argv = yargs const argv = yargs
.usage('yarn build-plugin [args]') .usage('yarn build-plugin [args]')
@@ -80,7 +81,7 @@ async function buildPlugin() {
const outputSourcemapServerAddOnArg = argv['output-sourcemap-server-addon']; const outputSourcemapServerAddOnArg = argv['output-sourcemap-server-addon'];
const packageJsonPath = path.join(pluginDir, 'package.json'); const packageJsonPath = path.join(pluginDir, 'package.json');
const packageJsonOverridePath = path.join(pluginDir, 'fb', 'package.json'); const packageJsonOverridePath = path.join(pluginDir, 'fb', 'package.json');
await runBuild(pluginDir, false, { await runBuild(pluginDir, false, isFB, {
sourceMapPath: outputSourcemapArg, sourceMapPath: outputSourcemapArg,
sourceMapPathServerAddOn: outputSourcemapServerAddOnArg, sourceMapPathServerAddOn: outputSourcemapServerAddOnArg,
}); });

View File

@@ -36,6 +36,7 @@ import {
} from './paths'; } from './paths';
import pFilter from 'p-filter'; import pFilter from 'p-filter';
import child from 'child_process'; import child from 'child_process';
import isFB from './isFB';
const dev = process.env.NODE_ENV !== 'production'; const dev = process.env.NODE_ENV !== 'production';
@@ -63,7 +64,11 @@ export async function prepareDefaultPlugins(isInsidersBuild: boolean = false) {
console.log('✅ Copied the provided default plugins dir.'); console.log('✅ Copied the provided default plugins dir.');
} else { } else {
const defaultPlugins = await getDefaultPlugins(isInsidersBuild); const defaultPlugins = await getDefaultPlugins(isInsidersBuild);
await buildDefaultPlugins(defaultPlugins, dev); await buildDefaultPlugins(
defaultPlugins,
dev,
isFB && !process.env.FLIPPER_FORCE_PUBLIC_BUILD,
);
} }
console.log('✅ Prepared default plugins.'); console.log('✅ Prepared default plugins.');
} }

View File

@@ -13,6 +13,7 @@ import {pluginsDir} from './paths';
import path from 'path'; import path from 'path';
import {runBuild} from 'flipper-pkg-lib'; import {runBuild} from 'flipper-pkg-lib';
import {getWorkspaces} from './workspaces'; import {getWorkspaces} from './workspaces';
import isFB from './isFB';
async function bundleAllPlugins() { async function bundleAllPlugins() {
const plugins = await getWorkspaces().then((workspaces) => const plugins = await getWorkspaces().then((workspaces) =>
@@ -24,7 +25,7 @@ async function bundleAllPlugins() {
console.log(`Bundling "${relativeDir}"`); console.log(`Bundling "${relativeDir}"`);
console.time(`Finished bundling "${relativeDir}"`); console.time(`Finished bundling "${relativeDir}"`);
try { try {
await runBuild(plugin.dir, false); await runBuild(plugin.dir, false, isFB);
} catch (err) { } catch (err) {
console.log(`Failed to bundle "${relativeDir}": ${err.message}`); console.log(`Failed to bundle "${relativeDir}": ${err.message}`);
errors.set(relativeDir, err); errors.set(relativeDir, err);

View File

@@ -413,9 +413,13 @@ function checkDevServer() {
await startMetroServer(app, server); await startMetroServer(app, server);
outputScreen(socket); outputScreen(socket);
await compileMain(); await compileMain();
await startWatchPlugins(isInsidersBuild, (changedPlugins) => { await startWatchPlugins(
socket.emit('plugins-source-updated', changedPlugins); isInsidersBuild,
}); isFB && !process.env.FLIPPER_FORCE_PUBLIC_BUILD,
(changedPlugins) => {
socket.emit('plugins-source-updated', changedPlugins);
},
);
if (dotenv && dotenv.parsed) { if (dotenv && dotenv.parsed) {
console.log('✅ Loaded env vars from .env file: ', dotenv.parsed); console.log('✅ Loaded env vars from .env file: ', dotenv.parsed);
} }