javascripttypescriptamdsystemjses6-module-loader

How to get rid off the "default" property when loading modules with SystemJS?


I have an AMD module which I want to load with SystemJS. I am able to do this but unfortunately I have to call it like this:

var Logdown = module.default;
var instance = new Logdown('Test');

I would like to skip making a call to .default, but I don't know how to get rid off this property. I think that this default is somehow assigned by the SystemJS loader.

This is my module:

logdown.js

define('Logdown', function() {
  function Logdown(name) {
    this.name = name;
  }

  Logdown.prototype.log = function() {
    console.log(this.name);
  };

  return Logdown;
});

And here is my SystemJS configuration:

SystemJS.config({
  baseURL: '/dist',
  map: {
    'logdown': 'lib/dynamic/logdown/logdown.js'
  }
});

Solution

  • TL;DR

    Use the import ... from "..."; syntax instead of import ... = require("..."); when using named AMD modules in TypeScript code.

    Explanation

    My main application (using the Logdown module) is written in TypeScript and compiled to ES5 code. With this setup I noticed that there is a difference in the output depending on the TypeScript import syntax used.

    Here are the differences:

    import Logdown from "logdown";
    
    export default class Main {
    
      constructor(message: string) {
        let logger: Logdown = new Logdown('Test');
        logger.log();
      }
    }
    

    Compiles to:

    System.register(["logdown"], function(exports_1, context_1) {
      "use strict";
      var __moduleName = context_1 && context_1.id;
      var logdown_1;
      var Main;
      return {
        setters: [
          function(logdown_1_1) {
            logdown_1 = logdown_1_1;
          }],
        execute: function() {
          Main = (function() {
            function Main(message) {
              var logger = new logdown_1.default('Test');
              logger.log();
            }
    
            return Main;
          }());
          exports_1("default", Main);
        }
      }
    });
    

    And:

    import Logdown = require("logdown");
    
    export default class Main {
    
      constructor(message: string) {
        let logger: Logdown = new Logdown('Test');
        logger.log();
      }
    }
    

    Compiles to:

    System.register(["logdown"], function(exports_1, context_1) {
        "use strict";
        var __moduleName = context_1 && context_1.id;
        var Logdown;
        var Main;
        return {
            setters:[
                function (Logdown_1) {
                    Logdown = Logdown_1;
                }],
            execute: function() {
                Main = (function () {
                    function Main(message) {
                        var logger = new Logdown('Test');
                        logger.log();
                    }
                    return Main;
                }());
                exports_1("default", Main);
            }
        }
    });
    

    The important part is that when using import Logdown from "logdown";, the compiled TypeScript code will create new instances like this var logger = new logdown_1.default('Test');.

    But when using import Logdown = require("logdown");, then the compiled TypeScript code does not add a default property but instead creates instances like this: var logger = new Logdown('Test');.

    So with the module type I have (a named AMD module), I need to use the import ... from "..."; synatx.