Simplify bundled plugin setup
Summary: Stop bundling plugins into Flipper Server bundles. In later diffs, we will start building all plugins even in dev mode which removes the need to bundle them. Reviewed By: lblasa Differential Revision: D39276249 fbshipit-source-id: 091405cfcf58aa7e1bd2b382da40f8d9841ae6b1
This commit is contained in:
committed by
Facebook GitHub Bot
parent
a67a4e5d0f
commit
a888e6affa
@@ -9,7 +9,6 @@
|
|||||||
|
|
||||||
import {FlipperDoctor} from './doctor';
|
import {FlipperDoctor} from './doctor';
|
||||||
import {
|
import {
|
||||||
BundledPluginDetails,
|
|
||||||
DeviceSpec,
|
DeviceSpec,
|
||||||
DeviceType,
|
DeviceType,
|
||||||
DownloadablePluginDetails,
|
DownloadablePluginDetails,
|
||||||
@@ -254,7 +253,6 @@ export type FlipperServerCommands = {
|
|||||||
'keychain-unset': (service: string) => Promise<void>;
|
'keychain-unset': (service: string) => Promise<void>;
|
||||||
'plugins-load-dynamic-plugins': () => Promise<InstalledPluginDetails[]>;
|
'plugins-load-dynamic-plugins': () => Promise<InstalledPluginDetails[]>;
|
||||||
'plugins-load-marketplace-plugins': () => Promise<MarketplacePluginDetails[]>;
|
'plugins-load-marketplace-plugins': () => Promise<MarketplacePluginDetails[]>;
|
||||||
'plugins-get-bundled-plugins': () => Promise<BundledPluginDetails[]>;
|
|
||||||
'plugins-get-installed-plugins': () => Promise<InstalledPluginDetails[]>;
|
'plugins-get-installed-plugins': () => Promise<InstalledPluginDetails[]>;
|
||||||
'plugins-get-updatable-plugins': (
|
'plugins-get-updatable-plugins': (
|
||||||
query: string | undefined,
|
query: string | undefined,
|
||||||
|
|||||||
@@ -75,12 +75,13 @@ export abstract class AbstractPluginInitializer {
|
|||||||
protected async loadAllLocalVersions(
|
protected async loadAllLocalVersions(
|
||||||
uninstalledPluginNames: Set<string>,
|
uninstalledPluginNames: Set<string>,
|
||||||
): Promise<(BundledPluginDetails | InstalledPluginDetails)[]> {
|
): Promise<(BundledPluginDetails | InstalledPluginDetails)[]> {
|
||||||
const bundledPlugins = await getBundledPlugins();
|
this.bundledPlugins = Object.values(this.defaultPluginsIndex).map(
|
||||||
this.bundledPlugins = bundledPlugins;
|
(defaultPluginEntry: any) => defaultPluginEntry.description,
|
||||||
|
);
|
||||||
|
|
||||||
const allLocalVersions = [
|
const allLocalVersions = [
|
||||||
...bundledPlugins,
|
|
||||||
...(await getDynamicPlugins()),
|
...(await getDynamicPlugins()),
|
||||||
|
...this.bundledPlugins,
|
||||||
].filter((p) => !uninstalledPluginNames.has(p.name));
|
].filter((p) => !uninstalledPluginNames.has(p.name));
|
||||||
|
|
||||||
return allLocalVersions;
|
return allLocalVersions;
|
||||||
@@ -147,24 +148,6 @@ export function getLatestCompatibleVersionOfEachPlugin<
|
|||||||
return Array.from(latestCompatibleVersions.values());
|
return Array.from(latestCompatibleVersions.values());
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getBundledPlugins(): Promise<
|
|
||||||
Array<BundledPluginDetails>
|
|
||||||
> {
|
|
||||||
if (getRenderHostInstance().serverConfig.env.NODE_ENV === 'test') {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
// defaultPlugins that are included in the Flipper distributive.
|
|
||||||
// List of default bundled plugins is written at build time to defaultPlugins/bundled.json.
|
|
||||||
return await getRenderHostInstance().flipperServer!.exec(
|
|
||||||
'plugins-get-bundled-plugins',
|
|
||||||
);
|
|
||||||
} catch (e) {
|
|
||||||
console.error('Failed to load list of bundled plugins', e);
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function getDynamicPlugins(): Promise<InstalledPluginDetails[]> {
|
export async function getDynamicPlugins(): Promise<InstalledPluginDetails[]> {
|
||||||
try {
|
try {
|
||||||
return await getRenderHostInstance().flipperServer!.exec(
|
return await getRenderHostInstance().flipperServer!.exec(
|
||||||
|
|||||||
@@ -30,9 +30,9 @@ export class HeadlessPluginInitializer extends AbstractPluginInitializer {
|
|||||||
protected async requirePluginImpl(
|
protected async requirePluginImpl(
|
||||||
pluginDetails: ActivatablePluginDetails,
|
pluginDetails: ActivatablePluginDetails,
|
||||||
): Promise<_SandyPluginDefinition> {
|
): Promise<_SandyPluginDefinition> {
|
||||||
const plugin = pluginDetails.isBundled
|
const plugin = await getRenderHostInstance().requirePlugin(
|
||||||
? this.defaultPluginsIndex[pluginDetails.name]
|
(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}`,
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ export function initializeRenderHost(
|
|||||||
restartFlipper() {
|
restartFlipper() {
|
||||||
// TODO:
|
// TODO:
|
||||||
},
|
},
|
||||||
loadDefaultPlugins: getDefaultPluginsIndex,
|
loadDefaultPlugins: () => ({}),
|
||||||
serverConfig: flipperServerConfig,
|
serverConfig: flipperServerConfig,
|
||||||
GK(gatekeeper) {
|
GK(gatekeeper) {
|
||||||
return flipperServerConfig.gatekeepers[gatekeeper] ?? false;
|
return flipperServerConfig.gatekeepers[gatekeeper] ?? false;
|
||||||
@@ -81,8 +81,3 @@ export function initializeRenderHost(
|
|||||||
},
|
},
|
||||||
} as RenderHost;
|
} as RenderHost;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getDefaultPluginsIndex() {
|
|
||||||
// TODO: Fix me
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -435,7 +435,6 @@ export class FlipperServerImpl implements FlipperServer {
|
|||||||
this.pluginManager.loadDynamicPlugins(),
|
this.pluginManager.loadDynamicPlugins(),
|
||||||
'plugins-load-marketplace-plugins': () =>
|
'plugins-load-marketplace-plugins': () =>
|
||||||
this.pluginManager.loadMarketplacePlugins(),
|
this.pluginManager.loadMarketplacePlugins(),
|
||||||
'plugins-get-bundled-plugins': () => this.pluginManager.getBundledPlugins(),
|
|
||||||
'plugins-get-installed-plugins': () =>
|
'plugins-get-installed-plugins': () =>
|
||||||
this.pluginManager.getInstalledPlugins(),
|
this.pluginManager.getInstalledPlugins(),
|
||||||
'plugins-remove-plugins': (plugins) =>
|
'plugins-remove-plugins': (plugins) =>
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ import tmp from 'tmp';
|
|||||||
import {promisify} from 'util';
|
import {promisify} from 'util';
|
||||||
import {default as axios} from 'axios';
|
import {default as axios} from 'axios';
|
||||||
import {
|
import {
|
||||||
BundledPluginDetails,
|
|
||||||
DownloadablePluginDetails,
|
DownloadablePluginDetails,
|
||||||
ExecuteMessage,
|
ExecuteMessage,
|
||||||
FlipperServerForServerAddOn,
|
FlipperServerForServerAddOn,
|
||||||
@@ -77,28 +76,6 @@ export class PluginManager {
|
|||||||
return await fs.readFile(path, 'utf8');
|
return await fs.readFile(path, 'utf8');
|
||||||
}
|
}
|
||||||
|
|
||||||
async getBundledPlugins(): Promise<Array<BundledPluginDetails>> {
|
|
||||||
if (
|
|
||||||
process.env.NODE_ENV === 'test' ||
|
|
||||||
process.env.FLIPPER_NO_BUNDLED_PLUGINS === 'true'
|
|
||||||
) {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
// defaultPlugins that are included in the Flipper distributive.
|
|
||||||
// List of default bundled plugins is written at build time to defaultPlugins/bundled.json.
|
|
||||||
const pluginPath = getStaticPath(
|
|
||||||
path.join('defaultPlugins', 'bundled.json'),
|
|
||||||
{asarUnpacked: true},
|
|
||||||
);
|
|
||||||
let bundledPlugins: Array<BundledPluginDetails> = [];
|
|
||||||
try {
|
|
||||||
bundledPlugins = await fs.readJson(pluginPath);
|
|
||||||
} catch (e) {
|
|
||||||
console.error('Failed to load list of bundled plugins', e);
|
|
||||||
}
|
|
||||||
return bundledPlugins;
|
|
||||||
}
|
|
||||||
|
|
||||||
async loadMarketplacePlugins() {
|
async loadMarketplacePlugins() {
|
||||||
console.info('Load available plugins from marketplace');
|
console.info('Load available plugins from marketplace');
|
||||||
return loadMarketplacePlugins(this.flipperServer, '');
|
return loadMarketplacePlugins(this.flipperServer, '');
|
||||||
|
|||||||
@@ -19,7 +19,6 @@ import {InstalledPluginDetails} from 'flipper-common';
|
|||||||
import {getStaticPath} from '../utils/pathUtils';
|
import {getStaticPath} from '../utils/pathUtils';
|
||||||
|
|
||||||
// Load "dynamic" plugins, e.g. those which are either pre-installed (default), installed or loaded from sources (for development).
|
// Load "dynamic" plugins, e.g. those which are either pre-installed (default), installed or loaded from sources (for development).
|
||||||
// This opposed to "bundled" plugins which are included into Flipper bundle.
|
|
||||||
export async function loadDynamicPlugins(): Promise<InstalledPluginDetails[]> {
|
export async function loadDynamicPlugins(): Promise<InstalledPluginDetails[]> {
|
||||||
if (process.env.NODE_ENV === 'test') {
|
if (process.env.NODE_ENV === 'test') {
|
||||||
return [];
|
return [];
|
||||||
@@ -36,29 +35,14 @@ export async function loadDynamicPlugins(): Promise<InstalledPluginDetails[]> {
|
|||||||
ex,
|
ex,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
const bundledPlugins = new Set<string>(
|
|
||||||
(
|
const [installedPlugins, sourcePlugins] = await Promise.all([
|
||||||
await fs.readJson(
|
|
||||||
getStaticPath(path.join('defaultPlugins', 'bundled.json'), {
|
|
||||||
asarUnpacked: true,
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
).map((p: any) => p.name) as string[],
|
|
||||||
);
|
|
||||||
console.log(
|
|
||||||
`✅ Detected ${bundledPlugins.size} bundled plugins: ${Array.from(
|
|
||||||
bundledPlugins,
|
|
||||||
).join(', ')}.`,
|
|
||||||
);
|
|
||||||
const [installedPlugins, unfilteredSourcePlugins] = await Promise.all([
|
|
||||||
process.env.FLIPPER_NO_PLUGIN_MARKETPLACE
|
process.env.FLIPPER_NO_PLUGIN_MARKETPLACE
|
||||||
? Promise.resolve([])
|
? Promise.resolve([])
|
||||||
: getAllInstalledPluginVersions(),
|
: getAllInstalledPluginVersions(),
|
||||||
getSourcePlugins(),
|
getSourcePlugins(),
|
||||||
]);
|
]);
|
||||||
const sourcePlugins = unfilteredSourcePlugins.filter(
|
|
||||||
(p) => !bundledPlugins.has(p.name),
|
|
||||||
);
|
|
||||||
const defaultPluginsDir = getStaticPath('defaultPlugins', {
|
const defaultPluginsDir = getStaticPath('defaultPlugins', {
|
||||||
asarUnpacked: true,
|
asarUnpacked: true,
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -20,15 +20,6 @@ declare global {
|
|||||||
}
|
}
|
||||||
global.FlipperPlugin = FlipperPluginSDK;
|
global.FlipperPlugin = FlipperPluginSDK;
|
||||||
|
|
||||||
// defaultPlugins has to be required after we set FlipperPlugin.
|
|
||||||
// In server add-ons, developers might import utilities from 'flipper-plugin'
|
|
||||||
// In babel-transformer/plugin-flipper-requires flipper-plugin is replaces with global.FlipperPlugin.
|
|
||||||
// If defaultPlugins is required before we set global.FlipperPlugin,
|
|
||||||
// then flipper-plugin replaced with global.FlipperPlugin is evaluated in server add-ons before we set it - to undefined.
|
|
||||||
//
|
|
||||||
// The file is generated automatically by "prepareDefaultPlugins" in "scripts"
|
|
||||||
const defaultPlugins = require('../defaultPlugins').default;
|
|
||||||
|
|
||||||
interface ServerAddOnModule {
|
interface ServerAddOnModule {
|
||||||
default: ServerAddOnFn<any, any>;
|
default: ServerAddOnFn<any, any>;
|
||||||
}
|
}
|
||||||
@@ -39,18 +30,9 @@ export const loadServerAddOn = (
|
|||||||
): ServerAddOnModule => {
|
): ServerAddOnModule => {
|
||||||
console.debug('loadPlugin', pluginName, details);
|
console.debug('loadPlugin', pluginName, details);
|
||||||
|
|
||||||
if (details.isBundled) {
|
|
||||||
const bundledPlugin = defaultPlugins[pluginName];
|
|
||||||
assertNotNull(
|
|
||||||
bundledPlugin,
|
|
||||||
`loadPlugin (isBundled = true) -> plugin ${pluginName} not found.`,
|
|
||||||
);
|
|
||||||
return bundledPlugin;
|
|
||||||
}
|
|
||||||
|
|
||||||
assertNotNull(
|
assertNotNull(
|
||||||
details.path,
|
details.path,
|
||||||
`loadPlugin (isBundled = false) -> server add-on path is empty plugin ${pluginName}.`,
|
`loadPlugin -> server add-on path is empty plugin ${pluginName}.`,
|
||||||
);
|
);
|
||||||
|
|
||||||
// eslint-disable-next-line no-eval
|
// eslint-disable-next-line no-eval
|
||||||
|
|||||||
@@ -127,7 +127,7 @@ export const requirePluginInternal = async (
|
|||||||
pluginDetails: ActivatablePluginDetails,
|
pluginDetails: ActivatablePluginDetails,
|
||||||
): Promise<PluginDefinition> => {
|
): Promise<PluginDefinition> => {
|
||||||
let plugin = pluginDetails.isBundled
|
let plugin = pluginDetails.isBundled
|
||||||
? defaultPluginsIndex[pluginDetails.name]
|
? defaultPluginsIndex[pluginDetails.name].source
|
||||||
: await getRenderHostInstance().requirePlugin(pluginDetails.entry);
|
: await getRenderHostInstance().requirePlugin(pluginDetails.entry);
|
||||||
if (!plugin) {
|
if (!plugin) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
|
|||||||
@@ -353,7 +353,7 @@ async function buildServerRelease() {
|
|||||||
// create plugin output dir
|
// create plugin output dir
|
||||||
await fs.mkdirp(path.join(dir, 'static', 'defaultPlugins'));
|
await fs.mkdirp(path.join(dir, 'static', 'defaultPlugins'));
|
||||||
|
|
||||||
await prepareDefaultPlugins(argv.channel === 'insiders', true);
|
await prepareDefaultPlugins(argv.channel === 'insiders');
|
||||||
await buildServerAddOns(false);
|
await buildServerAddOns(false);
|
||||||
await buildHeadlessPlugins(false);
|
await buildHeadlessPlugins(false);
|
||||||
await compileServerMain(false);
|
await compileServerMain(false);
|
||||||
|
|||||||
@@ -27,6 +27,8 @@ import {
|
|||||||
genMercurialRevision,
|
genMercurialRevision,
|
||||||
prepareDefaultPlugins,
|
prepareDefaultPlugins,
|
||||||
moveSourceMaps,
|
moveSourceMaps,
|
||||||
|
buildServerAddOns,
|
||||||
|
buildHeadlessPlugins,
|
||||||
} from './build-utils';
|
} from './build-utils';
|
||||||
import isFB from './isFB';
|
import isFB from './isFB';
|
||||||
import copyPackageWithDependencies from './copy-package-with-dependencies';
|
import copyPackageWithDependencies from './copy-package-with-dependencies';
|
||||||
@@ -311,6 +313,8 @@ async function copyStaticFolder(buildFolder: string) {
|
|||||||
|
|
||||||
await compileMain();
|
await compileMain();
|
||||||
await prepareDefaultPlugins(argv.channel === 'insiders');
|
await prepareDefaultPlugins(argv.channel === 'insiders');
|
||||||
|
await buildServerAddOns(false);
|
||||||
|
await buildHeadlessPlugins(false);
|
||||||
await copyStaticFolder(dir);
|
await copyStaticFolder(dir);
|
||||||
await downloadIcons(dir);
|
await downloadIcons(dir);
|
||||||
await compileRenderer(dir);
|
await compileRenderer(dir);
|
||||||
|
|||||||
@@ -36,7 +36,6 @@ import {
|
|||||||
serverDir,
|
serverDir,
|
||||||
rootDir,
|
rootDir,
|
||||||
browserUiDir,
|
browserUiDir,
|
||||||
serverCoreDir,
|
|
||||||
} from './paths';
|
} from './paths';
|
||||||
import pFilter from 'p-filter';
|
import pFilter from 'p-filter';
|
||||||
import child from 'child_process';
|
import child from 'child_process';
|
||||||
@@ -44,7 +43,6 @@ import pMap from 'p-map';
|
|||||||
|
|
||||||
// eslint-disable-next-line flipper/no-relative-imports-across-packages
|
// eslint-disable-next-line flipper/no-relative-imports-across-packages
|
||||||
const {version} = require('../package.json');
|
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,
|
||||||
@@ -75,10 +73,7 @@ export function die(err: Error) {
|
|||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function prepareDefaultPlugins(
|
export async function prepareDefaultPlugins(isInsidersBuild: boolean = false) {
|
||||||
isInsidersBuild: boolean = false,
|
|
||||||
flipperServerBuild = false,
|
|
||||||
) {
|
|
||||||
console.log(
|
console.log(
|
||||||
`⚙️ Preparing default plugins (isInsidersBuild=${isInsidersBuild})...`,
|
`⚙️ Preparing default plugins (isInsidersBuild=${isInsidersBuild})...`,
|
||||||
);
|
);
|
||||||
@@ -107,10 +102,7 @@ export async function prepareDefaultPlugins(
|
|||||||
await buildDefaultPlugins(defaultPlugins);
|
await buildDefaultPlugins(defaultPlugins);
|
||||||
await generateDefaultPluginEntryPoints([]); // calling it here just to generate empty indexes
|
await generateDefaultPluginEntryPoints([]); // calling it here just to generate empty indexes
|
||||||
} else {
|
} else {
|
||||||
await generateDefaultPluginEntryPoints(
|
await generateDefaultPluginEntryPoints(defaultPlugins);
|
||||||
defaultPlugins,
|
|
||||||
flipperServerBuild,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
console.log('✅ Prepared default plugins.');
|
console.log('✅ Prepared default plugins.');
|
||||||
@@ -155,7 +147,6 @@ function getGeneratedIndex(pluginRequires: string) {
|
|||||||
|
|
||||||
async function generateDefaultPluginEntryPoints(
|
async function generateDefaultPluginEntryPoints(
|
||||||
defaultPlugins: InstalledPluginDetails[],
|
defaultPlugins: InstalledPluginDetails[],
|
||||||
flipperServerBuild?: boolean,
|
|
||||||
) {
|
) {
|
||||||
console.log(
|
console.log(
|
||||||
`⚙️ Generating entry points for ${defaultPlugins.length} bundled plugins...`,
|
`⚙️ Generating entry points for ${defaultPlugins.length} bundled plugins...`,
|
||||||
@@ -173,10 +164,7 @@ async function generateDefaultPluginEntryPoints(
|
|||||||
serverAddOnEntry: undefined,
|
serverAddOnEntry: undefined,
|
||||||
} as BundledPluginDetails),
|
} as BundledPluginDetails),
|
||||||
);
|
);
|
||||||
await fs.writeJSON(
|
|
||||||
path.join(defaultPluginsDir, 'bundled.json'),
|
|
||||||
bundledPlugins,
|
|
||||||
);
|
|
||||||
const pluginRequires = bundledPlugins
|
const pluginRequires = bundledPlugins
|
||||||
.map(
|
.map(
|
||||||
(x) =>
|
(x) =>
|
||||||
@@ -195,22 +183,6 @@ async function generateDefaultPluginEntryPoints(
|
|||||||
generatedIndex,
|
generatedIndex,
|
||||||
);
|
);
|
||||||
|
|
||||||
const serverAddOns = flipperServerBuild
|
|
||||||
? []
|
|
||||||
: defaultPlugins.filter(({serverAddOnSource}) => !!serverAddOnSource);
|
|
||||||
const serverAddOnRequires = serverAddOns
|
|
||||||
.map(
|
|
||||||
(x) =>
|
|
||||||
` '${x.name}': tryRequire('${x.name}', () => require('${x.name}/${x.serverAddOnSource}'))`,
|
|
||||||
)
|
|
||||||
.join(',\n');
|
|
||||||
const generatedIndexServerAddOns = getGeneratedIndex(serverAddOnRequires);
|
|
||||||
await fs.ensureDir(path.join(serverCoreDir, 'src', 'defaultPlugins'));
|
|
||||||
await fs.writeFile(
|
|
||||||
path.join(serverCoreDir, 'src', 'defaultPlugins', 'index.tsx'),
|
|
||||||
generatedIndexServerAddOns,
|
|
||||||
);
|
|
||||||
|
|
||||||
console.log('✅ Generated bundled plugin entry points.');
|
console.log('✅ Generated bundled plugin entry points.');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ import {
|
|||||||
compileMain,
|
compileMain,
|
||||||
prepareDefaultPlugins,
|
prepareDefaultPlugins,
|
||||||
buildHeadlessPlugins,
|
buildHeadlessPlugins,
|
||||||
|
buildServerAddOns,
|
||||||
} from './build-utils';
|
} from './build-utils';
|
||||||
import Watchman from './watchman';
|
import Watchman from './watchman';
|
||||||
// @ts-ignore no typings for metro
|
// @ts-ignore no typings for metro
|
||||||
@@ -445,6 +446,7 @@ function checkDevServer() {
|
|||||||
await prepareDefaultPlugins(
|
await prepareDefaultPlugins(
|
||||||
process.env.FLIPPER_RELEASE_CHANNEL === 'insiders',
|
process.env.FLIPPER_RELEASE_CHANNEL === 'insiders',
|
||||||
);
|
);
|
||||||
|
await buildServerAddOns(true);
|
||||||
await buildHeadlessPlugins(true);
|
await buildHeadlessPlugins(true);
|
||||||
await ensurePluginFoldersWatchable();
|
await ensurePluginFoldersWatchable();
|
||||||
const port = await detect(DEFAULT_PORT);
|
const port = await detect(DEFAULT_PORT);
|
||||||
|
|||||||
@@ -186,10 +186,9 @@ async function startWatchChanges() {
|
|||||||
}
|
}
|
||||||
await prepareDefaultPlugins(
|
await prepareDefaultPlugins(
|
||||||
process.env.FLIPPER_RELEASE_CHANNEL === 'insiders',
|
process.env.FLIPPER_RELEASE_CHANNEL === 'insiders',
|
||||||
true,
|
|
||||||
);
|
);
|
||||||
await buildHeadlessPlugins(true);
|
|
||||||
await buildServerAddOns(true);
|
await buildServerAddOns(true);
|
||||||
|
await buildHeadlessPlugins(true);
|
||||||
|
|
||||||
await ensurePluginFoldersWatchable();
|
await ensurePluginFoldersWatchable();
|
||||||
// builds and starts
|
// builds and starts
|
||||||
|
|||||||
Reference in New Issue
Block a user