¿Cómo usar la biblioteca moment.js en la aplicación de mecanografía angular 2?

231

Traté de usarlo con enlaces de tipografía:

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

test.ts:

import {moment} from 'moment/moment';

Y sin:

npm install moment --save

test.ts:

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

Pero cuando llamo a moment.format (), recibo un error. Debería ser simple, ¿alguien puede proporcionar una combinación de línea de comando / importación que funcione?

Sergey Aldoukhov
fuente
1
comparte tu error por favor
basarat
1
Si instalo moment.d.ts y uso import, obtengo el error de compilación ERROR en ... / typings / browser / ambient / moment / moment.d.ts (9,21): error TS2503: No puedo encontrar el espacio de nombres 'moment' . Y si no instalo tipings y uso require, me sale Uncaught TypeError: moment.format no es una función
Sergey Aldoukhov
Hay demasiadas respuestas antiguas aquí. Mire aquí: github.com/angular/angular-cli/wiki/…
Didia
3
La respuesta de Hinrich funcionó para mí con ng4 (a partir de junio de 2017) stackoverflow.com/a/43257938/1554495
lomo
SergeyAldoukhov ¿sigue siendo la mejor respuesta? seguramente @ Hinrich's es?
jenson-button-event

Respuestas:

513

Actualización de abril de 2017:

A partir de la versión 2.13.0, Moment incluye un archivo de definición de mecanografiado. https://momentjs.com/docs/#/use-it/typescript/

Simplemente instálelo con npm, en su tipo de consola

npm install --save moment

Y luego, en su aplicación Angular, importar es tan fácil como esto:

import * as moment from 'moment';

Eso es todo, ¡obtienes soporte completo de Typecript!

Edición de bonificación: para escribir una variable o propiedad como Momenten Typecript, puede hacer esto, por ejemplo:

let myMoment: moment.Moment = moment("someDate");
Hinrich
fuente
1
¿Es importante agregarlo al archivo app.module e importar la matriz? o simplemente puede importarlo dentro de un componente y usarlo?
Katherine R
3
@Katherine R Puede usarlo en cualquier archivo, no es específico de Angular.
Hinrich
Ahora, ¿qué pasa con los complementos de momento, como momento redondo?
Greywire
2
En realidad, esta respuesta no es específica de Angular, se aplica a cualquier proyecto mecanografiado.
Hinrich
Genial, y ¿cómo uso la tubería en la plantilla?
vladanPro
98

momentes un recurso global de terceros. El momento en que el objeto vive windowen el navegador. Por lo tanto, no es correcto importen su aplicación angular2. En cambio, incluya el<script> etiqueta en su html que cargará el archivo moment.js.

Para hacer feliz a TypeScript, puede agregar

declare var moment: any;

en la parte superior de sus archivos donde lo usa para detener los errores de compilación, o puede usar

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

o use tsd para instalar el archivo moment.d.ts que TypeScript podría encontrar por sí mismo.

Ejemplo

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

Solo asegúrese de agregar la etiqueta de script en su html o el momento no existirá.

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

Módulo de carga moment

Primero, necesitaría configurar un cargador de módulos como System.js para cargar los archivos commonjs del momento

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

Luego, para importar el momento en el archivo donde sea necesario, use

import * as moment from 'moment';

o

import moment = require('moment');

EDITAR:

También hay opciones con algunos paquetes como Webpack o SystemJS Builder o Browserify que mantendrán el momento alejado del objeto de la ventana. Para obtener más información sobre estos, visite sus respectivos sitios web para obtener instrucciones.

SnareChops
fuente
3
Eso es posible, pero es muy largo, ya que necesitaría tener un cargador de módulos como Systemcargar en la versión de momento del nodo commonjs y luego podría hacer referencia a él import * as moment from 'moment';o con el import moment = require('moment');que para todos los intentos y propósitos son idénticos, pero tienen algunas diferencias sutiles en mecanografiado.
SnareChops
@SnareChops typings install moment --ambient -- saveno despliega typingsel archivo de definición y crea la referencia a ///<reference path="./path/to/moment.d.ts" />? Tengo el mismo error cuando ejecutonpm run tsc
Shawn Northrop
Esto es engañoso; No hay nada malo con el importmomento.
Stiggler
2
Esta respuesta está incompleta porque debe usar Typings para administrar la definición del momento. Además, no necesita importar nada. Por favor, mira mi respuesta a continuación .
Bernardo Pacheco
8
Esta respuesta es engañosa, el hecho de que el momento sea una variable global no significa que "tenga" que cargarla como una etiqueta de script. Puede y debe agruparlo en un archivo de proveedor si está utilizando algún tipo de agrupador (Webpack). También puede solucionar la asignación global si utiliza webpack y un cargador adecuado.
Shlomi Assaf
49

Lo siguiente funcionó para mí.

Primero, instale las definiciones de tipo por el momento.

typings install moment --save

(Nota: NO --ambient )

Luego, para evitar la falta de una exportación adecuada:

import * as moment from 'moment';
Stiggler
fuente
2
Tuve que hacer en su import moment from "moment";lugar para que funcione.
Aetherix
3
Esta respuesta está incompleta porque no necesita importar nada. Por favor, mira mi respuesta a continuación .
Bernardo Pacheco
1
Además, cada iteración de ionic 2 beta / angular 2 rc parecía traer una nueva forma de importar cosas, por lo que es posible que tenga que probar algunas de estas sugerencias, aunque en un momento fueron la respuesta más actualizada
discodane
import * as moment from 'moment';es la llave.
nima
No puedo encontrar el "momento" ("npm") en el registro. cuando intento instalar definiciones, ayuda por favor
Sebastián Rojas
28

Yo iría con lo siguiente:

npm install moment --save

A systemjs.config.jsla mapmatriz de su archivo agregue:

'moment': 'node_modules/moment'

para packagesagregar matriz:

'moment': { defaultExtension: 'js' }

En su component.ts use: import * as moment from 'moment/moment';

y eso es. Puede usar desde la clase de su componente:

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

Aleksandras
fuente
25

Estamos usando módulos ahora,

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

después npm install angular2-moment

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

usuario6402762
fuente
76
Esto es insuficiente, porque esto solo instala tuberías. Aparentemente, no puede trabajar con fechas Moment en sus módulos de esta manera.
ntaso
1
me encantaría algunos consejos sobre cómo utilizar filtros angular2-momento en la clase del componente
trickpatty
3
esto debería ser: import {MomentModule} desde 'angular2-moment / moment.module';
yasser
1
Esta ya no debería ser la respuesta elegida. Echa un vistazo a la respuesta de @Hinrich. npm install moment --save, npm install @types/moment --save stackoverflow.com/questions/35166168/…
jamesjansson
en lugar de instalar un contenedor debería ser comoimport * as moment from 'moment';
M. Atif Riaz
22

Para usarlo en un Typescriptproyecto necesitará instalar moment:

npm install moment --save

Después de instalar el momento, puede usarlo en cualquier .tsarchivo después de importarlo:

import * as moment from "moment";

Shahzad
fuente
1
Nota ** @ types / moment @ 2.13.0: Esta es una definición de tipos de stub para Moment ( github.com/moment/moment ). Momento proporciona sus propias definiciones de tipo, por lo que no necesita @ tipos / momento instalados
Winnemucca
1
¡Excelente! Aquí la referencia oficial: momentjs.com/docs/#/use-it/typescript
Andrea
14

--- Actualización 11/01/2017

Typings ahora está en desuso y fue reemplazado por npm @types . A partir de ahora, obtener declaraciones de tipo no requerirá herramientas aparte de npm. Para usar Moment no necesitará instalar las definiciones de tipo a través de @types porque Moment ya proporciona sus propias definiciones de tipo.

Por lo tanto, se reduce a solo 3 pasos:

1 - Instalar momento que incluye las definiciones de tipo:

npm install moment --save

2 - Agregue la etiqueta de script en su archivo HTML:

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

3 - Ahora puedes usarlo. Período.

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

--- Respuesta original

Esto se puede hacer en solo 3 pasos:

1 - Instalar definición de momento - archivo * .d.ts :

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

2 - Agregue la etiqueta de script en su archivo HTML:

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

3 - Ahora puedes usarlo. Período.

today: string = moment().format('D MMM YYYY');
Bernardo Pacheco
fuente
Tengo problemas con la versión de tipings que está disponible en dt. Está usando una versión antigua del momento que no tiene los nuevos métodos que quiero usar. Si hago lo que me recomiendan ( momentjs.com/docs/#/use-it/system-js ) la aplicación se compila, pero no se carga en el navegador. Casi estoy llegando a un callejón sin salida ...
Fabricio
No pude hacer que la etiqueta del script funcione con cli angular. Sin embargo
Winnemucca el
@ Bernardo Intenté seguir tus pasos e instalé moment.js. Después declare var moment;Sin embargo, tipificaciones no funciona para mí. Después de escribir moment().no intellisense. Supongo que me faltan algunos pasos aquí.
Shyamal Parikh
Bastante seguro de que esto no funciona, ¿cómo sabe el paquete web incluir esto en los módulos de nodo de compilación?
johnny 5
12

Para Angular 7+ (también admite 8 y 9) :

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

2: No agregue nada en el app.module.ts

3: Simplemente agregue la declaración de importación en la parte superior de su componentarchivo o cualquier otro como este:import * as moment from 'moment';

4: Ahora puede usarlo momenten cualquier parte de su código. Al igual que:

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

Rahmat Ali
fuente
Tuve que importar de esta manera: de lo import * as moment_ from 'moment'; const moment = moment_;contrario estaba obteniendoError: Cannot call a namespace ('moment')
Snook
Muy extraño escucharlo. moment_Es solo un nombre literal. Puede ser cualquier cosa, creo ...
Rahmat Ali
1
Solo tenga en cuenta que import * as moment from 'moment';aumenta el tamaño del paquete en ~ 500kb. Hay un buen artículo que explica el problema con una solución medium.jonasbandi.net/…
Kosmonaft
9

con ng CLI

> npm install moment --save

en app.module

import * as moment from 'moment';

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

en componente

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

así importas momento una vez

ACTUALIZACIÓN Angular => 5

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

Para mí trabaja en prod con aot y también con universal

No me gusta usar ninguno, pero usar momento. Momento que obtuve

Error   Typescript  Type 'typeof moment' is not assignable to type 'Moment'. Property 'format' is missing in type 'typeof moment'.
Whisher
fuente
Me sale un Parameter 'moment' implicitly has an 'any' typeerror
Azimuth
¿Funciona esto en modo prod? Funcionaba bien en modo dev, pero cuando ejecuto mi aplicación en modo prod falla. Mi aplicación también tiene módulos cargados de forma diferida (en caso de que eso importe). momento termina siendo nulo.
jbgarr
@jbgarr Lo he intentado en un módulo perezoso como constructor (@Inject ('moment') private moment) {console.log ('date', moment ()); } sin problemas
Whisher
8

La biblioteca angular2-moment tiene tuberías como {{myDate | amTimeAgo}} para usar en archivos .html.

También se puede acceder a esas mismas canalizaciones como funciones de mecanografía dentro de un archivo de clase de componente (.ts). Primero instale la biblioteca como se indica:

npm install --save angular2-moment

En node_modules / angular2-moment ahora habrá archivos ".pipe.d.ts" como calendar.pipe.d.ts , date-format.pipe.d.ts y muchos más.

Cada uno de ellos contiene el nombre de la función de mecanografía para la tubería equivalente, por ejemplo, DateFormatPipe () es la función para amDateFormatPipe .

Para usar DateFormatPipe en su proyecto, impórtelo y agréguelo a sus proveedores globales en app.module.ts:

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

Luego, en cualquier componente donde desee utilizar la función, impórtelo en la parte superior, inyecte en el constructor y 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 cualquiera de las funciones, siga este proceso. Sería bueno si hubiera una forma de obtener acceso a todas las funciones, pero ninguna de las soluciones anteriores funcionó para mí.

royappa
fuente
Esto es genial, gracias! En todas partes, para el momento angular2, se muestra cómo usarlo solo en la plantilla. Su publicación muy útil me mostró cómo usarlo para manipular el valor antes de enviarlo a la plantilla.
Andrew Junior Howard
@royappa Veo que algunos usan el módulo Pipes y otros que usan solo un momento para acceder a ellos en Typecript. Entiendo que estás diciendo que puedes usar la versión de Tuberías en Typecript, pero ¿cuál sería el daño al instalar ambas?
Jacques
5

Si está de acuerdo en agregar más paquetes de terceros, utilicé la biblioteca angular2-moment . La instalación fue bastante sencilla, y debe seguir las últimas instrucciones en el archivo README. También instalé tipings como resultado de esto.

Funcionó como un encanto para mí, y apenas agregué ningún código para que funcione.

wli
fuente
5

Sin embargo, no estoy seguro de si esto sigue siendo un problema para las personas ... Al usar SystemJS y MomentJS como biblioteca, esto me resolvió

/*
 * 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 bien desde allí para mí.

Astrid Karsten
fuente
5

para angular2 RC5 esto funcionó para mí ...

primer momento de instalación a través de npm

npm install moment --save

Luego importe el momento en el componente que desea usar

import * as moment from 'moment';

finalmente configure el momento en systemjs.config.js "mapa" y "paquetes"

// 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
fuente
¿Alguna idea sobre cuál es el paso equivalente para webpack?
Bharat Geleda
@BharatGeleda No es necesario hacer nada con webpack. Usando Angular2 y angular-cli solo tuve que instalar e importar npm. No necesitaba ninguna tipificación ya que la última versión de moment admite mecanografiado.
Stanislasdrg Restablece a Mónica el
1
La única solución que me hizo importar otra ubicación: import 'moment/locale/de.js';¡Gracias!
iBaff
4

Además de la respuesta de SnareChop, tuve que cambiar el archivo de tipificación por momentos.

En moment-node.d.tsreemplacé:

export = moment;

con

export default moment;
joshin_my_tots
fuente
4

Mi propia versión de usar 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);    

}

Primero importa el momento como _moment, luego declara la momentvariable con tipo _moment.Momentcon un valor inicial de _moment().

La importación simple del momento no le dará ninguna finalización automática, pero si declara el momento con la Momentinterfaz de tipo desde el _momentespacio de nombres desde el 'moment'paquete inicializado con el espacio de nombres de momento invocado_moment() le dará la finalización automática de la API del momento.

Creo que esta es la forma más angular de usar moment sin usar @types typingso proveedores angulares, si está buscando la finalización automática de bibliotecas javascript de vainilla como moment.

Vadamadafaka
fuente
La instalación de tipos le permitirá acceder al autocompletado:npm install @types/moment --save
jamesjansson
3

Intenta agregar "allowSyntheticDefaultImports": truea tutsconfig.json .

¿Qué hace la bandera?

Básicamente, esto le dice al compilador TypeScript que está bien usar una declaración de importación ES6, es decir

import * as moment from 'moment/moment';

en un módulo CommonJS como Moment.js que no declara una exportación predeterminada. La bandera solo afecta la verificación de tipo, no el código generado.

Es necesario si usa SystemJS como su cargador de módulos. El indicador se activará automáticamente si le dice a su compilador de TS que usa SystemJS:

"module": "system"

Esto también eliminará cualquier error que arrojen los IDE si están configurados para utilizar el tsconfig.json.

Mark Langer
fuente
2

para angular2 con systemjs y jspm tenía que hacer:

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

Para usuarios de CLI ANGULAR

El uso de bibliotecas externas se encuentra en la documentación aquí:

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

Simplemente instale su biblioteca a través de

npm install lib-name --save

e impórtalo en tu código. Si la biblioteca no incluye tipings, puede instalarlos usando:

npm install lib-name --save

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

Luego abra src / tsconfig.app.json y agréguelo a la matriz de tipos:

"tipos": ["nombre-lib"]

Si la biblioteca para la que agregó tipings solo se utilizará en sus pruebas de e2e, utilice e2e / tsconfig.e2e.json. Lo mismo ocurre con las pruebas unitarias y src / tsconfig.spec.json.

Si la biblioteca no tiene tipings disponibles en @ types /, aún puede usarla agregando manualmente tipings para ella:

Primero, cree un archivo typings.d.ts en su carpeta src /.

Este archivo se incluirá automáticamente como definición de tipo global. Luego, en src / typings.d.ts, agregue el siguiente código:

declara el módulo 'typeless-package';

Finalmente, en el componente o archivo que usa la biblioteca, agregue el siguiente código:

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

Hecho. Nota: es posible que necesite o le resulte útil definir más tipificaciones para la biblioteca que está intentando usar.

Som
fuente
Consulte este artículo si necesita instrucciones paso a paso. medium.com/@jek.bao.choo/…
wag0325
1

Seguí los consejos para permitir allowSyntheticDefaultImports (ya que no hay exportación de momento para usar), usando System. Luego seguí el consejo de alguien para usar:

import moment from 'moment';

Con el momento asignado en mi configuración system.js. Las otras declaraciones de importación no funcionarían para mí, por alguna razón

Paul Jerome Bordallo
fuente
Esta es la última respuesta en este momento, ¡pero la única que funciona!
TJL
1

Lo siguiente funcionó para mí:

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

El nodo de momento no existe en el repositorio de tipings. Debe redirigir a Definitely Typed para que funcione con el prefijo dt.

stvnwrgs
fuente
1

Con systemjs lo que hice es, dentro de mi systemjs.config agregué mapa para moment

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

Y luego puede importar fácilmente momentsimplemente haciendo

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

Sé que es un hilo viejo, pero para mí la solución más simple que realmente funcionó fue:

  1. Instalarlo primero npm install moment --save
  2. En mis componentes que lo requieren de node_modules y lo uso:
const moment = require('../../../node_modules/moment/moment.js');

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