Как использовать библиотеку moment.js в приложении 2 с машинописным текстом?

231

Я пытался использовать его с привязками машинописи:

npm install moment --save
typings install moment --ambient -- save

test.ts:

import {moment} from 'moment/moment';

И без:

npm install moment --save

test.ts:

var moment = require('moment/moment');

Но когда я вызываю moment.format (), я получаю сообщение об ошибке. Должно быть просто, кто-нибудь может предоставить комбинацию командной строки / импорта, которая будет работать?

Сергей Алдоухов
источник
1
поделитесь своей ошибкой пожалуйста
Басарат
1
Если я устанавливаю moment.d.ts и использую импорт, я получаю ОШИБКУ при компиляции в ... / typings / browser / ambient / moment / moment.d.ts (9,21): ошибка TS2503: не удается найти пространство имен 'moment' , И если я не устанавливаю набор текста и использую require, я получаю Uncaught TypeError: moment.format - это не функция
Сергей Алдоухов
Здесь слишком много старых ответов. Пожалуйста, смотрите здесь: github.com/angular/angular-cli/wiki/…
Didia
3
Ответ Хинриха сработал для меня с ng4 (по состоянию на июнь 2017 года) stackoverflow.com/a/43257938/1554495
вырезка
Сергей Алдоухов, это лучший ответ? конечно, у Хинриха есть?
Дженсон Баттон: мероприятие

Ответы:

513

Обновление апрель 2017:

Начиная с версии 2.13.0, Moment включает файл определения машинописи. https://momentjs.com/docs/#/use-it/typescript/

Просто установите его с помощью npm, в вашей консоли типа

npm install --save moment

И затем в вашем приложении Angular импортировать так просто:

import * as moment from 'moment';

Вот и все, вы получаете полную поддержку Typescript!

Бонусное редактирование: чтобы ввести переменную или свойство, как Momentв Typescript, вы можете сделать это, например:

let myMoment: moment.Moment = moment("someDate");
Hinrich
источник
1
важно добавить его в файл app.module и импортировать массив? или вы можете просто импортировать его в компонент и использовать его?
Кэтрин R
3
@Katherine R Вы можете использовать его в любом файле, это не специфично для Angular.
Генрих
А как насчет моментных плагинов, например, моментальных?
Greywire
2
На самом деле этот ответ не является специфичным для Angular, он применим к любому проекту Typescript.
Хинрих
Отлично, а как я использую трубу на шаблоне?
vladanPro
98

momentявляется сторонним глобальным ресурсом. В данный момент объект живет windowв браузере. Поэтому это не правильно importв вашем приложении angular2. Вместо этого включите<script> включите в ваш html тег, который будет загружать файл moment.js.

Чтобы сделать TypeScript счастливым, вы можете добавить

declare var moment: any;

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

///<reference path="./path/to/moment.d.ts" />

или используйте tsd для установки файла moment.d.ts, который TypeScript может найти самостоятельно.

пример

import {Component} from 'angular2/core';
declare var moment: any;

@Component({
    selector: 'example',
    template: '<h1>Today is {{today}}</h1>'
})
export class ExampleComponent{
    today: string = moment().format('D MMM YYYY');
}

Просто убедитесь, что добавили тег script в ваш html, или момент не будет существовать.

<script src="node_modules/moment/moment.js" />

Загрузка модуля moment

Сначала вам нужно настроить загрузчик модулей. такой как System.js, чтобы загружать файлы commonjs.

System.config({
    ...
    packages: {
        moment: {
            map: 'node_modules/moment/moment.js',
            type: 'cjs',
            defaultExtension: 'js'
        }
    }
});

Затем импортировать момент в файл, где необходимо использовать

import * as moment from 'moment';

или

import moment = require('moment');

РЕДАКТИРОВАТЬ:

Есть также варианты с некоторыми упаковщиками, такими как Webpack или SystemJS builder или Browserify, которые будут держать момент в стороне от объекта окна. Для получения дополнительной информации об этом, пожалуйста, посетите их соответствующие веб-сайты для обучения.

SnareChops
источник
3
Это возможно, но это очень долго, так как вам нужно иметь загрузчик модулей, такой как Systemload, в версии момента commonjs для узла, и тогда вы сможете ссылаться на него import * as moment from 'moment';или import moment = require('moment');который для всех намерений и целей идентичен, но имеет некоторые тонкие различия в машинописи.
SnareChops
@SnareChops typings install moment --ambient -- saveне typingsопускает файл определения и не создает ссылку на ///<reference path="./path/to/moment.d.ts" />? У меня та же ошибка при запускеnpm run tsc
Шон Нортроп
Это вводит в заблуждение; нет ничего плохого в этом importмоменте.
Стигглер
2
Этот ответ неполон, потому что вы должны использовать Наборы для управления определением момента. Также не нужно ничего импортировать. Пожалуйста, смотрите мой ответ ниже .
Бернардо Пачеко
8
Этот ответ вводит в заблуждение, тот факт, что момент является глобальной переменной, не означает, что вам «нужно» загрузить ее как тег сценария. Вы можете и должны связать его в файл поставщика, если вы используете какой-то пакет (Webpack). Вы также можете обойти глобальное назначение, если вы используете webpack и правильный загрузчик.
Шломи Ассаф
49

Следующее сработало для меня.

Сначала установите определения типа для момента.

typings install moment --save

(Примечание: НЕ --ambient )

Затем, чтобы обойти отсутствие надлежащего экспорта:

import * as moment from 'moment';
Stiggler
источник
2
Я должен был сделать import moment from "moment";вместо этого, чтобы заставить это работать.
Aetherix
3
Этот ответ неполон, потому что вам не нужно ничего импортировать. Пожалуйста, смотрите мой ответ ниже .
Бернардо Пачеко
1
Кроме того, каждая итерация ionic 2 beta / angular 2 rc, казалось, приносила новый способ импорта вещей, поэтому вам, возможно, придется попробовать некоторые из этих предложений, даже если в какой-то момент они когда-то были наиболее актуальным ответом
дискодан
import * as moment from 'moment';это ключ.
Нима
Я не могу найти «момент» («npm») в реестре. когда я пытаюсь установить определения, помогите пожалуйста
Себастьян Рохас
28

Я бы пошел со следующим:

npm install moment --save

К массиву вашего systemjs.config.jsфайла mapдобавьте:

'moment': 'node_modules/moment'

к packagesмассиву добавить:

'moment': { defaultExtension: 'js' }

В вашем component.ts используйте: import * as moment from 'moment/moment';

и это все. Вы можете использовать из класса вашего компонента:

today: string = moment().format('D MMM YYYY');

Aleksandras
источник
25

Мы используем модули сейчас,

пытаться import {MomentModule} from 'angular2-moment/moment.module';

после npm install angular2-moment

http://ngmodules.org/modules/angular2-moment

user6402762
источник
76
Этого недостаточно, потому что это только устанавливает трубы. По-видимому, вы не можете работать с датами Момента в ваших модулях таким образом.
ntaso
1
хотелось бы получить несколько советов о том, как использовать угловые2-моментные фильтры в классе компонентов
trickpatty
3
это должно быть: import {MomentModule} из 'angular2-moment / moment.module';
Ясир
1
Это не должно быть выбранным ответом больше. Посмотрите на ответ @Hinrich. npm install moment --save, npm install @types/moment --save stackoverflow.com/questions/35166168/…
jamesjansson
вместо того, чтобы устанавливать обертку это должно быть какimport * as moment from 'moment';
М. Атиф Риаз
22

Чтобы использовать его в Typescriptпроекте, вам нужно установить момент:

npm install moment --save

После установки вы можете использовать его в любом .tsфайле после его импорта:

import * as moment from "moment";

Шахзад
источник
1
Примечание ** @ types / moment @ 2.13.0: это определение типов заглушки для Moment ( github.com/moment/moment ). Moment предоставляет собственные определения типов, поэтому вам не нужно устанавливать @ types / moment!
Виннемукка
1
Большой! Вот официальная ссылка: momentjs.com/docs/#/use-it/typescript
Андреа
14

--- Обновление 01.11.2017

Typings устарела и была заменена на npm @types . Отныне для получения объявлений типов не требуется никаких инструментов, кроме npm. Чтобы использовать Moment, вам не нужно устанавливать определения типов через @types, потому что Moment уже предоставляет свои собственные определения типов.

Таким образом, он сокращается до 3 шагов:

1 - установить момент, который включает определения типа:

npm install moment --save

2 - Добавьте тег script в ваш HTML-файл:

<script src="node_modules/moment/moment.js" />

3 - Теперь вы можете просто использовать его. Период.

today: string = moment().format('D MMM YYYY');

--- Оригинальный ответ

Это можно сделать всего за 3 шага:

1 - Установить определение момента - файл * .d.ts :

typings install --save --global dt~moment dt~moment-node

2 - Добавьте тег script в ваш HTML-файл:

<script src="node_modules/moment/moment.js" />

3 - Теперь вы можете просто использовать его. Период.

today: string = moment().format('D MMM YYYY');
Бернардо Пачеко
источник
У меня проблемы с версией для печати, которая доступна на DT. Он использует старую версию момента, в которой нет новых методов, которые я хочу использовать. Если я делаю так, как они рекомендуют ( momentjs.com/docs/#/use-it/system-js ), приложение компилируется, но не загружается в браузер. Я почти зашел в тупик ...
Фабрисио
Я не смог заставить тег script работать с angular cli. Имеет больше смысла, чем импорт
Winnemucca
@ Бернардо Я попытался следовать вашим шагам и установил moment.js. После того declare var moment;, как набор текста не работает для меня. После ввода moment().нет смысла. Я предполагаю, что пропускаю несколько шагов здесь.
Шьямал Парих
Уверен, что это не сработает. Как веб-пакет знает, как включить его в модули узла сборки?
Джонни 5
12

Для угловых 7+ (поддержка 8 и 9 также) :

1: установить момент по команде npm install moment --save

2: не добавляйте ничего в app.module.ts

3: Просто добавьте оператор импорта в начало вашего componentили любого другого файла, подобного этому:import * as moment from 'moment';

4: Теперь вы можете использовать в momentлюбом месте вашего кода. Как:

myDate = moment(someDate).format('MM/DD/YYYY HH:mm');

Рахмат Али
источник
Я должен был импорт , как это: В import * as moment_ from 'moment'; const moment = moment_;противном случае я получаюError: Cannot call a namespace ('moment')
Снук
Очень странно слушать. moment_это просто буквальное имя. Это может быть что угодно, я думаю ...
Рахмат Али
1
Просто import * as moment from 'moment';учтите, что увеличьте размер пакета на ~ 500кб. Есть хорошая статья, объясняющая проблему с помощью решения medium.jonasbandi.net/…
Kosmonaft
9

с нг CLI

> npm install moment --save

в app.module

import * as moment from 'moment';

providers: [{ provide: 'moment', useValue: moment }]

в компоненте

constructor(@Inject('moment') private moment)

таким образом, вы импортируете момент один раз

ОБНОВЛЕНИЕ Angular => 5

{
   provide: 'moment', useFactory: (): any => moment
}

У меня работает в прод с аот а также с универсал

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

Error   Typescript  Type 'typeof moment' is not assignable to type 'Moment'. Property 'format' is missing in type 'typeof moment'.
Whisher
источник
Я получаю Parameter 'moment' implicitly has an 'any' typeошибку.
Азимут
Это работает для вас в режиме Prod? Он работал нормально в режиме разработки, но когда я запускаю свое приложение в режиме Prod, это не удается. Мое приложение имеет лениво загруженные модули тоже (на всякий случай, если это имеет значение). момент становится нулевым.
Jbgarr
@jbgarr Я пробовал в ленивом модуле, таком как конструктор (@Inject ('moment') частный момент) {console.log ('date', moment ()); } без проблем
Whisher
8

В библиотеке angular2-moment есть каналы типа {{myDate | amTimeAgo}} для использования в файлах .html.

К тем же каналам можно также получить доступ как к функциям Typescript в файле класса компонентов (.ts). Сначала установите библиотеку в соответствии с инструкциями:

npm install --save angular2-moment

В node_modules / angular2-moment теперь будут находиться файлы ".pipe.d.ts", такие как calendar.pipe.d.ts , date-format.pipe.d.ts и многие другие.

Каждый из них содержит имя функции Typescript для эквивалентного канала, например, DateFormatPipe () является функцией для amDateFormatPipe .

Чтобы использовать DateFormatPipe в вашем проекте, импортируйте и добавьте его к вашим глобальным провайдерам в app.module.ts:

import { DateFormatPipe } from "angular2-moment";
.....
providers: [{provide: ErrorHandler, useClass: IonicErrorHandler}, ...., DateFormatPipe]

Затем в любом компоненте, где вы хотите использовать функцию, импортируйте ее сверху, вставьте в конструктор и используйте:

import { DateFormatPipe } from "angular2-moment";
....
constructor(.......,  public dfp: DateFormatPipe) {
    let raw = new Date(2015, 1, 12);
    this.formattedDate = dfp.transform(raw, 'D MMM YYYY');
}

Чтобы использовать любую из функций, следуйте этому процессу. Было бы хорошо, если бы был один способ получить доступ ко всем функциям, но ни одно из перечисленных выше решений не помогло мне.

royappa
источник
Это потрясающе, спасибо! Везде для angular2 момент показывает вам, как использовать его только на шаблоне. Ваш очень полезный пост показал мне, как использовать его для манипулирования значением, прежде чем я выведу его в шаблон.
Эндрю Джуниор Говард
@royappa Я вижу, что некоторые используют модуль Pipes, а некоторые используют только мгновение для доступа к нему в Typescript. Я понимаю, что вы говорите, что можете использовать версию Pipes в Typescript, но какой вред это принесет при установке обоих?
Жак
5

Если вы можете добавить дополнительные сторонние пакеты, я использовал библиотеку angular2-moment . Установка была довольно простой, и вы должны следовать последним инструкциям на README. Я также установил набор текста в результате этого.

Работал для меня как шарм, и едва добавил какой-либо код, чтобы он заработал.

WLI
источник
5

Не уверен, если это все еще проблема для людей, однако ... Использование SystemJS и MomentJS в качестве библиотеки, это решило это для меня

/*
 * Import Custom Components
 */
import * as moment from 'moment/moment'; // please use path to moment.js file, extension is set in system.config

// under systemjs, moment is actually exported as the default export, so we account for that
const momentConstructor: (value?: any) => moment.Moment = (<any>moment).default || moment;

Работает хорошо оттуда для меня.

Астрид Карстен
источник
5

для angular2 RC5 у меня это работало ...

момент первой установки через npm

npm install moment --save

Затем импортируйте момент в компонент, который вы хотите использовать

import * as moment from 'moment';

наконец, настройте момент в systemjs.config.js "карта" и "пакеты"

// map tells the System loader where to look for things
  var map = {
  ....
  'moment':                     'node_modules/moment'
  };
  // packages tells the System loader how to load when no filename and/or no extension
  var packages = {
    ...
    'moment':                       { main:'moment', defaultExtension: 'js'}
  };
Арни Гуджонссон
источник
Любая идея о том, что эквивалентный шаг для веб-пакета?
Бхарат Геледа
@BharatGeleda Нет необходимости делать что-либо с веб-пакетом. Используя Angular2 и angular-cli, мне просто нужно было установить и импортировать npm. Мне не нужно было печатать, так как последняя версия момента поддерживает машинопись.
Stanislasdrg Восстановить Монику
1
Единственное решение, которое заставило меня импортировать другой язык: import 'moment/locale/de.js';Спасибо!
iBaff,
4

В дополнение к ответу SnareChop мне пришлось изменить файл для набора моментов.

В moment-node.d.tsя заменил:

export = moment;

с участием

export default moment;
joshin_my_tots
источник
4

Моя собственная версия использования Moment в Angular

npm i moment --save

import * as _moment from 'moment';

...

moment: _moment.Moment = _moment();

constructor() { }

ngOnInit() {

    const unix = this.moment.format('X');
    console.log(unix);    

}

Сначала импортируйте момент как _moment, затем объявите momentпеременную с типом _moment.Momentс начальным значением _moment().

Простой импорт момента не даст вам никакого автоматического завершения, но если вы объявите момент с типом Momentinterface из _momentпространства имен из 'moment'пакета, инициализированного вызванным пространством имен момента_moment() вы получите автоматическое завершение API моментов.

Я думаю, что это самый угловой способ использования момента без использования @types typingsпровайдеров или угловых провайдеров, если вы ищете автоматическое завершение для таких ванильных библиотек JavaScript, как момент.

Vadamadafaka
источник
Установка типов позволит вам получить доступ к автозаполнению:npm install @types/moment --save
jamesjansson
3

Попробуйте добавить "allowSyntheticDefaultImports": trueв свой tsconfig.json.

Что делает флаг?

Это в основном говорит компилятору TypeScript, что можно использовать оператор импорта ES6, т.е.

import * as moment from 'moment/moment';

в модуле CommonJS, таком как Moment.js, который не объявляет экспорт по умолчанию. Флаг влияет только на проверку типов, но не на сгенерированный код.

Это необходимо, если вы используете SystemJS в качестве загрузчика модулей. Флаг будет автоматически включен, если вы сообщите компилятору TS, что вы используете SystemJS:

"module": "system"

Это также удалит все ошибки, возникшие в IDE, если они настроены на использование tsconfig.json.

Марк Лангер
источник
2

для angular2 с systemjs и jspm пришлось сделать:

import * as moment_ from 'moment';
export const moment =  moment_["default"];

var a = moment.now();
var b = moment().format('dddd');
var c = moment().startOf('day').fromNow();
born2net
источник
2

Для пользователей ANGULAR CLI

Использование внешних библиотек находится в документации здесь:

https://github.com/angular/angular-cli/wiki/stories-third-party-lib

Просто установите вашу библиотеку через

npm установить lib-имя --save

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

npm установить lib-имя --save

npm install @ types / lib-name --save-dev

Затем откройте src / tsconfig.app.json и добавьте его в массив типов:

"types": ["lib-name"]

Если библиотека, для которой вы добавили наборы, должна использоваться только в ваших тестах e2e, вместо этого используйте e2e / tsconfig.e2e.json. То же самое касается модульных тестов и src / tsconfig.spec.json.

Если в библиотеке нет доступных типов в @ types /, вы все равно можете использовать ее, добавив для нее вручную:

Сначала создайте файл typings.d.ts в вашей папке src /.

Этот файл будет автоматически включен как определение глобального типа. Затем в файл src / typings.d.ts добавьте следующий код:

объявить модуль 'typeless-package';

Наконец, в компонент или файл, который использует библиотеку, добавьте следующий код:

импорт * как typelessPackage из 'typeless-package'; typelessPackage.method ();

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

Som
источник
Закажите эту статью, если вам нужны пошаговые инструкции. medium.com/@jek.bao.choo/...
wag0325
1

Я следовал совету разрешить allowSyntheticDefaultImports (поскольку у меня нет экспорта для использования в данный момент), используя System. Тогда я последовал чьему-то совету использовать:

import moment from 'moment';

С моментом сопоставления в моей конфигурации system.js. Другие операторы импорта по какой-то причине мне не подойдут

Пол Джером Бордалло
источник
Это последний ответ на данный момент, но единственный, который работает!
19
1

У меня сработало следующее:

typings install dt~moment-node --save --global

Момент-узел не существует в репозитории. Вам нужно перенаправить на Определенно Типизированный, чтобы заставить его работать, используя префикс dt.

stvnwrgs
источник
1

Что я сделал с systemjs, то внутри моего systemjs.config я добавил карту для moment

map: {
   .....,
   'moment': 'node_modules/moment/moment.js',
   .....
}

И тогда вы можете легко импортировать, momentпросто делая

import * as moment from 'moment'
Панкай Паркар
источник
1

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

  1. Установка его первой npm install moment --save
  2. В моих компонентах требуется это от node_modules и использовать его:
const moment = require('../../../node_modules/moment/moment.js');

@Component({...})
export class MyComponent {
   ...
   ngOnInit() {
       this.now = moment().format();
   }
   ...
}
Dehumanizer
источник