最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Using Moment with Angular and TypeScript - Stack Overflow

programmeradmin9浏览0评论

I'm new to TypeScript and it's been a while since I've done any serious JavaScript development, so I may be missing something obvious.

I'm trying to use Moment in an Angular 1 app with TypeScript.

I'm using Angular 1.6.5, Moment 2.17.1 and TypeScript 2.17.1. I have Angular typings installed from the npm @types\angular package. Intellisense etc for Angular is working in VS Code.

I've posted the sample code to GitHub here:

The first error

My sample app runs in the browser, but the TypeScript piler plains that it can't find Moment:

app/controller.ts(3,20): error TS2503: Cannot find namespace 'moment'.
app/controller.ts(6,30): error TS2304: Cannot find name 'moment'.

Try using a /// piler directive

To fix this, I tried adding the following /// piler directive:

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

But that doesn't fix the TypeScript piler:

app/controller.ts(5,20): error TS2503: Cannot find namespace 'moment'.
app/controller.ts(8,30): error TS2304: Cannot find name 'moment'.

Import Moment

Next I tried importing Moment using the instructions from their docs:

import * as moment from 'moment';

But this makes TypeScript generate a different erorr:

app/controller.ts(13,5): error TS2686: 'angular' refers to a UMD global, but the current file is a module. Consider adding an import instead.

Import Angular

I also imported Angular. This fixes TypeScript:

import * as angular from "angular";

But now the app doesn't run in the browser:

Uncaught ReferenceError: require is not defined
    at controller.js:2

Use Require.JS

Finally I tried adding Require.JS, but this just causes a different runtime error:

Uncaught Error: Module name "moment" has not been loaded yet for context: _. Use require([])
.html#notloaded
    at makeError (require.js:168)
    at Object.localRequire [as require] (require.js:1433)
    at requirejs (require.js:1794)
    at controller.js:2

Questions

  1. Have I missed anything obvious here?
  2. What's the best practice for referencing d.ts files which are shipped with the main package on npm rather than a separate @types package?
  3. How do I make this work without using an external module loader?

I'm new to TypeScript and it's been a while since I've done any serious JavaScript development, so I may be missing something obvious.

I'm trying to use Moment in an Angular 1 app with TypeScript.

I'm using Angular 1.6.5, Moment 2.17.1 and TypeScript 2.17.1. I have Angular typings installed from the npm @types\angular package. Intellisense etc for Angular is working in VS Code.

I've posted the sample code to GitHub here: https://github./kevinkuszyk/moment-angular-typescript

The first error

My sample app runs in the browser, but the TypeScript piler plains that it can't find Moment:

app/controller.ts(3,20): error TS2503: Cannot find namespace 'moment'.
app/controller.ts(6,30): error TS2304: Cannot find name 'moment'.

Try using a /// piler directive

To fix this, I tried adding the following /// piler directive:

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

But that doesn't fix the TypeScript piler:

app/controller.ts(5,20): error TS2503: Cannot find namespace 'moment'.
app/controller.ts(8,30): error TS2304: Cannot find name 'moment'.

Import Moment

Next I tried importing Moment using the instructions from their docs:

import * as moment from 'moment';

But this makes TypeScript generate a different erorr:

app/controller.ts(13,5): error TS2686: 'angular' refers to a UMD global, but the current file is a module. Consider adding an import instead.

Import Angular

I also imported Angular. This fixes TypeScript:

import * as angular from "angular";

But now the app doesn't run in the browser:

Uncaught ReferenceError: require is not defined
    at controller.js:2

Use Require.JS

Finally I tried adding Require.JS, but this just causes a different runtime error:

Uncaught Error: Module name "moment" has not been loaded yet for context: _. Use require([])
http://requirejs/docs/errors.html#notloaded
    at makeError (require.js:168)
    at Object.localRequire [as require] (require.js:1433)
    at requirejs (require.js:1794)
    at controller.js:2

Questions

  1. Have I missed anything obvious here?
  2. What's the best practice for referencing d.ts files which are shipped with the main package on npm rather than a separate @types package?
  3. How do I make this work without using an external module loader?
Share Improve this question asked Feb 14, 2017 at 13:36 Kevin KuszykKevin Kuszyk 1,98825 silver badges38 bronze badges 8
  • you can do that using direct add moment.min.js file – bipin patel Commented Feb 14, 2017 at 13:40
  • My index.html is already referencing moment.js from the node_modules folder. If I switch that over to moment.min.js I still get errors from the TypeScript piler. – Kevin Kuszyk Commented Feb 14, 2017 at 13:48
  • can you try to declare moment variable like this 'declare var moment: any;' before @Injectable() or @Component – bipin patel Commented Feb 14, 2017 at 13:50
  • That fixes usage like let foo = moment(), but using the moment.Moment interface still produces a piler error. Also there's no intellisense in VS Code for moment() with this fix. – Kevin Kuszyk Commented Feb 14, 2017 at 13:54
  • @KevinKuszyk I'm having the exact same issue. Did you ever figure this out? – Darthg8r Commented Apr 17, 2017 at 15:52
 |  Show 3 more ments

3 Answers 3

Reset to default 6

It looks like this is a known issue with Moment's d.ts file (see issues #3763, #3808 and #3663).

While we wait for an official fix, this worked for me.

Change:

export = moment;

to this:

declare module "moment" {
    export = moment;
}

Try explicitly declaring the @types scoped package to typesRoot in your tsconfig.json file:

{
    "pilerOptions": {
        "module": "monjs",
        "target": "es5",
        "noImplicitAny": false,
        "sourceMap": false,
        "typeRoots": [
            "./node_modules/@types"
        ]
    }
}

Ensure the type definitions are installed properly in node_modules/@types/... and that your TypeScript piler is up to date.

I'm trying to very slowly bring a dated project up to modern standards, and so I struggled with trying to get the other solutions to work while this same issue happened to me intermittently.

Ultimately, I decided to replace Moment with one of the maintained alternatives, as suggested on the Moment website: https://momentjs./docs/#/-project-status/

I highly remend anyone reading this do the same. Moment was great, but it's time to say goodbye.

发布评论

评论列表(0)

  1. 暂无评论