Install pre-bundled packages 2/N

Summary: A first simple version of pre-bundled plugin installation. Currently both pre-bundled and source-only plugins are supported. Pre-bundled plugins should have folder "dist" inside and package.json's "main" field should point to the entry point script there.

Reviewed By: passy

Differential Revision: D19834020

fbshipit-source-id: 7e0b495fb9666acbb22fc32ca2382339cd9dc72f
This commit is contained in:
Anton Nikolaev
2020-02-12 04:55:55 -08:00
committed by Facebook Github Bot
parent c315691b2d
commit 707759f096
3 changed files with 29 additions and 23 deletions

View File

@@ -80,7 +80,7 @@ export default (store: Store, logger: Logger) => {
};
function getBundledPlugins(): Array<PluginDefinition> {
if (!isProduction()) {
if (!isProduction() || process.env.FLIPPER_NO_EMBEDDED_PLUGINS) {
// Plugins are only bundled in production builds
return [];
}

View File

@@ -38,7 +38,7 @@ function providePluginManagerNoDependencies(): PM {
return new PM({ignoredDependencies: [/.*/]});
}
async function installPlugin(pluginDir: string) {
async function installPluginFromTempDir(pluginDir: string) {
const packageJSONPath = path.join(pluginDir, 'package.json');
const packageJSON = JSON.parse(
(await fs.readFile(packageJSONPath)).toString(),
@@ -51,27 +51,25 @@ async function installPlugin(pluginDir: string) {
const destinationDir = path.join(PLUGIN_DIR, name);
// Clean up existing destination files.
await fs.remove(destinationDir);
await fs.ensureDir(destinationDir);
const isPreBundled = await fs.pathExists(path.join(pluginDir, 'dist'));
if (!isPreBundled) {
const pluginManager = providePluginManager();
// install the plugin dependencies into node_modules
const nodeModulesDir = path.join(destinationDir, 'node_modules');
pluginManager.options.pluginsPath = nodeModulesDir;
const pluginInfo = await pluginManager.installFromPath(pluginDir);
const itselfDir = path.join(nodeModulesDir, name);
// copying plugin files into the destination folder
const pluginFiles = await fs.readdir(itselfDir);
await Promise.all(
pluginFiles.map(f =>
fs.move(path.join(itselfDir, f), path.join(destinationDir, f)),
),
);
await pluginManager.installFromPath(pluginDir);
// live-plugin-manager also installs plugin itself into the target dir, it's better remove it
await fs.remove(itselfDir);
return pluginInfo;
await fs.remove(path.join(nodeModulesDir, name));
}
// copying plugin files into the destination folder
const pluginFiles = await fs.readdir(pluginDir);
await Promise.all(
pluginFiles
.filter(f => f !== 'node_modules')
.map(f => fs.move(path.join(pluginDir, f), path.join(destinationDir, f))),
);
}
async function getPluginRootDir(dir: string) {
@@ -99,8 +97,8 @@ export async function installPluginFromNpm(name: string) {
const plugManNoDep = providePluginManagerNoDependencies();
plugManNoDep.options.pluginsPath = tmpDir;
await plugManNoDep.install(name);
const pluginDir = path.join(tmpDir, name);
return await installPlugin(pluginDir);
const pluginTempDir = path.join(tmpDir, name);
await installPluginFromTempDir(pluginTempDir);
} finally {
if (await fs.pathExists(tmpDir)) {
await fs.remove(tmpDir);
@@ -118,7 +116,7 @@ export async function installPluginFromFile(packagePath: string) {
throw new Error('The package is not in tar.gz format or is empty');
}
const pluginDir = await getPluginRootDir(tmpDir);
return await installPlugin(pluginDir);
await installPluginFromTempDir(pluginDir);
} finally {
if (await fs.pathExists(tmpDir)) {
await fs.remove(tmpDir);

View File

@@ -210,9 +210,17 @@ async function compilePlugin(
pluginCache,
options,
) {
const isPreBundled = fs.existsSync(path.join(rootDir, 'dist'));
const result = Object.assign({}, packageJSON, {rootDir, name, entry});
if (isPreBundled) {
// eslint-disable-next-line no-console
console.log(`🥫 Using pre-built version of ${name}...`);
result.out = path.resolve(rootDir, result.main);
return result;
}
const fileName = `${name}@${packageJSON.version || '0.0.0'}.js`;
const out = path.join(pluginCache, fileName);
const result = Object.assign({}, packageJSON, {rootDir, name, entry, out});
result.out = out;
// check if plugin needs to be compiled
const rootDirCtime = await mostRecentlyChanged(rootDir);
if (