Как экспортировать класс TypeScript таким образом, чтобы не нарушать доступ к объекту, используя простой старый ванильный JavaScript

Простите мое незнание в этом вопросе, я застрял и надеюсь получить какое-то руководство.

Возьмите этот пример класса Greeter, найденный на TypeScript страница детской площадки:

class Greeter {
    greeting: string;
    constructor(message: string) {
        this.greeting = message;
    }
    greet() {
        return "Hello, " + this.greeting;
    }
}

Мне было поручено создать и управлять одним компонентом, который можно использовать как в простой среде HTML + JavaScript, так и в приложении Angular. Я управляю / пишу этот код на TypeScript и использую TypeScript для компиляции вывода как JavaScript.

Возвращаясь к приведенному выше примеру, если бы я хотел сделать этот класс доступным (как импорт) в Angular, мне нужно было бы экспортировать класс?

export class Greeter {
    ...
}

Когда я это делаю, страница выдает ошибки:

Uncaught ReferenceError: define is not defined

Скомпилированный JavaScript выглядит так:

define(["require", "exports"], function (require, exports) {
    "use strict";
    Object.defineProperty(exports, "__esModule", { value: true });
    var Greeter = /** @class */ (function () {
        function Greeter(message) {
            this.greeting = message;
        }
        Greeter.prototype.greet = function () {
            return "Hello, " + this.greeting;
        };
        return Greeter;
    }());
    exports.Greeter = Greeter;
    var greeter = new Greeter("world");
});

Поскольку класс Greeter теперь привязан к этому блоку определения, я, очевидно, не могу создать экземпляр нового класса как такового:

let greeter = new Greeter("world"); // < -- Won't work.

Выдает ошибку:

Uncaught ReferenceError: Greeter is not defined

  1. Как я могу экспортировать этот класс таким образом, чтобы не нарушать доступ к объекту, скажем, в стиле ванильного JavaScript?
  2. Возможно ли то, что я пытаюсь сделать?
  3. Это разумная цель, или я здесь совершенно ошибаюсь?
define появляется в Playground, потому что по умолчанию используется модуль AMD. Это не так в реальном коде и зависит от того, какой параметр компилятора module установлен на. Как именно код связан с Angular? Это в первую очередь Angular или AngularJS? Вы используете этот файл в исходных файлах проекта Angular? В этом случае он будет скомпилирован как другие файлы. Вы экспортируете его как пакет NPM?
Estus Flask 28.04.2018 15:52

Это Angular, а не AngularJS. Что касается использования его с Angular, еще не совсем так, но идея состоит в том, что да, я хотел бы импортировать файл, а затем определить его как компонент. На данный момент это не пакет NPM, но применима та же идея: включите общий пакет JS где-нибудь в корневом приложении, обратитесь к нему или импортируйте его и используйте в приложении.

Michel Joanisse 30.04.2018 13:01

Это одна из многочисленных проблем, которые вам придется решить при настройке приложения Angular с нуля. Как показывает практика, приложения Angular используют Angular CLI для создания лесов и построения. TS уже настроен для вас. Альтернативой является использование шаблонного проекта, в котором TS снова уже настроен для вас. В практических целях вы можете придерживаться их и узнать, как там все делается. Вы можете узнать из официального Angular plunk, который, конечно же, содержит конфигурацию TS, plnkr.co/edit/tpl:AvJOMERrnz94ekVua0u5

Estus Flask 30.04.2018 15:11
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
2
3
254
1

Ответы 1

Хороший вопрос, то, что вы спрашиваете, определенно разумно.

Прежде всего, стоит упомянуть, что то, что вы называете «ванильным JavaScript», - это ES5 с совместимостью библиотек модулей AMD. ES6 представил для JavaScript модули на уровне родного языка, что и является синтаксисом export и import.

TypeScript имеет опция компилятора--module, который позволяет вам выбирать, для какого целевого модуля компилировать и для чего производить вывод. Однако в случае систем с внешними модулями, таких как AMD и CommonJS, он фактически не выводит модульную систему, необходимую для ее работы, а просто генерирует JavaScript, совместимый с этими системами. Вам решать, включать ли модульную систему, такую ​​как RequireJS, или запускать в среде со встроенной поддержкой, такой как модульная система CommonJS в NodeJS. Если вы установите для цели --module значение es6, вы увидите, что он оставляет операторы export как есть, и это будет работать в браузере, поддерживающем модули ES6 (при условии, что путь импорта разрешается в файл, к которому браузер может получить доступ).

Также стоит упомянуть, что с помощью сборщиков JavaScript, таких как Webpack или Browserify, вы можете взять практически любой вывод модуля из TypeScript и связать его для браузера без необходимости самостоятельно вводить среду выполнения модуля, потому что сборщик позаботится об этом.

Надеюсь, это поможет.

Спасибо @Aaron, ценим отзывы! Очень полезно. Мы учтем все эти моменты и соответствующим образом проведем рефакторинг.

Michel Joanisse 30.04.2018 12:54

Другие вопросы по теме