Search code examples
angularoptimizationbuildangular-cliangular-standalone-components

Angular two way binding broken in production build - TypeError "st is not a function"


I have a project that is using Angular 17, application builder, standalone components, with NgModule imports. In Development, it builds and runs just fine, but when building in Production, the application crashes with the following error:

core.mjs:6373 ERROR TypeError: st is not a function
    at HTMLElement.addEventListener (zone.js:1907:21)
    at n.addEventListener (platform-browser.mjs:785:15)
    at n.addEventListener (platform-browser.mjs:212:21)
    at Dd.listen (platform-browser.mjs:665:30)
    at sf.listen (browser.mjs:4309:26)
    at G0 (core.mjs:24973:34)
    at _t (core.mjs:26820:3)
    at Kle (createAccount.component.html:31:53)
    at o0 (core.mjs:10988:5)
    at LA (core.mjs:12150:7)

createAccount.component.html:31:53 looks like this, with line 31 being [(value)]="model.Username"

<my-textbox [label]="ResourceKey.Portals_EditProfile_Username"
    [(value)]="model.Username"
    [readonly]="model.IsSSO" 
    [required]="true">
</my-textbox>

If I comment this textbox out, then the same error on the next textbox's [(value)] line.

From what I can tell poking around in the stack, st seems to be mapped to prepareEventNames in zone.js:

if (!symbolEventNames) {
    prepareEventNames(eventName, eventNameToString);
    symbolEventNames = zoneSymbolEventNames[eventName];
}

attempting to step into prepareEventNames() results in the error.

So what does this mean? Did the optimized build shake one too many things out? How do I fix/find the issue?

Environment:

Angular CLI: 17.3.8
Node: 20.16.0
Package Manager: npm 10.8.1
OS: win32 x64

Angular: 17.3.12
... animations, common, compiler, compiler-cli, core, forms
... localize, platform-browser, platform-browser-dynamic, router

Package                         Version
---------------------------------------------------------
@angular-devkit/architect       0.1703.8
@angular-devkit/build-angular   17.3.8
@angular-devkit/core            17.3.8
@angular-devkit/schematics      17.3.8
@angular/cdk                    17.3.10
@angular/cli                    17.3.8
@angular/flex-layout            15.0.0-beta.42
@angular/material               17.3.10
@schematics/angular             17.3.8
ng-packagr                      17.3.0
rxjs                            7.8.1
typescript                      5.3.3
zone.js                         0.14.4

Application configuration:

export const appConfig: ApplicationConfig = {
    providers: [
        { provide: LocalizationSource, useClass: MinIDLocalizationSource },
        provideRouter(routes),
        importProvidersFrom(BrowserAnimationsModule),
        provideHttpClient(
            withInterceptors([
                DateInterceptorFn
            ])
        )
    ]
};

bootstrapApplication(AppComponent, appConfig)
  .catch((err) => console.error(err));

Update: If I build with optimization turned off, the application runs fine. ng build {project} --configuration=production --optimization=false


Solution

  • Searching for any relevant info regarding this issue, I ran into this one: Enabling optimization breaks Angular site for no apparent reason

    Lo and behold, that was it. Now my production build works fine.

    To recap the issue and the fix:

    • It seemed production builds were broken. Functions within zone.js being undefined or set to scalar values, resulting in TypeErrors and a broken application
    • The SO post referenced above talks about different javascript files clobbering eachother's functions and variables
    • The fix was to add type="module" to the script references. <script src="main.js"></script> to <script src="main.js" type="module"></script>

    Definitely one to remember for the future