added simple watch mode
Summary: Added a watch mode to the bundle command of flipper plugins. This makes it easy to test develop plugins locally, even when you are using a production build of flipper, which lowers the barrier of developing / fixing plugins. opted for `fs.watch` over watchman to avoid some overengineering: 1. pkg / pkg-lib don't have the watchman utilities that would be needed for this. I wasn't sure if I could move those over from `static` without breaking the bootstrapping process 2. watchman is often a nuisance on non FB machines that aren't set up for it. fs.watch in contrast doesn't have any further dependencies or setup requirements, and is much more likely to work ootb. 3. since we watch only the `src` folder we don't really need the watchman optimizations. (so for a package.json change people would have to restart, but I don't think that is much of a problem). Reviewed By: jknoxville Differential Revision: D21523814 fbshipit-source-id: b1de72b7d01c6fc50cb8ce5709f54f8019eb89e4
This commit is contained in:
committed by
Facebook GitHub Bot
parent
1e309abe4f
commit
080085e788
@@ -7,7 +7,7 @@
|
||||
* @format
|
||||
*/
|
||||
|
||||
import {Command} from '@oclif/command';
|
||||
import {Command, flags} from '@oclif/command';
|
||||
import {args} from '@oclif/parser';
|
||||
import fs from 'fs-extra';
|
||||
import path from 'path';
|
||||
@@ -28,8 +28,12 @@ export default class Bundle extends Command {
|
||||
},
|
||||
];
|
||||
|
||||
public static flags = {
|
||||
watch: flags.boolean(),
|
||||
};
|
||||
|
||||
public async run() {
|
||||
const {args} = this.parse(Bundle);
|
||||
const {args, flags} = this.parse(Bundle);
|
||||
const inputDirectory: string = path.resolve(process.cwd(), args.directory);
|
||||
const stat = await fs.lstat(inputDirectory);
|
||||
if (!stat.isDirectory()) {
|
||||
@@ -44,6 +48,53 @@ export default class Bundle extends Command {
|
||||
const plugin = await getPluginDetails(inputDirectory);
|
||||
const out = path.resolve(inputDirectory, plugin.main);
|
||||
await fs.ensureDir(path.dirname(out));
|
||||
await runBuild(inputDirectory, plugin.source, out);
|
||||
|
||||
const success = await runBuildOnce(inputDirectory, plugin.source, out);
|
||||
if (!flags.watch) {
|
||||
process.exit(success ? 0 : 1);
|
||||
} else {
|
||||
enterWatchMode(inputDirectory, plugin.source, out);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function runBuildOnce(
|
||||
inputDirectory: string,
|
||||
source: string,
|
||||
out: string,
|
||||
) {
|
||||
try {
|
||||
await runBuild(inputDirectory, source, out);
|
||||
console.log('✅ Build succeeded');
|
||||
return true;
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
console.error('🥵 Build failed');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function enterWatchMode(inputDirectory: string, source: string, out: string) {
|
||||
console.log(`⏳ Waiting for changes...`);
|
||||
let isBuilding = false;
|
||||
let pendingChanges = false;
|
||||
fs.watch(
|
||||
path.join(inputDirectory, 'src'),
|
||||
{
|
||||
recursive: true,
|
||||
},
|
||||
async () => {
|
||||
pendingChanges = true;
|
||||
if (isBuilding) {
|
||||
return; // prevent kicking of a second build
|
||||
}
|
||||
isBuilding = true;
|
||||
while (pendingChanges) {
|
||||
pendingChanges = false;
|
||||
await runBuildOnce(inputDirectory, source, out);
|
||||
}
|
||||
isBuilding = false;
|
||||
console.log(`⏳ Waiting for changes...`);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
@@ -14,7 +14,8 @@
|
||||
"scripts": {
|
||||
"lint": "flipper-pkg lint",
|
||||
"prepack": "flipper-pkg lint && flipper-pkg bundle",
|
||||
"build": "flipper-pkg bundle"
|
||||
"build": "flipper-pkg bundle",
|
||||
"watch": "flipper-pkg bundle --watch"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"flipper": "latest"
|
||||
|
||||
Reference in New Issue
Block a user