Skip to content

Commit

Permalink
fix(@schematics/angular): replace existing `BrowserModule.withServerT…
Browse files Browse the repository at this point in the history
…ransition` calls when running universal schematic

This change fixes an issue where calling the universal schematic on an application with existing `BrowserModule.withServerTransition` will cause an additional `.withServerTransition` call to be added.

With this change we now remove the previous `withServerTransition` call to avoid misconfiguration.

Closes #24563

(cherry picked from commit c8a3b30)
  • Loading branch information
alan-agius4 authored and dgp1130 committed Jan 18, 2023
1 parent bc5555c commit 0f5fb7e
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 7 deletions.
22 changes: 15 additions & 7 deletions packages/schematics/angular/universal/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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);
};
}
Expand Down
33 changes: 33 additions & 0 deletions packages/schematics/angular/universal/index_spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down

0 comments on commit 0f5fb7e

Please sign in to comment.