diff --git a/packages/cli/src/commands/app/serve.ts b/packages/cli/src/commands/app/serve.ts new file mode 100644 index 0000000000..21241c99e3 --- /dev/null +++ b/packages/cli/src/commands/app/serve.ts @@ -0,0 +1,31 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { run } from '../../helpers/run'; +import { watchDeps } from '../watch-deps'; + +export default async () => { + const args = ['start']; + + // Start dynamic watch and build of dependencies, then serve the app + await watchDeps(); + await run('react-scripts', args, { + env: { + EXTEND_ESLINT: 'true', + SKIP_PREFLIGHT_CHECK: 'true', + }, + }); +}; diff --git a/packages/cli/src/commands/watch-deps/index.ts b/packages/cli/src/commands/watch-deps/index.ts index 6ea1fae23b..e5993ae9d6 100644 --- a/packages/cli/src/commands/watch-deps/index.ts +++ b/packages/cli/src/commands/watch-deps/index.ts @@ -31,16 +31,9 @@ const PACKAGE_BLACKLIST = [ const WATCH_LOCATIONS = ['package.json', 'src', 'assets']; -/* - * The watch-deps command is meant to improve iteration speed while working in a large monorepo - * with packages that are built independently, meaning packages depends on each other's build output. - * - * The command traverses all dependencies of the current package within the monorepo, and starts - * watching for updates in all those packages. If a change is detected, we stop listening for changes, - * and instead start up watch mode for that package. Starting watch mode means running the first - * available yarn script out of "build:watch", "watch", or "build" --watch. - */ -export default async (_command: any, args: string[]) => { +// Start watching for dependency changes. +// The returned promise resolves when watchers have started for all current dependencies. +export async function watchDeps() { const localPackagePath = resolvePath('package.json'); // Rotate through different prefix colors to make it easier to differenciate between different deps @@ -66,6 +59,19 @@ export default async (_command: any, args: string[]) => { const newDeps = await getPackageDeps(localPackagePath, PACKAGE_BLACKLIST); await watcher.update(newDeps); }); +} + +/* + * The watch-deps command is meant to improve iteration speed while working in a large monorepo + * with packages that are built independently, meaning packages depends on each other's build output. + * + * The command traverses all dependencies of the current package within the monorepo, and starts + * watching for updates in all those packages. If a change is detected, we stop listening for changes, + * and instead start up watch mode for that package. Starting watch mode means running the first + * available yarn script out of "build:watch", "watch", or "build" --watch. + */ +export default async (_command: any, args: string[]) => { + await watchDeps(); if (args?.length) { await waitForExit(startChild(args)); diff --git a/packages/cli/src/index.ts b/packages/cli/src/index.ts index 487ba58e53..4797cceaf2 100644 --- a/packages/cli/src/index.ts +++ b/packages/cli/src/index.ts @@ -22,6 +22,7 @@ import watch from './commands/watch-deps'; import lintCommand from './commands/lint'; import testCommand from './commands/testCommand'; import appBuild from './commands/app/build'; +import appServe from './commands/app/serve'; import pluginBuild from './commands/plugin/build'; import pluginServe from './commands/plugin/serve'; import { exitWithError } from './helpers/errors'; @@ -36,6 +37,11 @@ const main = (argv: string[]) => { .description('Build an app for a production release') .action(actionHandler(appBuild)); + program + .command('app:serve') + .description('Serve an app for local development') + .action(actionHandler(appServe)); + program .command('create-plugin') .description('Creates a new plugin in the current repository')