8

我正在尝试将 Angular 1.x 与 TypeScript 1.5.3 和 SystemJS 一起使用。该index.html页面已设置为System.import('bootstrapper')应该启动的内容。

bootstrapper.tsbootstrapper.js只要它不使用角度,就可以编译并正常工作(即只做一个console.log()工作正常)

现在,我想导入并使用 angular 来引导它。我已经完成了jspm install angular,我还使用tsd. 类型在文件顶部引用bootstrap.ts

不幸的是,做import angular from 'angular'不编译,我得到Module "angular" has no default export. 我的问题是:

  1. 为什么不import angular from 'angular'编译?查看angular.d.ts文件,如果我理解正确,我看到declare module 'angular'{ export = angular; }哪个是从变量的模块角度的默认导出(在上面的类型文件中定义)declare var angular: angular.IAngularStatic
  2. 我注意到进行import 'angular'编译然后我可以实际引用angular并执行 eg angular.module(...),但我认为我没有正确理解它是如何工作的。不应该import 'angular'做一个“裸导入”,即只为它的副作用运行一个模块?如果是这样,这是否意味着这个导入实际上是angular在全局范围内注册的?

我很确定我不能正确理解模块/类型定义文件在 Typescript 中是如何工作的,在此先感谢您的解释。

4

2 回答 2

7

首先,以下是我将 AngularJS 1.5 与 TypeScript 和 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(加载器配置,简化)

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

笔记:

  1. 如果您使用的是 JSPM 0.17,请指定"plugin-typescript",而不是"typescript"加载器和转译器,或者只是运行$ jspm init并选择一个转译器。
  2. 您可以将 angular 作为默认值导入,但它仍会在全局范围内注册。
  3. 您收到语法错误的原因是angular,它的angular.d.ts声明文件包含一个 CommonJS 样式export =声明,以允许基于模块和全局命名空间的使用。SystemJS,为了获得最大的兼容性,在运行时将其插入到默认导出中。
  4. TypeScript 编译器需要意识到这一点。这可以通过设置"module": "system"和/或指定来完成"allowSyntheticDefaultImports": true。为了阐述和明确,我已经这样做了。
  5. 如果你不使用 jspm,你只需要告诉系统 JS 在哪里可以使用 map 或 package config 找到 typescript

    SystemJS.config({
      map: {
        "typescript": "node_modules/typescript"
      }
    });
    
于 2016-05-30T03:06:40.327 回答
5

[...]如果我理解正确,是从变量的模块角度的默认导出

不,这不是正在发生的事情。如果有意义的话,Angular 会将整个命名空间导出为导出。

import angular from 'angular'正在尝试default从模块导入。

您想要的是import * as angular from 'angular';将整个导出作为变量导入。

于 2015-09-01T17:11:55.740 回答