diff --git a/packages/schematics/angular/universal/index.ts b/packages/schematics/angular/universal/index.ts index a8273e21054f..fdef0f4a7275 100644 --- a/packages/schematics/angular/universal/index.ts +++ b/packages/schematics/angular/universal/index.ts @@ -23,7 +23,6 @@ import { import { NodePackageInstallTask } from '@angular-devkit/schematics/tasks'; import * as ts from '../third_party/github.com/Microsoft/TypeScript/lib/typescript'; import { findNode, getDecoratorMetadata } from '../utility/ast-utils'; -import { InsertChange } from '../utility/change'; import { NodeDependencyType, addPackageJsonDependency, @@ -202,13 +201,22 @@ function addServerTransition( ); const browserModuleImport = findBrowserModuleImport(host, bootstrapModulePath); - const appId = options.appId; - const transitionCall = `.withServerTransition({ appId: '${appId}' })`; - const position = browserModuleImport.pos + browserModuleImport.getFullText().length; - const transitionCallChange = new InsertChange(bootstrapModulePath, position, transitionCall); - const transitionCallRecorder = host.beginUpdate(bootstrapModulePath); - transitionCallRecorder.insertLeft(transitionCallChange.pos, transitionCallChange.toAdd); + const position = browserModuleImport.pos + browserModuleImport.getFullWidth(); + const browserModuleFullImport = browserModuleImport.parent; + + if (browserModuleFullImport.getText() === 'BrowserModule.withServerTransition') { + // Remove any existing withServerTransition as otherwise we might have incorrect configuration. + transitionCallRecorder.remove( + position, + browserModuleFullImport.parent.getFullWidth() - browserModuleImport.getFullWidth(), + ); + } + + transitionCallRecorder.insertLeft( + position, + `.withServerTransition({ appId: '${options.appId}' })`, + ); host.commitUpdate(transitionCallRecorder); }; } diff --git a/packages/schematics/angular/universal/index_spec.ts b/packages/schematics/angular/universal/index_spec.ts index df207cfcb607..ff84b3bb584e 100644 --- a/packages/schematics/angular/universal/index_spec.ts +++ b/packages/schematics/angular/universal/index_spec.ts @@ -158,6 +158,39 @@ describe('Universal Schematic', () => { expect(contents).toMatch(/BrowserModule\.withServerTransition\({ appId: 'serverApp' }\)/); }); + it('should replace existing `withServerTransition` in BrowserModule import', async () => { + const filePath = '/projects/bar/src/app/app.module.ts'; + appTree.overwrite( + filePath, + ` + import { NgModule } from '@angular/core'; + import { BrowserModule } from '@angular/platform-browser'; + + import { AppRoutingModule } from './app-routing.module'; + import { AppComponent } from './app.component'; + + @NgModule({ + declarations: [ + AppComponent + ], + imports: [ + BrowserModule.withServerTransition({ appId: 'foo' }), + AppRoutingModule + ], + providers: [], + bootstrap: [AppComponent] + }) + export class AppModule { } + `, + ); + const tree = await schematicRunner.runSchematic('universal', defaultOptions, appTree); + const contents = tree.readContent(filePath); + console.log(contents); + + expect(contents).toContain(`BrowserModule.withServerTransition({ appId: 'serverApp' }),`); + expect(contents).not.toContain(`withServerTransition({ appId: 'foo' })`); + }); + it('should wrap the bootstrap call in a DOMContentLoaded event handler', async () => { const tree = await schematicRunner.runSchematic('universal', defaultOptions, appTree); const filePath = '/projects/bar/src/main.ts';