defaultValue: getDefaultValue()

in packages/ice/src/createService.ts [210:394]


          defaultValue: getDefaultValue(),
        };
      }
      return resetConfig;
    });

    ctx.registerConfig(configType, configData);
  });
  let taskConfigs: TaskConfig<Config>[] = await ctx.setup();

  // get userConfig after setup because of userConfig maybe modified by plugins
  const { userConfig } = ctx;
  const { routes: routesConfig, server, syntaxFeatures, polyfill } = userConfig;

  const coreEnvKeys = getCoreEnvKeys();

  const routesInfo = await generateRoutesInfo(rootDir, routesConfig, routeManifest.getRoutesDefinitions());
  routeManifest.setRoutes(routesInfo.routes);

  const hasExportAppData = (await getFileExports({ rootDir, file: 'src/app' })).includes('dataLoader');
  const csr = !userConfig.ssr && !userConfig.ssg;

  const disableRouter = (userConfig?.optimization?.router && routesInfo.routesCount <= 1) ||
    userConfig?.optimization?.disableRouter;
  if (disableRouter) {
    logger.info('`optimization.router` is enabled, ice build will remove react-router and history which is unnecessary.');
    taskConfigs = mergeTaskConfig(taskConfigs, {
      alias: {
        '@ice/runtime/router': '@ice/runtime/single-router',
      },
    });
  } else {
    // Only when router is enabled, we will add router polyfills.
    addPolyfills(generatorAPI, userConfig.featurePolyfill, rootDir, command === 'start');
  }

  // Get first task config as default platform config.
  const platformTaskConfig = taskConfigs[0];

  const iceRuntimePath = '@ice/runtime';
  // Only when code splitting use the default strategy or set to `router`, the router will be lazy loaded.
  const lazy = [true, 'chunks', 'page', 'page-vendors'].includes(userConfig.codeSplitting);
  const { routeImports, routeDefinition } = getRoutesDefinition({
    manifest: routesInfo.routes,
    lazy,
  });
  const loaderExports = hasExportAppData || Boolean(routesInfo.loaders);
  const hasDataLoader = Boolean(userConfig.dataLoader) && loaderExports;
  // add render data
  generator.setRenderData({
    ...routesInfo,
    target,
    iceRuntimePath,
    hasExportAppData,
    runtimeModules,
    coreEnvKeys,
    // Stringify basename because `config` basename in task config only support type string.
    basename: JSON.stringify(platformTaskConfig.config.basename || '/'),
    memoryRouter: platformTaskConfig.config.memoryRouter,
    hydrate: !csr,
    importCoreJs: polyfill === 'entry',
    // Enable react-router for web as default.
    enableRoutes: true,
    entryCode,
    hasDocument: hasDocument(rootDir),
    dataLoader: userConfig.dataLoader,
    hasDataLoader,
    routeImports,
    routeDefinition,
    routesFile: './routes',
  });
  dataCache.set('routes', JSON.stringify(routesInfo));
  dataCache.set('hasExportAppData', hasExportAppData ? 'true' : '');

  // Render exports files if route component export dataLoader / pageConfig.
  renderExportsTemplate(
    {
      ...routesInfo,
      hasExportAppData,
    },
    generator.addRenderFile,
    {
      rootDir,
      runtimeDir: RUNTIME_TMP_DIR,
      templateDir: path.join(templateDir, 'exports'),
      dataLoader: Boolean(userConfig.dataLoader),
    },
  );

  if (platformTaskConfig.config.server?.fallbackEntry) {
    // Add fallback entry for server side rendering.
    generator.addRenderFile('core/entry.server.ts.ejs', FALLBACK_ENTRY, { hydrate: false });
  }

  if (typeof userConfig.dataLoader === 'object' && userConfig.dataLoader.fetcher) {
    const {
      packageName,
      method,
    } = userConfig.dataLoader.fetcher;

    generatorAPI.addDataLoaderImport(method ? {
      source: packageName,
      alias: {
        [method]: 'dataLoaderFetcher',
      },
      specifier: [method],
    } : {
      source: packageName,
      specifier: '',
    });
  }

  if (multipleServerEntry(userConfig, command)) {
    renderMultiEntry({
      generator,
      renderRoutes: routeManifest.getFlattenRoute(),
      routesManifest: routesInfo.routes,
      lazy,
    });
  }

  // render template before webpack compile
  const renderStart = new Date().getTime();
  generator.render();
  logger.debug('template render cost:', new Date().getTime() - renderStart);
  if (server.onDemand && command === 'start') {
    serverRunner = new ServerRunner({
      speedup: commandArgs.speedup,
      rootDir,
      task: platformTaskConfig,
      server,
      csr,
      getRoutesFile: () => routeManifest.getRoutesFile(),
    });
    addWatchEvent([
      // Files in .ice directory will update when routes changed.
      /(src|.ice)\/?[\w*-:.$]+$/,
      async (eventName: string, filePath: string) => {
        if (eventName === 'change' || eventName === 'add') {
          serverRunner.fileChanged(filePath);
        }
      }],
    );
  }
  // create serverCompiler with task config
  const serverCompiler = createServerCompiler({
    rootDir,
    task: platformTaskConfig,
    command,
    speedup: commandArgs.speedup,
    server,
    syntaxFeatures,
    getRoutesFile: () => routeManifest.getRoutesFile(),
  });
  initAppConfigCompiler(serverCompiler);
  initRouteConfigCompiler(serverCompiler);

  addWatchEvent(
    ...getWatchEvents({
      generator,
      targetDir: RUNTIME_TMP_DIR,
      templateDir: coreTemplate,
      cache: dataCache,
      routeManifest,
      lazyRoutes: lazy,
      ctx,
    }),
  );

  const appConfig: AppConfig = (await getAppConfig()).default;
  updateRuntimeEnv(appConfig, {
    disableRouter,
    // The optimization for runtime size should only be enabled in production mode.
    routesConfig: command !== 'build' || routesInfo.routesExports.length > 0,
    dataLoader: command !== 'build' || loaderExports,
  });

  return {
    run: async () => {
      const bundlerConfig = {
        taskConfigs,
        spinner: buildSpinner,
        routeManifest,
        appConfig,
        hooksAPI: {