如何在 Angular 2 typescript 应用程序中使用 moment.js 库?

Posted

技术标签:

【中文标题】如何在 Angular 2 typescript 应用程序中使用 moment.js 库?【英文标题】:How to use moment.js library in angular 2 typescript app? 【发布时间】:2016-05-12 00:11:05 【问题描述】:

我尝试将它与打字稿绑定一起使用:

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() 时,我得到一个错误。 应该很简单,任何人都可以提供一个可行的命令行/导入组合吗?

【问题讨论】:

请分享您的错误 如果我安装 moment.d.ts 并使用 import,我会在 .../typings/browser/ambient/moment/moment.d.ts (9,21) 中收到编译错误 ERROR:错误TS2503:找不到命名空间“时刻”。如果我不安装类型和使用要求,我会得到 Uncaught TypeError: moment.format is not a function 这里的旧答案太多了。请看这里:github.com/angular/angular-cli/wiki/… Hinrich 的回答对我有用 ng4(截至 2017 年 6 月)***.com/a/43257938/1554495 SergeyAldoukhov 这仍然是最好的答案吗? @Hinrich 肯定是? 【参考方案1】:

2017 年 4 月更新:

从 2.13.0 版开始,Moment 包含一个打字稿定义文件。 https://momentjs.com/docs/#/use-it/typescript/

只需在控制台类型中使用 npm 安装它

npm install --save moment

然后在您的 Angular 应用程序中,导入就像这样简单:

import * as moment from 'moment';

就是这样,您将获得完整的 Typescript 支持!

额外编辑:要在 Typescript 中将变量或属性键入为 Moment,您可以这样做,例如:

let myMoment: moment.Moment = moment("someDate");

【讨论】:

将它添加到您的 app.module 文件并导入数组是否重要?或者你可以简单地在一个组件中导入它并使用它? @Katherine R 你可以在任何文件中使用它,它不是 Angular 特定的。 现在,像moment-round这样的moment插件呢? 其实这个答案不是 Angular 特定的,它适用于任何 Typescript 项目。 太好了,我如何在模板上使用管道?【参考方案2】:

moment 是第三方全球资源。 moment 对象位于浏览器中的 window 上。因此,在您的 angular2 应用程序中 import 它是不正确的。而是在您的 html 中包含 <script> 标记,该标记将加载 moment.js 文件。

为了让 TypeScript 满意,您可以添加

declare var moment: any;

在您使用它来停止编译错误的文件顶部,或者您可以使用

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

或使用 tsd 安装 TypeScript 可能自行找到的 moment.d.ts 文件。

示例

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

请务必在您的 html 中添加 script 标签,否则moment 将不存在。

<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,它们将保持窗口对象的时间。有关这些的更多信息,请访问它们各自的网站以获取说明。

【讨论】:

这是可能的,但是非常冗长,因为您需要在 commonjs 节点版本的 moment 中加载诸如 System 之类的模块加载器,然后您就可以使用 @987654335 引用它@ 或 import moment = require('moment'); 在所有意图和目的上都是相同的,但在打字稿上确实有一些细微的差别。 @SnareChops typings install moment --ambient -- savetypings 下拉定义文件并创建对 ///&lt;reference path="./path/to/moment.d.ts" /&gt; 的引用?运行 npm run tsc 时我遇到了同样的错误 这是误导; importing 时刻没有任何问题。 此答案不完整,因为您必须使用 Typings 来管理时刻定义。此外,它不需要导入任何东西。请参阅my answer bellow。 这个答案具有误导性,时刻是一个全局变量这一事实并不意味着您“必须”将它作为脚本标签加载。如果您使用某种捆绑器(Webpack),您可以并且应该将其捆绑到供应商文件中。如果您使用 webpack 和适当的加载器,您也可以解决全局分配问题。【参考方案3】:

以下内容对我有用。

首先,暂时安装类型定义。

typings install moment --save

(注意:不是--ambient

然后,解决缺少正确导出的问题:

import * as moment from 'moment';

【讨论】:

我不得不这样做 import moment from "moment"; 来让它工作。 此答案不完整,因为您不需要导入任何内容。请参阅my answer bellow。 此外,ionic 2 beta / angular 2 rc 的每次迭代似乎都带来了一种新的导入方式,因此您可能不得不尝试其中的一些建议,即使它们曾经是最热门的迄今为止的答案 import * as moment from 'moment'; 是关键。 我无法在注册表中找到“moment”(“npm”)。当我尝试安装定义时,请帮助【参考方案4】:

我会选择以下内容:

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

【讨论】:

【参考方案5】:

我们现在正在使用模块,

试试import MomentModule from 'angular2-moment/moment.module';

npm install angular2-moment之后

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

【讨论】:

这是不够的,因为这只是安装管道。显然,您不能以这种方式在模块中使用 Moment 日期。 希望得到一些关于如何在组件类中使用 angular2-moment 过滤器的提示 这应该是: import MomentModule from 'angular2-moment/moment.module'; 这不应该是选择的答案了。看看@Hinrich 的回答。 npm install moment --save, npm install @types/moment --save ***.com/questions/35166168/… 而不是安装包装器应该像import * as moment from 'moment';【参考方案6】:

要在Typescript 项目中使用它,您需要安装moment:

npm install moment --save

安装moment后,导入后可以在任意.ts文件中使用:

import * as moment from "moment";

【讨论】:

注意** @types/moment@2.13.0:这是 Moment (github.com/moment/moment) 的存根类型定义。 Moment 提供了自己的类型定义,因此您不需要安装 @types/moment! 太棒了!这里官方参考:momentjs.com/docs/#/use-it/typescript【参考方案7】:

对于 Angular 7+(也支持 8、9、10、11)

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_ 只是一个字面名称。它可以是任何东西,我认为...... 请注意 import * as moment from 'moment'; 将包的大小增加了 ~500kb。有一篇很好的文章解释了这个问题的解决方案medium.jonasbandi.net/…【参考方案8】:

--- 2017 年 11 月 1 日更新

Typings 现已弃用,并由 npm @types 取代。从现在开始,除了 npm 之外,获取类型声明将不需要任何工具。要使用 Moment,您无需通过 @types 安装类型定义,因为 Moment 已经提供了自己的类型定义。

所以,它减少到只有 3 个步骤:

1 - 包含类型定义的安装时刻:

npm install moment --save

2 - 在您的 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 - 在您的 HTML 文件中添加脚本标签:

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

3 - 现在你可以使用它了。期间。

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

【讨论】:

我在使用 dt 提供的打字版本时遇到问题。它使用的是旧版本的时刻,没有我想使用的新方法。如果我按照他们的建议 (momentjs.com/docs/#/use-it/system-js) 进行操作,则应用程序会编译,但不会加载到浏览器中。我快走到死胡同了…… 我无法让脚本标签与 Angular cli 一起使用。虽然比导入更有意义 @Bernardo 我尝试按照您的步骤安装moment.js。在declare var moment; 之后,打字对我不起作用。输入moment(). 后没有智能感知。我想我在这里遗漏了几个步骤。 很确定这不起作用,webpack 怎么知道将其包含在构建节点模块中?【参考方案9】:

使用 ng 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

对我来说,与 aot 一起工作 还有通用的

我不喜欢使用任何东西,但使用 moment.Moment 我得到了

Error   Typescript  Type 'typeof moment' is not assignable to type 'Moment'. Property 'format' is missing in type 'typeof moment'.

【讨论】:

我收到Parameter 'moment' implicitly has an 'any' type 错误。 这在 prod 模式下对您有用吗?它在开发模式下工作正常,但是当我在生产模式下运行我的应用程序时它失败了。我的应用程序也有延迟加载的模块(以防万一)。时刻最终为空。 @jbgarr 我已经尝试过像构造函数这样的惰性模块(@Inject('moment') private moment) console.log('date', moment()); 没有问题【参考方案10】:

angular2-moment 库有像 myDate | amTimeAgo 在 .html 文件中使用。

同样的管道也可以作为组件类 (.ts) 文件中的 Typescript 函数进行访问。首先按照说明安装库:

npm install --save angular2-moment

在 node_modules/angular2-moment 中现在将是“.pipe.d.ts”文件,例如 calendar.pipe.d.tsdate-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');

要使用任何功能,请遵循此过程。如果有一种方法可以访问所有功能,那就太好了,但上述解决方案都不适合我。

【讨论】:

这太棒了,谢谢! Everywhere for angular2 moment 向您展示如何仅在模板上使用它。您非常有用的帖子向我展示了如何在将值输出到模板之前使用它来操作值。 @royappa 我看到有些人使用 Pipes 模块,有些人只是在 Typescript 中使用它。我了解您的意思是您可以在 Typescript 中使用 Pipes 版本,但同时安装这两个版本会有什么危害?【参考方案11】:

如果您可以添加更多第三方软件包,我使用了angular2-moment 库。安装非常简单,您应该按照自述文件中的最新说明进行操作。因此,我还安装了typings。

对我来说就像一个魅力,几乎没有添加任何代码来让它工作。

【讨论】:

【参考方案12】:

不确定这是否仍然是人们的问题,但是...使用 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;

从那里对我来说效果很好。

【讨论】:

【参考方案13】:

对于 angular2 RC5,这对我有用...

通过 npm 首次安装时刻

npm install moment --save

然后在要使用的组件中导入moment

import * as moment from 'moment';

最后在systemjs.config.js“map”和“packages”中配置moment

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

【讨论】:

知道 webpack 的等效步骤是什么吗? @BharatGeleda 不需要对 webpack 做任何事情。使用 Angular2 和 angular-cli 我只需要 npm install 并导入它。我不需要任何打字,因为 moment 的最后一个版本支持打字稿。 唯一让我导入另一个语言环境的解决方案:import 'moment/locale/de.js'; 谢谢!【参考方案14】:

除了 SnareChop 的回答之外,我还必须更改 momentjs 的类型文件。

moment-node.d.ts我换成了:

export = moment;

export default moment;

【讨论】:

【参考方案15】:

Moment.js 现在在 v2.14.1 中支持 TypeScript。

见:https://github.com/moment/moment/pull/3280

【讨论】:

【参考方案16】:

我自己在 Angular 中使用 Moment 的版本

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()

moment 的普通导入不会给你任何自动完成,但如果你将声明类型为 Moment 接口的时刻来自 _moment 命名空间来自 'moment' 包初始化并调用时刻命名空间 _moment() 给你自动完成时刻的 api .

如果您正在寻找像 moment 这样的 vanilla javascript 库的自动完成功能,我认为这是不使用 @types typings 或角度提供程序的最有角度的使用方式。

【讨论】:

安装类型将允许您访问自动完成功能:npm install @types/moment --save【参考方案17】:

尝试将"allowSyntheticDefaultImports": true 添加到您的tsconfig.json

标志有什么作用?

这基本上告诉 TypeScript 编译器可以使用 ES6 导入语句,即。 e.

import * as moment from 'moment/moment';

在像 Moment.js 这样没有声明默认导出的 CommonJS 模块上。该标志只影响类型检查,不影响生成的代码。

如果你使用 SystemJS 作为你的模块加载器,这是必要的。如果您告诉 TS 编译器您使用 SystemJS,该标志将自动打开:

"module": "system"

如果 IDE 被配置为使用 tsconfig.json,这也将消除 IDE 引发的任何错误。

【讨论】:

【参考方案18】:

以下内容对我有用:

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

类型存储库中不存在矩节点。您需要重定向到“绝对类型”才能使用前缀 dt 使其工作。

【讨论】:

【参考方案19】:

对于带有 systemjs 和 jspm 的 angular2 必须这样做:

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();

【讨论】:

【参考方案20】:

对于 ANGULAR CLI 用户

使用外部库在此处的文档中:

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

只需通过

安装您的库

npm install lib-name --save

并将其导入您的代码中。如果库不包含类型, 您可以使用以下方式安装它们:

npm install lib-name --save

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

然后打开 src/tsconfig.app.json 并将其添加到 types 数组中:

“类型”:[“库名称”]

如果您为其添加类型的库仅用于您的 e2e 测试,而是使用 e2e/tsconfig.e2e.json。单元测试也是如此 和 src/tsconfig.spec.json。

如果库在 @types/ 上没有可用的类型,您可以 仍然通过手动添加类型来使用它:

首先,在您的 src/ 文件夹中创建一个 typings.d.ts 文件。

此文件将自动包含为全局类型定义。 然后,在 src/typings.d.ts 中,添加如下代码:

声明模块“无类型包”;

最后,在使用该库的组件或文件中,添加 以下代码:

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

完成。注意:您可能需要或发现定义更多类型的有用 您尝试使用的库。

【讨论】:

如果您需要分步说明,请查看本文。 medium.com/@jek.bao.choo/…【参考方案21】:

我遵循了允许 allowSyntheticDefaultImports 的建议(因为现在没有导出可供我使用),使用 System.然后我按照某人的建议使用:

import moment from 'moment';

在我的 system.js 配置中映射时刻。由于某种原因,其他导入语句对我不起作用

【讨论】:

这是目前的最后一个答案,但唯一有效的答案!【参考方案22】:

使用 systemjs 我所做的是,在我的 systemjs.config 中,我为 moment 添加了映射

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

然后你就可以轻松导入moment

import * as moment from 'moment'

【讨论】:

以上是关于如何在 Angular 2 typescript 应用程序中使用 moment.js 库?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Angular 2 的 TypeScript 中映射嵌套的 Json

“Angular 2.0 for TypeScript”(alpha)动画是如何工作的?

Angular 2 / Typescript - 如何检查对象数组以查看属性是不是具有相同的值?

我如何实际部署 Angular 2 + Typescript + systemjs 应用程序?

如何使用 Typescript 在 Angular 2 中使用 Google 实现登录

如何使用 Angular 2 / Typescript 限制输入字段中的特殊字符