Как избавиться от свойства «default» при загрузке модулей с помощью SystemJS?

#javascript #typescript #amd #systemjs #es6-module-loader

#javascript #typescript #amd #systemjs #es6-module-loader

Вопрос:

У меня есть модуль AMD, который я хочу загрузить с помощью SystemJS. Я могу это сделать, но, к сожалению, мне приходится называть это следующим образом:

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

Я хотел бы пропустить вызов .default , но я не знаю, как избавиться от этого свойства. Я думаю, что это default каким-то образом назначается загрузчиком SystemJS.

Это мой модуль:

logdown.js

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

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

  return Logdown;
});
  

И вот моя конфигурация SystemJS:

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

Комментарии:

1. Что у вас есть в logdown.js называется «named module» в спецификации AMD , на которую вы ссылаетесь, и в этом документе говорится: «Вам следует избегать присвоения имен модулям самостоятельно и размещать только один модуль в файле во время разработки. Однако для обеспечения инструментария и производительности модульному решению необходим способ идентификации модулей во встроенных ресурсах.» Для SystemJS присвоение имени module в logdown.js превращает этот файл в пакет, а не в модуль. И на ваш вопрос невозможно ответить, не увидев полный исходный код, который импортирует этот модуль.

2. Спасибо за разъяснение, Артем. ☺

3. default создается не загрузчиком модуля, а скорее объявлением экспорта.

Ответ №1:

TL; DR

Используйте import ... from "..."; синтаксис вместо import ... = require("..."); при использовании именованных модулей AMD в коде TypeScript.

Объяснение

Мое основное приложение (использующее Logdown модуль) написано на TypeScript и скомпилировано в код ES5. При этой настройке я заметил, что в выходных данных есть разница в зависимости от используемого синтаксиса импорта TypeScript.

Вот различия:

 import Logdown from "logdown";

export default class Main {

  constructor(message: string) {
    let logger: Logdown = new Logdown('Test');
    logger.log();
  }
}
  

Компилируется в:

 System.register(["logdown"], function(exports_1, context_1) {
  "use strict";
  var __moduleName = context_1 amp;amp; 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);
    }
  }
});
  

И:

 import Logdown = require("logdown");

export default class Main {

  constructor(message: string) {
    let logger: Logdown = new Logdown('Test');
    logger.log();
  }
}
  

Компилируется в:

 System.register(["logdown"], function(exports_1, context_1) {
    "use strict";
    var __moduleName = context_1 amp;amp; 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);
        }
    }
});
  

Важной частью является то, что при использовании import Logdown from "logdown"; скомпилированный код TypeScript создаст новые экземпляры, подобные этому var logger = new logdown_1.default('Test'); .

Но при использовании import Logdown = require("logdown"); скомпилированный код TypeScript не добавляет default свойство, а вместо этого создает экземпляры, подобные этому: var logger = new Logdown('Test'); .

Итак, с тем типом модуля, который у меня есть (названный модуль AMD), мне нужно использовать import ... from "..."; synatx.

Ответ №2:

При предыдущей комплектации с webpack вы могли просто добавить esModule свойство со значением false в конфигурацию загрузчиков (если поддерживается).

Например, с помощью html-загрузчика выполните следующие действия: https://webpack.js.org/loaders/html-loader/#esmodule