Как использовать momentjs в TypeScript с SystemJS?

настройка моего проекта включает инструмент "jspm" для библиотек и инструмент " tsd " для типизаций.

после установки moment'S TypeScript d.TS file (эти), Я не могу найти способ загрузить и фактически использовать экземпляр moment.

в моем файле (используя загрузку модуля 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:момент не является функцией"

определения структурированы так же, как лодашь, который нормально работает, поэтому я не знаю, что может быть причиной.

кто может помочь?

9 ответов


я сделал следующее:

я установил moment файл определения следующим образом:

tsd install moment --save

тогда я создал main.ТС:

///<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.13, moment включает в себя типизации Typescript. Нет необходимости использовать tsd (или typings) больше.

на systemjs.config.js файл, просто добавьте следующее:

  var map = {
    // (...)
    moment: 'node_modules/moment',      
  };

  var packages = {
    // (...)
    moment: { main: 'moment.js', defaultExtension: 'js' },
  };

и в модуле:

import moment = require('moment')

мне было очень трудно заставить это работать, так как я не мог использовать npm из-за ограничений прокси (поэтому пришлось вручную устанавливать библиотеки). При условии, что версии moment и definitelytyped файлы установлены в соответствующих местах в вашем проекте, вы можете заставить это работать с немного возиться.

есть Полезная заметка здесь на данный момент.сайт Яш по настройке typescript с моментом. Ключевым аспектом, который помог в моем случае добавлял следующее В разделе compilerOptions моего tsconfig.файл json:

"allowSyntheticDefaultImports": true

это работает с Angular 2, но не должно быть специфичным для него. Вы в основном просто говорите системному загрузчику, где найти 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 * синтаксис выше, и мне пришлось переключиться на это после некоторых обновлений (не знаю, почему).


в моем файле typescript, когда я использую

import moment from 'moment';

Он говорит, что не может найти модуль "момент". Я установил момент как пакет npm, и он ссылается правильно, но по той причине, что этот момент.d.ts экспортирует момент как пространство имен не модуль, как показано ниже, я не могу ссылаться на него.

export = moment; 

поэтому, если я изменю его на

declare module 'moment' {
    export default moment;
}

импорт прекрасно работает. Что я здесь делаю не так?


это немного неясно, если вы пытаетесь использовать moment для разработки на стороне клиента или на стороне сервера (например, node.в JS). Но, если ваш случай front-end, то я смог использовать момент довольно легко:

1) я только что добавил файлы в свой проект:

enter image description here

2) написал простой тестовый код:

window.onload = () =>
{
    var timestamp: number = 111111111111111;
    var momentResult: moment.Moment = moment(timestamp);
    alert(momentResult.toISOString());
};

и мой проект был построен нормально, и я увидел тестовое предупреждение в браузере.


просто сделать это в моем проекте. Это угловато, но я не думаю, что это имеет значение и может поставить вас на правильный путь. Это легко, как:

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
  }

  ...

Я полагаю, что момент был установлен с помощью

jspm install moment

Это должно добавить запись в разделе Карты вашей конфигурации.js.

...
"moment": "npm:moment@2.10.6",
...

таким образом, вы можете получить доступ к моменту в ваших JS-файлах через

import moment from 'moment';

console.log(moment().format('dddd, MMMM Do YYYY, h:mm:ss a'));

при импорте * as moment импортировать пространство имен модуля. Таким образом, moment будет объектом, свойства которого являются экспортом модуля. Таким образом, экспорт по умолчанию импортируется не как момент, а как момент.по умолчанию. Что-то вроде

moment.default().format('dddd, MMMM Do YYYY, h:mm:ss a')

может на самом деле работает в коде, но не так, как он предназначен для использования.


для моих материалов я использую Webpack с VS 2015 (обновление 3). Поэтому после добавления кодов для пакета.json и webpack.конфиг.торговец.JS-файлы, мне просто нужно вызвать import moment = require ('moment') в самой верхней части моего компонента (TypeScript, Angular 2).