Pregunta

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
¿Fue útil?

Solución

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.

Otros consejos

Typescript's documentation was useful to me on solving this once I figured out that the generation order was the problem. Typescript vs. Javascript Generation

When a output file is specified via out in combination with a reference file via reference then grunt-ts uses the generated reference file to order the code in the generated JavaScript.

Use reference.ts to specify the order for the few files the build really cares about and leave the rest to be maintained by grunt-ts.

E.g. in the following case the generated JavaScript for someBaseClass.ts is guaranteed to be at the top, and the generated JavaScript for main.ts is guaranteed to be at the bottom of the single merged js file.

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

// Put comments here and they are preserved

//grunt-start
/// <reference path="autoreference.ts" />
/// <reference path="someOtherFile.ts" />
//grunt-end

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

Everything between grunt-start and grunt-end is generated and maintained by grunt-ts. If there is no grunt-start section found, it is created. If reference.ts does not exist originally, it is also created.

Although sometimes all this feels like trying to follow the rules to Fizbin that Captain Kirk makes up on the fly.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top