Como usar a biblioteca moment.js no aplicativo datilografado angular 2?

231

Eu tentei usá-lo com ligações datilografadas:

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

test.ts:

import {moment} from 'moment/moment';

E sem:

npm install moment --save

test.ts:

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

Mas quando eu chamo moment.format (), recebo um erro. Deve ser simples, alguém pode fornecer uma combinação de linha de comando / importação que funcione?

Sergey Aldoukhov
fonte
1
compartilhe seu erro, por favor
basarat
1
Se eu instalar moment.d.ts e usar import, eu recebo o erro de compilação ERROR em ... / typings / browser / ambient / moment / moment.d.ts (9,21): error TS2503: Não é possível localizar o namespace 'moment' . E se eu não instalar tipagens e utilização exigem, recebo Uncaught TypeError: moment.format não é uma função
Sergey Aldoukhov
Há muitas respostas antigas aqui. Por favor, olhe aqui: github.com/angular/angular-cli/wiki/…
Didia
3
A resposta de Hinrich funcionou para mim com Cg4 (em junho de 2017) stackoverflow.com/a/43257938/1554495
lombo
SergeyAldoukhov ainda é a melhor resposta? certamente @ Hinrich é?
evento do botão jenson

Respostas:

513

Atualização em abril de 2017:

A partir da versão 2.13.0, o Moment inclui um arquivo de definição de texto datilografado. https://momentjs.com/docs/#/use-it/typescript/

Basta instalá-lo com npm, no seu tipo de console

npm install --save moment

E então, no seu aplicativo Angular, a importação é tão fácil quanto isto:

import * as moment from 'moment';

É isso aí, você obtém suporte completo ao TypeScript!

Edição de bônus: Para digitar uma variável ou propriedade como Momentem Texto Dactilografado, você pode fazer isso, por exemplo:

let myMoment: moment.Moment = moment("someDate");
Hinrich
fonte
1
é importante adicioná-lo ao arquivo app.module e importar a matriz? ou você pode simplesmente importá-lo em um componente e usá-lo?
Katherine R #
3
@Katherine R Você pode usá-lo em qualquer arquivo, não é específico ao Angular.
Hinrich 27/02
Agora, e os plugins de momento, como o momento todo?
Greywire
2
Na verdade, essa resposta não é específica da Angular, ela se aplica a qualquer projeto do Typecript.
Hinrich
Ótimo, e como eu uso pipe no template?
vladanPro
98

momenté um recurso global de terceiros. O momento em que o objeto permanece no windownavegador. Portanto, ele não está correto importem seu aplicativo angular2. Em vez disso, inclua a <script>tag no seu html que carregará o arquivo moment.js.

Para deixar o TypeScript feliz, você pode adicionar

declare var moment: any;

na parte superior dos arquivos, onde você o utiliza para interromper os erros de compilação ou pode usar

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

ou use tsd para instalar o arquivo moment.d.ts que o TypeScript pode encontrar por si próprio.

Exemplo

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');
}

Apenas certifique-se de adicionar a tag de script no seu html ou o momento não existirá.

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

Carregamento do módulo moment

Primeiro, você precisa configurar um carregador de módulo como o System.js para carregar o momento em que os arquivos commonjs

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

Depois, importe o momento para o arquivo onde for necessário

import * as moment from 'moment';

ou

import moment = require('moment');

EDITAR:

Também existem opções com alguns pacotes configuráveis, como o construtor Webpack ou SystemJS ou o Browserify, que manterão o momento fora do objeto da janela. Para mais informações, visite os respectivos sites para obter instruções.

SnareChops
fonte
3
Isso é possível, mas é muito demorado, pois você precisaria ter um carregador de módulo, como Systemload na versão do momento do nó commonjs, e poderá referenciá-lo import * as moment from 'moment';ou com o import moment = require('moment');qual, para todos os efeitos, é idêntico, mas possui algumas diferenças sutis no texto datilografado.
SnareChops
@SnareChops typings install moment --ambient -- savenão abre typingso arquivo de definição e cria a referência ///<reference path="./path/to/moment.d.ts" />? Estou tendo o mesmo erro durante a execuçãonpm run tsc
Shawn Northrop
Isso é enganador; não há nada errado com o importmomento.
Stiggler
2
Esta resposta está incompleta porque você precisa usar Typings para gerenciar a definição do momento. Além disso, ele não precisa importar nada. Por favor, veja minha resposta abaixo .
Bernardo Pacheco
8
Essa resposta é enganosa, o fato de o momento ser uma variável global não significa que você "precise" carregá-lo como uma tag de script. Você pode e deve agrupá-lo em um arquivo de fornecedor se estiver usando algum tipo de empacotador (Webpack). Você também pode solucionar a atribuição global se usar o webpack e um carregador adequado.
Shlomi Assaf
49

O seguinte funcionou para mim.

Primeiro, instale as definições de tipo por um momento.

typings install moment --save

(Nota: NÃO --ambient)

Em seguida, para solucionar a falta de uma exportação adequada:

import * as moment from 'moment';
Stiggler
fonte
2
Em import moment from "moment";vez disso, tive que fazê -lo funcionar.
Aetherix
3
Esta resposta está incompleta porque você não precisa importar nada. Por favor, veja minha resposta abaixo .
Bernardo Pacheco
1
Além disso, todas as iterações do ionic 2 beta / angular 2 rc pareciam trazer uma nova maneira de importar as coisas, então você pode ter que tentar algumas dessas sugestões, mesmo que um ponto elas tenham sido as respostas mais atualizadas
discodane
import * as moment from 'moment';É a chave.
Nima
Não estou conseguindo encontrar "moment" ("npm") no registro. whenI tentativa para instalar definições, ajuda por favor
Sebastián Rojas
28

Eu iria com o seguinte:

npm install moment --save

Na matriz systemjs.config.jsdo seu arquivo, mapadicione:

'moment': 'node_modules/moment'

a packagesvariedade add:

'moment': { defaultExtension: 'js' }

No seu component.ts, use: import * as moment from 'moment/moment';

e é isso. Você pode usar da classe do seu componente:

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

Aleksandras
fonte
25

Estamos usando módulos agora,

experimentar import {MomentModule} from 'angular2-moment/moment.module';

depois de npm install angular2-moment

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

user6402762
fonte
76
Isso é insuficiente, porque isso instala apenas tubos. Aparentemente, você não pode trabalhar com datas do momento em seus módulos dessa maneira.
Ntso 12/10/16
1
adoraria algumas dicas sobre como usar filtros angular2-momento na classe de componente
trickpatty
3
deve ser: import {MomentModule} de 'angular2-moment / moment.module';
yasser
1
Esta não deve ser mais a resposta escolhida. Veja a resposta de @Hinrich. npm install moment --save, npm install @types/moment --save Stackoverflow.com/questions/35166168/...
jamesjansson
em vez de instalar um invólucro, deve ser como:import * as moment from 'moment';
M. Atif Riaz
22

Para usá-lo em um Typescriptprojeto, você precisará instalar o momento:

npm install moment --save

Após a instalação, você pode usá-lo em qualquer .tsarquivo após a importação:

import * as moment from "moment";

Shahzad
fonte
1
Nota ** @ types / moment @ 2.13.0: esta é uma definição de tipos de stub para Moment ( github.com/moment/moment ). O Moment fornece suas próprias definições de tipo, para que você não precise do @ types / moment instalado!
23417 Winnemucca
1
Ótimo! Aqui está a referência oficial: momentjs.com/docs/#/use-it/typescript #
Andrea Andrea
14

--- Atualização 11/01/2017

A digitação agora está obsoleta e foi substituída por npm @types . A partir de agora, obter declarações de tipo não exigirá ferramentas além do npm. Para usar o Moment, você não precisará instalar as definições de tipo por meio de @types porque o Moment já fornece suas próprias definições de tipo.

Portanto, reduz para apenas 3 etapas:

1 - Instale o momento que inclui as definições de tipo:

npm install moment --save

2 - Adicione a tag de script no seu arquivo HTML:

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

3 - Agora você pode apenas usá-lo. Período.

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

--- Resposta original

Isso pode ser feito em apenas 3 etapas:

1 - Instale a definição de momento - arquivo * .d.ts :

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

2 - Adicione a tag de script no seu arquivo HTML:

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

3 - Agora você pode apenas usá-lo. Período.

today: string = moment().format('D MMM YYYY');
Bernardo Pacheco
fonte
Estou tendo problemas com a versão de digitação disponível na dt. Ele está usando uma versão antiga do momento que não possui os novos métodos que quero usar. Se eu fizer o que é recomendado por eles ( momentjs.com/docs/#/use-it/system-js ), o aplicativo será compilado, mas não será carregado no navegador. Estou quase chegando a um beco sem saída ...
Fabricio
Não consegui que a tag do script funcionasse com o CLI angular. Faz mais sentido do que importar embora
Winnemucca
@Bernardo Tentei seguir os seus passos e instalei o moment.js. Depois declare var moment;No entanto, as digitações não estão funcionando para mim. Depois de digitar moment().nenhum intellisense. Acho que estou faltando alguns passos aqui.
Shyamal Parikh
Certamente isso não funciona, como o web pack sabe incluí-lo nos módulos do nó de construção?
5116
12

Para Angular 7+ (Suporta 8 e 9 também) :

1: Instale momento por comando npm install moment --save

2: Não adicione nada no app.module.ts

3: Basta adicionar a declaração de importação na parte superior da sua component ou de qualquer outro arquivo como este:import * as moment from 'moment';

4: Agora você pode usar momentqualquer lugar do seu código. Assim como:

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

Rahmat Ali
fonte
Eu tinha de importação assim: import * as moment_ from 'moment'; const moment = moment_;Caso contrário, eu estava ficandoError: Cannot call a namespace ('moment')
Snook
Muito estranho ouvir. moment_é apenas um nome literal. Pode ser qualquer coisa, eu acho ...
Rahmat Ali
1
Esteja ciente de que import * as moment from 'moment';aumente o tamanho do pacote em ~ 500kb. Existe um bom artigo explicando o problema com uma solução medium.jonasbandi.net/…
Kosmonaft
9

com ng CLI

> npm install moment --save

no app.module

import * as moment from 'moment';

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

no componente

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

Desta forma, você importa o momento uma vez

ATUALIZAÇÃO Angular => 5

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

Para mim trabalha em prod com aot e também com universal

Eu não gosto de usar nada além de moment.Moment

Error   Typescript  Type 'typeof moment' is not assignable to type 'Moment'. Property 'format' is missing in type 'typeof moment'.
Whisher
fonte
Eu recebo Parameter 'moment' implicitly has an 'any' typeerro.
Azimute
Isso funciona para você no modo prod? Estava funcionando bem no modo dev, mas quando executo meu aplicativo no modo prod, ele falha. Meu aplicativo também possui módulos carregados preguiçosamente (caso isso importe). o momento acaba sendo nulo.
Jbgarr #
@jbgarr Eu tentei em um módulo lento como o construtor (@Inject ('moment') private moment) {console.log ('date', moment ()); } sem problemas
Whisher
8

A biblioteca angular2-moment possui canais como {{myDate | amTimeAgo}} para usar em arquivos .html.

Esses mesmos pipes também podem ser acessados ​​como funções Typescript em um arquivo de classe de componente (.ts). Primeiro instale a biblioteca conforme as instruções:

npm install --save angular2-moment

No node_modules / angular2-moment, agora haverá arquivos ".pipe.d.ts", como calendar.pipe.d.ts , date-format.pipe.d.ts e muito mais.

Cada um deles contém o nome da função TypeScript para o canal equivalente, por exemplo, DateFormatPipe () é a função de amDateFormatPipe .

Para usar o DateFormatPipe no seu projeto, importe e adicione-o aos seus fornecedores globais em app.module.ts:

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

Em qualquer componente em que você deseja usar a função, importe-a por cima, injete no construtor e use:

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

Para usar qualquer uma das funções, siga este processo. Seria bom se houvesse uma maneira de obter acesso a todas as funções, mas nenhuma das soluções acima funcionou para mim.

royappa
fonte
Isso é incrível, obrigado! Em todos os lugares por um momento angular2 mostra como usá-lo apenas no modelo. Seu post muito útil me mostrou como usá-lo para manipular o valor antes de enviá-lo para o modelo.
Andrew Júnior Howard
@royappa Eu vejo alguns usando o módulo Pipes e outros usando apenas um momento para acessá-lo no Typescript. Entendo que você está dizendo que pode usar a versão Pipes no Typescript, mas qual seria o dano na instalação de ambos?
Jacques
5

Se você concorda em adicionar mais pacotes de terceiros, usei a biblioteca angular2-moment . A instalação foi bem simples e você deve seguir as instruções mais recentes no arquivo LEIA-ME. Eu também instalei digitações como resultado disso.

Funcionou como um encanto para mim e quase não adicionei nenhum código para fazê-lo funcionar.

wli
fonte
5

No entanto, não tenho certeza se isso ainda é um problema para as pessoas ... Usando o SystemJS e o MomentJS como biblioteca, isso resolveu para mim

/*
 * 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;

Funciona bem a partir daí para mim.

Astrid Karsten
fonte
5

para angular2 RC5 isso funcionou para mim ...

primeiro momento de instalação via npm

npm install moment --save

Em seguida, importe o momento no componente que você deseja usá-lo

import * as moment from 'moment';

Por fim, configure o momento em systemjs.config.js "map" e "packages"

// 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'}
  };
Arni Gudjonsson
fonte
Alguma idéia sobre qual é o passo equivalente para o webpack?
Bharat Geleda 9/09/16
@BharatGeleda Não há necessidade de fazer nada com o webpack. Usando Angular2 e angular-cli, eu apenas tive que instalar e importá-lo. Eu não precisava de nenhuma digitação, pois a última versão do momento suporta texto datilografado.
Stanislasdrg Restabelecer Monica
1
A única solução que me fez importar outro código de idioma: import 'moment/locale/de.js';Obrigado!
IBaff
4

Além da resposta do SnareChop, eu tive que alterar o arquivo de digitações para momentjs.

Em moment-node.d.tseu substituí:

export = moment;

com

export default moment;
joshin_my_tots
fonte
4

Minha própria versão do Moment in 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);    

}

Primeiro importe o momento como e _moment, em seguida, declare a momentvariável com o tipo _moment.Momentcom um valor inicial de _moment().

A importação simples de momento não fornecerá nenhuma conclusão automática, mas se você declarar momento com a Momentinterface de tipo do _momentnamespace do 'moment'pacote inicializado com o namespace do momento invocado_moment() a conclusão automática das APIs do momento.

Eu acho que essa é a maneira mais angular de usar o momento sem o uso @types typingsou provedores angulares, se você estiver procurando a conclusão automática de bibliotecas de javascript vanilla como momento.

Vadamadafaka
fonte
A instalação de tipos permitirá que você acesse o preenchimento automático:npm install @types/moment --save
jamesjansson
3

Tente adicionar "allowSyntheticDefaultImports": trueao seu tsconfig.json.

O que a bandeira faz?

Isso basicamente diz ao compilador TypeScript que não há problema em usar uma instrução de importação ES6, ou seja,

import * as moment from 'moment/moment';

em um módulo CommonJS como Moment.js, que não declara uma exportação padrão. O sinalizador afeta apenas a verificação de tipo, não o código gerado.

É necessário se você usar o SystemJS como seu carregador de módulos. O sinalizador será ativado automaticamente se você informar ao seu compilador TS que você usa o SystemJS:

"module": "system"

Isso também removerá quaisquer erros gerados pelos IDEs se eles estiverem configurados para fazer uso do tsconfig.json.

Mark Langer
fonte
2

para angular2 com systemjs e jspm tinha que fazer:

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
fonte
2

Para usuários CLI ANGULAR

O uso de bibliotecas externas está na documentação aqui:

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

Basta instalar sua biblioteca via

npm install lib-name --save

e importe-o no seu código. Se a biblioteca não incluir digitações, você poderá instalá-las usando:

npm install lib-name --save

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

Em seguida, abra src / tsconfig.app.json e adicione-o à matriz de tipos:

"types": ["lib-name"]

Se a biblioteca para a qual você adicionou digitações for usada apenas nos testes do e2e, use e2e / tsconfig.e2e.json. O mesmo vale para testes de unidade e src / tsconfig.spec.json.

Se a biblioteca não tiver letras disponíveis em @ types /, você ainda poderá usá-las adicionando manualmente letras para ela:

Primeiro, crie um arquivo typings.d.ts na sua pasta src /.

Este arquivo será automaticamente incluído como definição de tipo global. Em src / typings.d.ts, adicione o seguinte código:

declarar o módulo 'typeless-package';

Por fim, no componente ou arquivo que usa a biblioteca, adicione o seguinte código:

import * as typelessPackage from 'typeless-package'; typelessPackage.method ();

Feito. Nota: você pode precisar ou achar útil definir mais fontes para a biblioteca que você está tentando usar.

Som
fonte
Confira este artigo se precisar de instruções passo a passo. medium.com/@jek.bao.choo/…
wag0325
1

Segui o conselho para permitir allowSyntheticDefaultImports (já que não há exportação do momento para usar para mim), usando o System. Então eu segui o conselho de alguém para usar:

import moment from 'moment';

Com o momento sendo mapeado na minha configuração system.js. As outras instruções de importação não funcionariam para mim, por algum motivo

Paul Jerome Bordallo
fonte
Esta é a última resposta agora, mas a única que está funcionando!
TJL
1

O seguinte funcionou para mim:

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

O momento-nó não existe no repositório de digitações. Você precisa redirecionar para Definitely Type, para fazê-lo funcionar usando o prefixo dt.

stvnwrgs
fonte
1

Com systemjs, o que eu fiz é que, dentro do meu systemjs.config, adicionei o mapa para moment

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

E então você pode importar facilmente momentapenas fazendo

import * as moment from 'moment'
Pankaj Parkar
fonte
1

Eu sei que é um tópico antigo, mas para mim a solução mais simples que realmente funcionou foi:

  1. Instalando primeiro npm install moment --save
  2. Nos meus componentes que exigem do node_modules e use-o:
const moment = require('../../../node_modules/moment/moment.js');

@Component({...})
export class MyComponent {
   ...
   ngOnInit() {
       this.now = moment().format();
   }
   ...
}
desumanizador
fonte