Как использовать momentjs в TypeScript с SystemJS?
Моя настройка проекта включает инструмент "jspm" для библиотек и инструмент "tsd" для типирования.
После установки момента TypeScript файла d.ts(этих) я не могу найти способ загрузки и фактического использования экземпляра момента.
В моем файле (с загрузкой модуля SystemJS)
/// <reference path="../../../typings/tsd.d.ts" />
import * as moment from "moment";
import * as _ from "lodash";
...
...
const now = (this.timestamp === 0) ? moment() : moment(this.timestamp);
Я получаю "TypeError: момент не является функцией"
Определения структурированы так же, как lodash, который отлично работает, поэтому я не знаю, что может быть причиной.
Может ли кто-нибудь помочь?
Ответы
Ответ 1
Я сделал следующее:
Я установил moment
файл определения следующим образом:
tsd install moment --save
Затем я создал main.ts:
///<reference path="typings/moment/moment.d.ts" />
import moment = require("moment");
moment(new Date());
И я побежал:
$ tsc --module system --target es5 main.ts # no error
$ tsc --module commonjs --target es5 main.ts # no error
main.js
выглядит следующим образом:
// https://github.com/ModuleLoader/es6-module-loader/blob/v0.17.0/docs/system-register.md - this is the corresponding doc
///<reference path="typings/moment/moment.d.ts" />
System.register(["moment"], function(exports_1) {
var moment;
return {
setters:[
function (moment_1) {
// You can place `debugger;` command to debug the issue
// "PLACE XY"
moment = moment_1;
}],
execute: function() {
moment(new Date());
}
}
});
Моя версия TypeScript - 1.6.2.
Вот что я узнал:
Momentjs экспортирует функцию (т.е. _moment = utils_hooks__hooks
и utils_hooks__hooks
- это функция, которая достаточно понятна.
Если вы разместите точку останова в месте, обозначенном мной как PLACE XY
выше, вы увидите, что moment_1
является объектом (!), а не функцией. Соответствующие строки: 1, 2
В заключение этого проблема не имеет ничего общего с TypeScript. Проблема в том, что systemjs не сохраняет информацию о том, что momentjs экспортирует функцию. Systemjs просто копирует свойства экспортируемого объекта из модуля (функция также является объектом в JavaScript). Я думаю, вы должны указать проблему в репозитории systemjs, чтобы узнать, считают ли они, что это ошибка (или функция:)).
Ответ 2
Начиная с версии 2.13, момент включает в себя Typescript типизацию. Нет необходимости использовать tsd
(или typings
) больше.
В файле systemjs.config.js
просто добавьте следующее:
var map = {
// (...)
moment: 'node_modules/moment',
};
var packages = {
// (...)
moment: { main: 'moment.js', defaultExtension: 'js' },
};
И в модуле:
import moment = require('moment')
Ответ 3
У меня были огромные проблемы с тем, чтобы это работало, поскольку я не мог использовать npm из-за ограничений прокси (поэтому им пришлось вручную устанавливать библиотеки). Если версии моментов и определенные файлы установлены в соответствующих местах вашего проекта, вы можете заставить это работать с немного возиться.
Здесь полезно отметить на сайте moment.js по настройке typescript с моментом. Ключевым аспектом, который помог в моем случае, было добавить следующее в разделе compilerOptions моего файла tsconfig.json:
"allowSyntheticDefaultImports": true
Ответ 4
Это работает с Angular 2, но не должно быть специфичным для него. В основном вы говорите загрузчику System, где можно найти moment.min.js
.
В system.config.js
:
// map tells the System loader where to look for things
var map = {
'app': 'app', // 'dist',
'@angular': 'node_modules/@angular',
'rxjs': 'node_modules/rxjs',
// tell system where to look for moment
'moment': 'node_modules/moment/min'
};
// packages tells the System loader how to load when no filename and/or no extension
var packages = {
'app': { main: 'main.js', defaultExtension: 'js' },
'rxjs': { defaultExtension: 'js' },
// tell system which file represents the script when you import
'moment': { main: 'moment.min.js', defaultExtension: 'js'}
};
В вашем модуле:
import moment from 'moment';
ИЛИ (Редактировать 10/13/2016):
import * as moment from 'moment';
Некоторые комментаторы опубликовали синтаксис import *
выше, и мне пришлось переключиться на это, а также после некоторых обновлений (не знаю, почему).
Ответ 5
В моем typescript файле, когда я использую
import moment from 'moment';
он говорит, что не может найти модуль "момент". Я установил момент как пакет npm, и он ссылается правильно, но по этой причине этот момент .d.ts экспортирует момент как пространство имен, а не модуль, как показано ниже, я не могу ссылаться на него.
export = moment;
Итак, если я изменю его на
declare module 'moment' {
export default moment;
}
импортирует работы отлично. Что я здесь делаю неправильно?
Ответ 6
Немного непонятно, пытаетесь ли вы использовать момент для разработки на стороне клиента или для серверной части (например, node.js). Но, если ваш случай является интерфейсом, то я смог использовать момент довольно легко:
1) Я просто добавил файлы в свой проект:
![введите описание изображения здесь]()
2) Написал простой тестовый код:
window.onload = () =>
{
var timestamp: number = 111111111111111;
var momentResult: moment.Moment = moment(timestamp);
alert(momentResult.toISOString());
};
И мой проект был построен нормально, и я видел тестовое предупреждение в браузере.
Ответ 7
Просто сделал это в моем проекте. Это angular, но я не думаю, что это имеет значение и может поставить вас на правильный путь. Это легко:
import MomentStatic = moment.MomentStatic;
class HelpdeskTicketController {
constructor(private moment: MomentStatic) { // angulars dependency injection, you will have some global probably
let d = this.moment(new Date()); // works
console.log(d.add(2, 'hours').format()); // works
}
...
Ответ 8
Я предполагаю, что момент был установлен с помощью
jspm install moment
Это должно добавить запись в раздел карты вашего config.js.
...
"moment": "npm:[email protected]",
...
Таким образом, вы можете получить доступ к моменту в файлах js через
import moment from 'moment';
console.log(moment().format('dddd, MMMM Do YYYY, h:mm:ss a'));
При импорте * as moment
вы импортируете пространство имен модулей. Таким образом, момент будет объектом, свойства которого представляют собой экспорт модулей. Таким образом, экспорт по умолчанию не импортируется как момент, а как moment.default.
Так что что-то вроде
moment.default().format('dddd, MMMM Do YYYY, h:mm:ss a')
может действительно работать в вашем коде, но не тот способ, которым он предназначен для использования.
Ответ 9
Для моих продуктов я использую Webpack с VS 2015 (обновление 3). Поэтому после добавления кодов для файлов package.json и webpack.config.vendor.js мне просто нужно вызвать import moment = require ('moment') на самом верху моего компонента (TypeScript, Angular 2).