1

I'm working on a big monolithic AngularJS application and want to add an Angular (as in Angular 4) component. Unfortunately, the AngularJS project's build system is largely fixed and the only thing I can do is adjust the project's index.html and, for instance, add additional <script> tags to load my Angular code. My question now is how I access AngularJS' global angular variable in my Angular project's TypeScript files to downgrade my Angular component and make it accessible to AngularJS, without adding the whole AngularJS library as a dependency to my Angular project since it's already bundled in the AngularJS project's JS files that the index.html loads.

To explain the situation a bit more in detail: I've followed the upgrade guide to bootstrap the AngularJS app from Angular, like so:

// src/app/app.module.ts of the Angular project
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { UpgradeModule } from '@angular/upgrade/static';

import { AppComponent } from './app.component';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    UpgradeModule
  ],
  providers: [],
})
export class AppModule {
  constructor(private upgrade: UpgradeModule) { }
  ngDoBootstrap() {
    // Bootstrap AngularJS app
    this.upgrade.bootstrap(document.documentElement, ['my-angularjs-app']);
  }
}

The files src/main.ts and src/app/app.component.ts are unchanged compared to a default $ ng new my-app project. Now, I run $ ng build --prod to produce production-ready JavaScript files that I can include in the AngularJS project's index.html as mentioned above. (Specifically, the Angular files are loader after the AngularJS files.)

Now I would like to make AppComponent available to AngularJS. This section of the guide suggests that I add the following lines to the above app.module.ts:

import { downgradeComponent } from '@angular/upgrade/static';

angular.module('my-angularjs-app')
  .directive(
    'my-ng2-component',
    downgradeComponent({ component: AppComponent }) as angular.IDirectiveFactory
  );

However, the angular variable obviously is not available and the TypeScript compiler complains about that. How do I change that? I've tried the following things to no avail:

  1. Add a line declare var angular: any or a line let angular = window.angular. This results in Cannot find namespace 'angular' when adding the downgrade code from above.
  2. Add @types/angular as a dependency to my Angular project and add a line import * as angular from 'angular'. (This results in Module not found: Error: Can't resolve 'angular' when adding the downgrade code.)
  3. Like 2) but add a line /// <reference path="../../node_modules/@types/angular/index.d.ts" /> to the top of the file
  4. Like 2) but add a line /// <reference types="angular" /> to the top of the file.

3) and 4) result in the following error message:

'angular' refers to a UMD global, but the current file is a module. Consider adding an import instead.

The latter seems to be related to the following two issues on GitHub:

Is there any way that actually works? The upgrade guide, unfortunately, is very vague when it comes to this.

1 Answer 1

1

After a lot of trial and error, I finally found a variant that seems to work. I added the following lines to app.module.ts:

import { downgradeComponent } from '@angular/upgrade/static';

declare var angular: any; // <-- Added declaration

angular.module('my-angularjs-app')
  .directive(
    'my-ng2-component',
    downgradeComponent({ component: AppComponent }) // <-- Note that there's no type conversion here anymore.
  );
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.