serve method

Future<void> serve({
  1. required bool enableHotReload,
  2. void onReady()?,
})

Implementation

Future<void> serve({
  required bool enableHotReload,
  void Function()? onReady,
}) async {
  var isHotReloadingEnabled = false;
  clearConsole();
  logger.detail('Starting server');

  var hasStartedServer = false;

  final process = _serverProcess = await io.Process.start(
    'dart',
    [
      if (enableHotReload) ...[
        '--enable-vm-service=$dartVmServicePort',
        '--enable-asserts',
      ],
      if (dartDefine.isNotEmpty) ...[
        for (final entry in dartDefine.entries) '-D$entry',
      ],
      serverFile,
    ],
    runInShell: true,
  );

  // On Windows listen for CTRL-C and use taskkill to kill
  // the spawned process along with any child processes.
  // https://github.com/dart-lang/sdk/issues/22470
  if (io.Platform.isWindows) {
    io.ProcessSignal.sigint.watch().listen((_) {
      // Do not await on sigint
      _killServerProcess().ignore();
      stop();
    });
  }

  process.stderr.listen((err) async {
    if (_isReloading) {
      return;
    }

    final message = utf8.decode(err).trim();
    if (message.isEmpty) return;

    if (message.contains(HotReload.nonRevaliReload)) {
      if (_errorInGeneration) {
        logger.err('Failed to reload');
        return;
      }

      clearConsole();
      printVmServiceUri();
      printParsedRoutes(null);
      return;
    }

    _progress?.fail('Failed to start server');

    final isDartVMServiceAlreadyInUseError =
        _dartVmServiceAlreadyInUseErrorRegex.hasMatch(message);
    final isSDKWarning = _warningRegex.hasMatch(message);

    if (isDartVMServiceAlreadyInUseError) {
      logger.err(
        '$message\n'
        'Try specifying a different port using the '
        '`--dart-vm-service-port` argument',
      );
      _progress?.fail('Failed to start server');
    } else if (isSDKWarning) {
      // Do not kill the process if the error is a warning from the SDK.
      logger.warn(message);
    } else {
      logger.err(message);
    }

    if ((!isHotReloadingEnabled && !isSDKWarning) ||
        isDartVMServiceAlreadyInUseError) {
      await _killServerProcess();
      await stop(1);
      return;
    }
  });

  process.stdout.listen((out) {
    if (_errorInGeneration) {
      return;
    }

    final message = utf8.decode(out).trim();
    if (message.isEmpty) {
      return;
    }

    if (message.contains(HotReload.reloaded)) {
      logger.write('');
      return;
    }

    if (message.contains(HotReload.nonRevaliReload)) {
      clearConsole();
      printVmServiceUri();
      return;
    }

    if (message.contains(HotReload.revaliStarted) && !hasStartedServer) {
      hasStartedServer = true;
      _progress?.complete();
      onReady?.call();
      return;
    }

    if (message.contains(HotReload.hotReloadEnabled)) {
      isHotReloadingEnabled = true;
      return;
    }

    if (message.contains('Dart VM service')) {
      _vmServiceUri = message;
      logger.success(message);
    } else if (message.contains('Dart DevTools debugger')) {
      _vmServiceUri += '\n$message';
      logger.success(message);
      printInputCommands();
      logger.write('\n');
      _progress = logger.progress('Starting server');
    } else {
      logger.write('$message\n');
    }
  });

  process.exitCode.then((_) async {
    if (isCompleted) return;
    await _killServerProcess();
    await stop(1);
  }).ignore();
}