hunk.code_window:     deleteOutputDir(workspaceRoot, options.outputPath);
     }
     // Setup bundler entry points
     const entryPoints: Record<string, string> = {
       main: mainEntryPoint,
     };
     if (polyfillsEntryPoint) {
       entryPoints['polyfills'] = polyfillsEntryPoint;
     }
  
hunk.labels: keep keep keep replace replace replace replace replace replace keep
hunk.after_edit:   // Create output directory if needed
     try {
       await fs.mkdir(outputPath, { recursive: true });
     } catch (e) {
       assertIsError(e);
       context.logger.error('Unable to create output directory: ' + e.message);
       return { success: false };
  
hunk.file_path: packages/angular_devkit/build_angular/src/builders/browser-esbuild/index.ts
hunk.type: replace
file: /**
   * @license
   * Copyright Google LLC All Rights Reserved.
   *
   * Use of this source code is governed by an MIT-style license that can be
   * found in the LICENSE file at https://angular.io/license
   */
  
  import { Architect } from '@angular-devkit/architect';
  import { getSystemPath, join, normalize, virtualFs } from '@angular-devkit/core';
  import express from 'express'; // eslint-disable-line import/no-extraneous-dependencies
  import * as http from 'http';
  import { AddressInfo } from 'net';
  import { createArchitect, host } from '../../testing/test-utils';
  
  describe('AppShell Builder', () => {
    const target = { project: 'app', target: 'app-shell' };
    let architect: Architect;
  
    beforeEach(async () => {
      await host.initialize().toPromise();
      architect = (await createArchitect(host.root())).architect;
    });
    afterEach(async () => host.restore().toPromise());
  
    const appShellRouteFiles = {
      'src/styles.css': `
        p { color: #000 }
      `,
      'src/app/app-shell/app-shell.component.html': `
        <p>
          app-shell works!
        </p>
      `,
      'src/app/app-shell/app-shell.component.ts': `
        import { Component, OnInit } from '@angular/core';
  
        @Component({
          selector: 'app-app-shell',
          templateUrl: './app-shell.component.html',
        })
        export class AppShellComponent implements OnInit {
  
          constructor() { }
  
          ngOnInit() {
          }
  
        }
      `,
      'src/app/app.module.ts': `
        import { BrowserModule } from '@angular/platform-browser';
        import { NgModule } from '@angular/core';
  
        import { AppRoutingModule } from './app-routing.module';
        import { AppComponent } from './app.component';
        import { environment } from '../environments/environment';
        import { RouterModule } from '@angular/router';
  
        @NgModule({
          declarations: [
            AppComponent
          ],
          imports: [
            BrowserModule.withServerTransition({ appId: 'serverApp' }),
            AppRoutingModule,
            RouterModule
          ],
          providers: [],
          bootstrap: [AppComponent]
        })
        export class AppModule { }
      `,
      'src/app/app.server.module.ts': `
        import { NgModule } from '@angular/core';
        import { ServerModule } from '@angular/platform-server';
  
        import { AppModule } from './app.module';
        import { AppComponent } from './app.component';
        import { Routes, RouterModule } from '@angular/router';
        import { AppShellComponent } from './app-shell/app-shell.component';
  
        const routes: Routes = [ { path: 'shell', component: AppShellComponent }];
  
        @NgModule({
          imports: [
            AppModule,
            ServerModule,
            RouterModule.forRoot(routes),
          ],
          bootstrap: [AppComponent],
          declarations: [AppShellComponent],
        })
        export class AppServerModule {}
      `,
      'src/main.ts': `
        import { enableProdMode } from '@angular/core';
        import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
  
        import { AppModule } from './app/app.module';
        import { environment } from './environments/environment';
  
        if (environment.production) {
          enableProdMode();
        }
  
        document.addEventListener('DOMContentLoaded', () => {
          platformBrowserDynamic().bootstrapModule(AppModule)
          .catch(err => console.log(err));
        });
      `,
      'src/app/app-routing.module.ts': `
        import { NgModule } from '@angular/core';
        import { Routes, RouterModule } from '@angular/router';
  
        const routes: Routes = [];
  
        @NgModule({
          imports: [RouterModule.forRoot(routes)],
          exports: [RouterModule]
        })
        export class AppRoutingModule { }
      `,
      'src/app/app.component.html': `
        <router-outlet></router-outlet>
      `,
    };
  
    it('works (basic)', async () => {
      host.replaceInFile(
        'src/app/app.module.ts',
        / {4}BrowserModule/,
        `
        BrowserModule.withServerTransition({ appId: 'some-app' })
      `,
      );
  
      const run = await architect.scheduleTarget(target);
      const output = await run.result;
      await run.stop();
  
      expect(output.success).toBe(true);
  
      const fileName = 'dist/index.html';
      const content = virtualFs.fileBufferToString(host.scopedSync().read(normalize(fileName)));
      expect(content).toMatch(/Welcome to app!/);
    });
  
    it('works with route', async () => {
      host.writeMultipleFiles(appShellRouteFiles);
      const overrides = { route: 'shell' };
  
      const run = await architect.scheduleTarget(target, overrides);
      const output = await run.result;
      await run.stop();
  
      expect(output.success).toBe(true);
      const fileName = 'dist/index.html';
      const content = virtualFs.fileBufferToString(host.scopedSync().read(normalize(fileName)));
      expect(content).toContain('app-shell works!');
    });
  
    it('works with route and service-worker', async () => {
      host.writeMultipleFiles(appShellRouteFiles);
      host.writeMultipleFiles({
        'src/ngsw-config.json': `
          {
            "index": "/index.html",
            "assetGroups": [{
              "name": "app",
              "installMode": "prefetch",
              "resources": {
                "files": [
                  "/favicon.ico",
                  "/index.html",
                  "/*.css",
                  "/*.js"
                ]
              }
            }, {
              "name": "assets",
              "installMode": "lazy",
              "updateMode": "prefetch",
              "resources": {
                "files": [
                  "/assets/**"
                ]
              }
            }]
          }
        `,
        'src/app/app.module.ts': `
          import { BrowserModule } from '@angular/platform-browser';
          import { NgModule } from '@angular/core';
  
          import { AppRoutingModule } from './app-routing.module';
          import { AppComponent } from './app.component';
          import { ServiceWorkerModule } from '@angular/service-worker';
          import { environment } from '../environments/environment';
          import { RouterModule } from '@angular/router';
  
          @NgModule({
            declarations: [
              AppComponent
            ],
            imports: [
              BrowserModule.withServerTransition({ appId: 'serverApp' }),
              AppRoutingModule,
              ServiceWorkerModule.register('/ngsw-worker.js', { enabled: environment.production }),
              RouterModule
            ],
            providers: [],
            bootstrap: [AppComponent]
          })
          export class AppModule { }
        `,
        'e2e/app.e2e-spec.ts': `
          import { browser, by, element } from 'protractor';
  
          it('should have ngsw in normal state', () => {
            browser.get('/');
            // Wait for service worker to load.
            browser.sleep(2000);
            browser.waitForAngularEnabled(false);
            browser.get('/ngsw/state');
            // Should have updated, and be in normal state.
            expect(element(by.css('pre')).getText()).not.toContain('Last update check: never');
            expect(element(by.css('pre')).getText()).toContain('Driver state: NORMAL');
          });
        `,
      });
      // This should match the browser target prod config.
      host.replaceInFile(
        'angular.json',
        '"buildOptimizer": true',
        '"buildOptimizer": true, "serviceWorker": true',
      );
  
      // We're changing the workspace file so we need to recreate the Architect instance.
      architect = (await createArchitect(host.root())).architect;
  
      const overrides = { route: 'shell' };
      const run = await architect.scheduleTarget(
        { ...target, configuration: 'production' },
        overrides,
      );
      const output = await run.result;
      await run.stop();
  
      expect(output.success).toBe(true);
  
      // Make sure the index is pre-rendering the route.
      const fileName = 'dist/index.html';
      const content = virtualFs.fileBufferToString(host.scopedSync().read(normalize(fileName)));
      expect(content).toContain('app-shell works!');
  
      // Serve the app using a simple static server.
      const app = express();
      app.use('/', express.static(getSystemPath(join(host.root(), 'dist')) + '/'));
      const server = await new Promise<http.Server>((resolve) => {
        const innerServer = app.listen(0, 'localhost', () => resolve(innerServer));
      });
      try {
        const serverPort = (server.address() as AddressInfo).port;
        // Load app in protractor, then check service worker status.
        const protractorRun = await architect.scheduleTarget(
          { project: 'app-e2e', target: 'e2e' },
          { baseUrl: `http://localhost:${serverPort}/`, devServerTarget: '' },
        );
  
        const protractorOutput = await protractorRun.result;
        await protractorRun.stop();
  
        expect(protractorOutput.success).toBe(true);
      } finally {
        // Close the express server.
        await new Promise<void>((resolve) => server.close(() => resolve()));
      }
    });
  
    it('critical CSS is inlined', async () => {
      host.writeMultipleFiles(appShellRouteFiles);
      const overrides = {
        route: 'shell',
        browserTarget: 'app:build:production,inline-critical-css',
      };
  
      const run = await architect.scheduleTarget(target, overrides);
      const output = await run.result;
      await run.stop();
  
      expect(output.success).toBe(true);
      const fileName = 'dist/index.html';
      const content = virtualFs.fileBufferToString(host.scopedSync().read(normalize(fileName)));
  
      expect(content).toContain('app-shell works!');
      expect(content).toContain('p{color:#000}');
      expect(content).toMatch(
        /<link rel="stylesheet" href="styles\.[a-z0-9]+\.css" media="print" onload="this\.media='all'">/,
      );
    });
  });
  