bsr bsr - 1 month ago 7
TypeScript Question

typescript: concatination order in generated file

I have a ts (angularjs) project and uses a reference file to specify the order of dependencies. But, it is not ordering correctly. In the generated

js
file, controller file is last, where it should be before module. Hence, it gives error at runtime as
TestCtrl
referenced in the module

test.am.controller(mod.test.TestCtrl.ID, [mod.test.TestService.ID, function (srv) {
return new mod.test.TestCtrl(srv);
}]);


so, why the ordering in
references
file is not followed? Any why in the generated file
controller
file is not included before
module
, though it is referenced in the
module.ts
file.

I use grunt-ts for compiling the files, and the command is

Running "ts:dev" (ts) task
Verifying property ts.dev exists in config...OK
Files: src/controller.ts, src/module.ts, src/names.ts, src/reference.ts, src/service.ts
Options: allowBool=false, allowImportModule=false, compile, declaration=false, mapRoot="", module="amd", noImplicitAny=false, noResolve=false, comments, removeComments=null, sourceMap, sourceRoot="", target="es3", verbose=false, fast="watch"
Compiling...
Cleared fast compile cache for target: dev
Fast compile will not work when --out is specified. Ignoring fast compilation
Using tsc v0.9.5
"/Users/test/order2/src/controller.ts" "/Users/test/order2/src/module.ts" "/Users/test/order2/src/names.ts" "/Users/test/order2/src/reference.ts" "/Users/test/order2/src/service.ts" --sourcemap --target ES3 --module amd --out out.js


ps: grunt-ts supports
reference-file-generation
, but I do not want to use it at the moment.

reference.ts

/// <reference path="angularjs/angular.d.ts" />

/// <reference path="names.ts" />
/// <reference path="service.ts" />
/// <reference path="controller.ts" />
/// <reference path="module.ts" />


names.ts

//names section

/// <reference path="reference.ts" />

module mod{
export module test{
export var ID = "test"
}
}


service.ts

//service section

/// <reference path="reference.ts" />

module mod{
export module test{

export interface ITestService {
}
export class TestService implements ITestService {
static ID = ""
}
}
}


controller.ts

//controller section

/// <reference path="reference.ts" />

module mod{
export module test{

export interface ITestCtrl {
}

export class TestCtrl implements ITestCtrl {
static ID = ""
constructor(private rec:ITestService) {
}
}
}
}


module.ts

//modules section

/// <reference path="reference.ts" />

module mod{
export module test{
export var am:ng.IModule = angular.module(test.ID, ['ngRoute']);
am.controller(TestCtrl.ID, [TestService.ID, (srv:ITestService) => new TestCtrl(srv)]);
}
}


generated file (js)

//names section
/// <reference path="reference.ts" />
var mod;
(function (mod) {
(function (test) {
test.ID = "test";
})(mod.test || (mod.test = {}));
var test = mod.test;
})(mod || (mod = {}));
//service section
/// <reference path="reference.ts" />
var mod;
(function (mod) {
(function (test) {
var TestService = (function () {
function TestService() {
}
TestService.ID = "";
return TestService;
})();
test.TestService = TestService;
})(mod.test || (mod.test = {}));
var test = mod.test;
})(mod || (mod = {}));
//modules section
/// <reference path="reference.ts" />
var mod;
(function (mod) {
(function (test) {
test.am = angular.module(mod.test.ID, ['ngRoute']);
test.am.controller(mod.test.TestCtrl.ID, [mod.test.TestService.ID, function (srv) {
return new mod.test.TestCtrl(srv);
}]);
})(mod.test || (mod.test = {}));
var test = mod.test;
})(mod || (mod = {}));
//controller section
/// <reference path="reference.ts" />
var mod;
(function (mod) {
(function (test) {
var TestCtrl = (function () {
function TestCtrl(rec) {
this.rec = rec;
}
TestCtrl.ID = "";
return TestCtrl;
})();
test.TestCtrl = TestCtrl;
})(mod.test || (mod.test = {}));
var test = mod.test;
})(mod || (mod = {}));
//# sourceMappingURL=out.js.map

Answer

It is because of the command passed into the compiler :

"/Users/test/order2/src/controller.ts" "/Users/test/order2/src/module.ts" "/Users/test/order2/src/names.ts" "/Users/test/order2/src/reference.ts" "/Users/test/order2/src/service.ts" --sourcemap --target ES3 --module amd --out out.js

The order will be determined by the file order passed in the command because you all files reference reference.ts unless all you pass to the compiler is reference.ts.

So solution: either use reference file generation by grunt-ts, so grunt-ts will only ask the compiler to compile reference.ts

OR

Have explicit <reference tags pointing to the files you need to be included before the current file.

BTW grunt-ts the latest version can generate these reference tags for you e.g. ///ts:ref=controller will generate a reference tag to controller.ts. I need to document these transform but am busy with projects.