5

我们正在考虑将我们的一些角度项目移动到typescript并在内部模块/命名空间中遇到一些问题。如何使用SystemJS将角度TypeScript与内部模块捆绑在一起

我们张贴了这个工作示例在GitHub上:https://github.com/hikirsch/TypeScriptSystemJSAngularSampleApp

步骤:

npm install jspm -g 
npm install 
cd src/ 
jspm install 
jspm install --dev 
cd .. 
gulp bundle 
cd src/ 
python -m SimpleHTTPServer 

这是应用程序的要点: index.ts

/// <reference path="../typings/tsd.d.ts" /> 
/// <reference path="../typings/typescriptApp.d.ts" /> 

import * as angular from 'angular'; 

import {ExampleCtrl} from './controllers/ExampleCtrl'; 
import {ExampleTwoCtrl} from './controllers/ExampleTwoCtrl'; 

export var app = angular.module("myApp", []); 

app.controller("ExampleCtrl", ExampleCtrl); 
app.controller("ExampleTwoCtrl", ExampleTwoCtrl); 

ExampleCtrl.ts

/// <reference path="../../typings/tsd.d.ts" /> 
/// <reference path="../../typings/typescriptApp.d.ts" /> 


export class ExampleCtrl { 
    public static $inject:Array<string> = []; 

    constructor() { 

    } 

    public name:string; 
    public hello_world:string; 

    public say_hello() { 
     console.log('greeting'); 

     this.hello_world = "Hello, " + this.name + "!"; 
    } 
} 

ExampleTwoCtrl.ts

/// <reference path="../../typings/tsd.d.ts" /> 
/// <reference path="../../typings/typescriptApp.d.ts" /> 

export class ExampleTwoCtrl { 
    public static $inject:Array<string> = []; 

    constructor() { 

    } 

    public name:string; 
    public text:string; 

    public second() { 
     this.text = "ExampleTwoCtrl: " + this.name; 
    } 
} 

如前所述,这个工作都很好。但我们宁愿有一个像这样的命名空间下的一切:

module myApp.controllers { 
    export class ExampleController { 
     ... 
    } 
} 
//do we need to export something here? 

,然后用它是这样的:

这将编译正常运行吞气包的任务,但在浏览器中 给出一个错误/// ///

import * as angular from 'angular'; 

import ExampleCtrl = myApp.controllers.ExampleCtrl; 
import ExampleTwoCtrl = myApp.controllers.ExampleTwoCtrl; 

export var app = angular.module("myApp", []); 

app.controller("ExampleCtrl", ExampleCtrl); 
app.controller("ExampleTwoCtrl", ExampleTwoCtrl); 

浏览器错误:

Uncaught ReferenceError: myApp is not defined(anonymous function) @ build.js:5u @ build.js:1i @ build.js:1c @ build.js:1(anonymous function) @ build.js:1(anonymous function) @ build.js:1 
build.js:1 Uncaught Error: [$injector:modulerr] Failed to instantiate module myApp due to: 
Error: [$injector:nomod] Module 'myApp' is not available! You either misspelled the module name or forgot to load it. If registering a module ensure that you specify the dependencies as the second argument. 
http://errors.angularjs.org/1.3.15/$injector/nomod?p0=myApp 
    at http://localhost:8000/build/build.js:1:4007 
    at http://localhost:8000/build/build.js:1:12353 
    at e (http://localhost:8000/build/build.js:1:11925) 
    at t.register.e (http://localhost:8000/build/build.js:1:12237) 
    at http://localhost:8000/build/build.js:1:20741 
    at o (http://localhost:8000/build/build.js:1:4392) 
    at p (http://localhost:8000/build/build.js:1:20519) 
    at Bt (http://localhost:8000/build/build.js:1:22209) 
    at t.register.s (http://localhost:8000/build/build.js:1:10038) 
    at Q (http://localhost:8000/build/build.js:1:10348) 
http://errors.angularjs.org/1.3.15/$injector/modulerr?p0=myApp&p1=Error%3A%…0%20at%20Q%20(http%3A%2F%2Flocalhost%3A8000%2Fbuild%2Fbuild.js%3A1%3A10348) 

回答

2

根据typescript documentation,在编译为commonjs时不需要使用内部模块。如前所述:

A key feature of external modules in TypeScript is that two different external modules will never contribute names to the same scope. Because the consumer of an external module decides what name to assign it, there's no need to proactively wrap up the exported symbols in a namespace.

我发现使用打字稿与CommonJS的装载机(我用browserify)最好的办法是做这样的事情:

class ExampleTwoCtrl { 
    public static $inject:Array<string> = []; 

    constructor() { 

    } 

    public name:string; 
    public text:string; 

    public second() { 
     this.text = "ExampleTwoCtrl: " + this.name; 
    } 
} 

export = ExampleTwoCtrl 

和使用它像:

import MyController = require('./ExampleTwoCtrl'); 
var a = new MyController(); 

这就是说,我从John Papa's talk at AngularU观看了录音,他们演示了一些代码捆绑在一起,使用的是没有任何导入的systemScript,只是内部的ts模块。我在twitter上询问我可以找到示例代码,但尚未得到答复。

+0

有使用链接到这里幻灯片中的示例代码18 https://docs.google.com/presentation/d/1ETDm0R_BxZUcumqDxnG8puKbq_gHvMZyOwmq09wUk68/edit#slide=id.ga1ef308f1_0_56 – stuffins

+0

它们基本上使用的方法只是转储脚本标签为项目中的每个JS放到html页面上,而不管它是否被使用。我们正在寻找一种方法,我们可以告诉它哪个文件启动应用程序,并让它适当地构建文件。我们没有使用模块似乎可以实现它。试图弄清楚我们如何使用模块进行这项工作(本质上只是想让所有的命名空间) – stuffins

+0

我也这么认为,但事实并非如此。如果您检查index.html(https://github.com/johnpapa/hottowel-angular-typescript/blob/master/src/client/index.html),它根本不使用systemjs。他们显示的代码是不同的,因为有一个systemjs和一些其他文件以及一个加载main的脚本。js(如果我没记错的话,视频的最低50分) – masimplo

相关问题