Search code examples
typescriptmagento2amd

Loading compiled Typescript AMD modules in Magento2


i'm trying to turn Magento 2 into the future and add Typescript support there. Everything compiles correctly, but I can't load it :(

require-config.js

var config = {
    deps: [
        "web/js/app"
    ],
    bundles: {
        "web/js/app": [ "main", "moduleone", "moduletwo" ]
    }
};

web/js/app.js

define("moduleone", ["require", "exports"], function (require, exports) {
    "use strict";
    Object.defineProperty(exports, "__esModule", { value: true });
    var ModuleOne = (function () {
        function ModuleOne() {
        }
        ModuleOne.prototype.sayHello = function () {
            console.log("Hello from ModuleTwo!");
        };
        ModuleOne.prototype.sayHelloTo = function (who) {
            console.log("Hello " + who.trim() + ". This is ModuleTwo");
        };
        return ModuleOne;
    }());
    exports.ModuleOne = ModuleOne;
});
define("moduletwo", ["require", "exports"], function (require, exports) {
    "use strict";
    Object.defineProperty(exports, "__esModule", { value: true });
    var ModuleTwo = (function () {
        function ModuleTwo() {
        }
        ModuleTwo.prototype.sayHello = function () {
            console.log("Hello from ModuleTwo!");
        };
        ModuleTwo.prototype.sayHelloTo = function (who) {
            console.log("Hello " + who.trim() + ". This is ModuleTwo");
        };
        return ModuleTwo;
    }());
    exports.ModuleTwo = ModuleTwo;
});
define("main", ["require", "exports", "moduleone", "moduletwo"], function (require, exports, Module1, Module2) {
    "use strict";
    Object.defineProperty(exports, "__esModule", { value: true });
    var Main = (function () {
        function Main() {
            console.log('Test');
        }
        Main.prototype.start = function () {
            var m1 = new Module1.ModuleOne();
            var m2 = new Module2.ModuleTwo();
            m1.sayHelloTo("David Wesst");
            m2.sayHelloTo("David Wesst");
        };
        return Main;
    }());
    exports.Main = Main;
});

Loading module:

<script type="text/javascript">
require(['main'], function(Main) {
    console.log(Main);
    var app = new Main();
    app.start();
});</script>

Calling Main returns:

Uncaught TypeError: Main is not a constructor

Plz help!


Solution

  • Since you are writing raw AMD JavaScript, just use return Main and not exports.Main = Main, that should do the trick.

    Perhaps I am misunderstanding and that is compiled output, it does look like it.

    In that case use, if it is compiled from TypeScript source, you can (very, very unpleasantly) use

    export = class Main {};
    

    over what you have now which would be

    export class Main {}
    

    Personally, I would bite the bullet and write

    export default class Main {};
    

    and bootstrap with

    <script type="text/javascript">
    require(['main'], function(module) {
        var Main = module.default;
        console.log(Main);
        var app = new Main();
        app.start();
    });</script>
    

    That way we can all move forward together and kill the bad legacy dept of TypeScript + NodeJS + CJS + AMD + Interop in browsers.