xref: /expo/packages/@expo/cli/src/run/startBundler.ts (revision deeca5da)
1import { getConfig } from '@expo/config';
2import chalk from 'chalk';
3
4import * as Log from '../log';
5import { startInterfaceAsync } from '../start/interface/startInterface';
6import { DevServerManager } from '../start/server/DevServerManager';
7import { isInteractive } from '../utils/interactive';
8
9export async function startBundlerAsync(
10  projectRoot: string,
11  {
12    port,
13    headless,
14    scheme,
15  }: {
16    port: number;
17    headless?: boolean;
18    scheme?: string;
19  }
20): Promise<DevServerManager> {
21  const options = {
22    port,
23    headless,
24    devClient: true,
25
26    location: {
27      scheme,
28    },
29  };
30
31  const devServerManager = new DevServerManager(projectRoot, options);
32
33  await devServerManager.startAsync([
34    {
35      // TODO: Allow swapping this value for another bundler.
36      type: 'metro',
37      options,
38    },
39  ]);
40
41  // Present the Terminal UI.
42  if (!headless && isInteractive()) {
43    // Only read the config if we are going to use the results.
44    const { exp } = getConfig(projectRoot, {
45      // We don't need very many fields here, just use the lightest possible read.
46      skipSDKVersionRequirement: true,
47      skipPlugins: true,
48    });
49    await startInterfaceAsync(devServerManager, {
50      platforms: exp.platforms ?? [],
51    });
52  } else {
53    // Display the server location in CI...
54    const url = devServerManager.getDefaultDevServer()?.getDevServerUrl();
55    if (url) {
56      Log.log(chalk`Waiting on {underline ${url}}`);
57    }
58  }
59
60  if (!options.headless) {
61    await devServerManager.watchEnvironmentVariables();
62    await devServerManager.bootstrapTypeScriptAsync();
63  }
64
65  return devServerManager;
66}
67