Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using Angular 1.x with TypeScript 1.5 and SystemJS

I'm trying to use Angular 1.x with TypeScript 1.5.3 and SystemJS. The index.html page is set up to System.import('bootstrapper') which should start things up.

bootstrapper.ts gets compiled to bootstrapper.js and works fine as long as it doesn't use angular (i.e. doing just a console.log() works ok)

Now, I'd like to import and use angular to bootstrap it. I've already done jspm install angular and I also installed some typings for angular using tsd. The typings are referenced at the top of the bootstrap.ts file.

Unfortunately doing import angular from 'angular' doesn't compile, I get Module "angular" has no default export. My questions are:

  1. Why doesn't import angular from 'angular' compile? Looking in the angular.d.ts file I see declare module 'angular'{ export = angular; } which, if I understand correctly, is a default export from the module angular of a variable (defined above in the typings file) declare var angular: angular.IAngularStatic
  2. I noticed that doing import 'angular' compiles and then I can actually reference angular and do e.g. angular.module(...), but I don't think I understand correctly how this works. Shouldn't import 'angular' do a "bare import", i.e. running a module only for its side effects? If that's the case, does that mean that this import actually registers angular in the global scope?

I'm pretty sure I don't understand correctly how modules/type definition files work in Typescript, thanks in advance for an explanation.

like image 428
adrian h. Avatar asked Sep 01 '15 16:09

adrian h.


2 Answers

Firstly, the following is my preferred way to use AngularJS 1.5 with TypeScript and SystemJS:

index.html

<script src="jspm_packages/system.js"></script>
<script src="config.js"></script>

<script>
  SystemJS.import('app')
    .then(function (app) {
      app.bootstrap(document);
    })
    .catch(function (reason) { 
      console.error(reason);
    });
</script>

app/main.ts

import angular from 'angular';

const app = angular.module('app', []);

export function bootstrap(target: Element | Document) {
  angular.bootstrap(target, [app.name], { strictDi: true });
}

tsconfig.json

{
    "compilerOptions": {
      "module": "system",
      "allowSyntheticDefaultImports": true,
      ....
    }
}

config.js (loader config, simplified)

SystemJS.config({
  transpiler: "typescript",
  packages: {
    "app": {
      "main": "main.ts",
      "defaultExtension": "ts",
      "meta": {
        "*.ts": {
          "loader": "typescript"
        }
      }
    }
  }
});

Notes:

  1. If you are using JSPM 0.17 specify "plugin-typescript", not "typescript" for the loader and transpiler or just run $ jspm init and select a transpiler.
  2. The you can import angular as a default, but it will still register itself on the global scope.
  3. The reason you are getting syntax errors is because angular, and its angular.d.ts declaration file contains a CommonJS style export = declaration to allow for module and global namespace based usage. SystemJS, for maximum compatibility, interpolates this into a default export at runtime.
  4. The TypeScript compiler needs to be made aware of this. This can be done by setting "module": "system", and/or specifying "allowSyntheticDefaultImports": true. I have done both for the sake of exposition and explicitness.
  5. If you aren't using jspm, you just need to tell system JS where to find the typescript using map or package config

    SystemJS.config({
      map: {
        "typescript": "node_modules/typescript"
      }
    });
    
like image 169
Aluan Haddad Avatar answered Oct 08 '22 17:10

Aluan Haddad


[...] if I understand correctly, is a default export from the module angular of a variable

Nope, that's not what's happening. Angular exports the entire namespace as the export, if that makes sense.

import angular from 'angular' is attempting to import the default from the module.

What you want is import * as angular from 'angular'; which imports the entire export as a variable.

like image 29
thoughtrepo Avatar answered Oct 08 '22 17:10

thoughtrepo