Moment: [TypeScript] "Fehler TS2304: Name 'Moment' kann nicht gefunden werden" bei Verwendung mit "module":"none"

Erstellt am 14. Feb. 2017  ·  51Kommentare  ·  Quelle: moment/moment

Typescript scheint die globale moment() Funktion nicht aufzulösen, wenn es in einem Nicht-Modul-Kontext verwendet wird.

tsc-Version: 2.1.6
Momentversion: 2.17.1

Repro (vorausgesetzt, tsc befindet sich auf Ihrem $PATH ):

$ mkdir repro && cd repro
$ npm i moment
$ echo 'const now = moment();' > test.ts
$ tsc --module none test.ts
test.ts(1,13): error TS2304: Cannot find name 'moment'.

Die Verwendung eines Modultyps funktioniert jedoch wie erwartet:

$ echo 'import * as moment from "moment"; const now = moment();' > test2.ts
$ tsc --module commonjs test2.js

Leider verwendet mein Projekt kein Bundler- oder Modulsystem, daher bleibe ich vorerst bei "module": "none" .

Ist meine einzige Alternative, etwas wie typings install --save --global dt~moment ?

TypeScript Up-For-Grabs

Hilfreichster Kommentar

+1 bitte korrigiere das

Alle 51 Kommentare

ich stehe vor dem gleichen Problem. Es spielt keine Rolle, welchen Modultyp Sie in tsconfig.json angeben. Ich bekomme den gleichen Fehler wie @rossipedia

Ich habe das gleiche Problem gemeldet (https://github.com/moment/moment/issues/3663), aber leider wurde es einfach ohne Reaktion geschlossen.

Am Ende habe ich moment.d.ts in mein /scripts/app Verzeichnis kopiert und den in https://github.com/moment/moment/issues/3663#issuecomment -273199291 angegebenen Fix implementiert

Hoffentlich wird irgendwann eine dauerhaftere Lösung seinen Weg in moment.d.ts .

Ich habe dies gelöst, indem ich "moduleResolution": "node" in meiner tsconfig angegeben habe. Ich bin mir nicht sicher, ob dies eine Option für Sie ist, aber es scheint den Zweck zu erfüllen.

"moduleResolution": "node" hat es leider nicht für mich behoben

@rossipedia Ich auch nicht.

Wäre es nicht hilfreich, export as namespace moment; in die Datei moment.d.ts einzufügen?

Siehe: https://github.com/moment/moment/issues/3808

@czb das hat das Problem bei mir leider auch nicht

Ich habe dies mit ein paar Hacks gelöst, die andere in vielen Projekten erwähnt haben, die dieses Problem haben. Wickeln Sie es einfach in eine eigene benutzerdefinierte Definitionsdatei ein. Dies verwendet Typescript 2.2. Auf diese Weise mache ich mich nicht mit der Abhängigkeit von npmjs.org herum und muss das Ganze nicht in die Quellcodeverwaltung einchecken.

tsconfig.json

"compilerOptions": {
    "target": "ES5",
    "moduleResolution": "node",
    ...
}

moment.custom.d.ts

import * as _moment from 'moment';
export as namespace moment;
export = _moment;

Ich bin neugierig, warum das nicht funktioniert, wenn dieser Code direkt zu moment.d.ts hinzugefügt wird? Ich kann nicht anders, als zu denken, dass wir in einen obskuren TypeScript-Auflösungsfehler geraten, und leider hat tsc keinen ausführlichen Modus (den ich kenne), der helfen würde, genau zu erkennen, wo etwas schief läuft.

Ich denke, wenn Sie "module": "none" definieren, sucht Typescript nicht nach d.ts Dateien im Ordner node_modules/moment . Meine Erfahrung ist, dass es nur im Ordner node_modules/@types sucht. Es gibt also grundsätzlich diese Möglichkeiten.

  1. Kopieren Sie moment.d.ts unter node_modules/@types/moment
  2. Fügen Sie /// <reference path="./node_modules/moment/moment.d.ts" /> in Ihre .ts Datei ein
  3. Rufen Sie tsc --typeRoots node_modules test.ts
  4. Fügen Sie ./node_modules/moment/moment.d.ts in den Abschnitt files von tsconfig.json

Außerdem müssen Sie export as namespace moment; in die Datei moment.d.ts einfügen.

Das Moment-Team würde sich über alle PRs freuen, die dies beheben würden, aber TS 1.x-kompatibel bleiben.

Ich muss noch eine Lösung finden, die überhaupt funktioniert, aber wenn ich es tue, werde ich auf jeden Fall einen PR hinzufügen

Laut #3663 der temporäre Fix, um es ohne Bundler zum Laufen zu bringen...

  • Kopieren Sie moment.d.ts von node_modules/moment/ nach node_modules/@types/moment

  • Ändere export = moment; in moment.d.ts in

declare module "moment" {
    export = moment;
}
  • Benennen Sie moment.d.ts in index.d.ts

Verwenden Sie einfach moment und Ihr Editor (in meinem Fall vscode) und tsc sollten sich nicht beschweren

+1 bitte korrigiere das

@mtgibbs Wo

@elSteeze

Ja, ich füge sie zu meinem tsconfig.json . Hier ist ein geschrubbtes Beispiel:

{
  "compilerOptions": {
    "target": "ES5",
    "moduleResolution": "node",
    "typeRoots": [
      "./node_modules/@types"
    ]
  },
  "compileOnSave": true,
  "exclude": [
    "node_modules",
    "./path/to/typings/**/*.d.ts",
    "./typings"
  ],
  "include": [
    "./path/to/typings/moment.custom.d.ts",
    "./path/to/src/**/*.ts"
  ]
}

@mtgibbs Hey danke Mann! Schätzen Sie die schnelle Antwort. Ich werde das versuchen.

@mtgibbs Entschuldigung für eine weitere Noob-ähnliche Frage, nach der Implementierung Ihrer Lösung bekam ich Editor-Fehler beim Moment-Schlüsselwort in meinem ts-Code ...

'moment' refers to a UMD global, but the current file is a module. Consider adding an import instead

Ich habe persönlich recherchiert und versucht, eine Lösung zu implementieren, indem ich moment.custom.d.ts neu geschrieben habe, aber leider hat das mein Problem nicht behoben.

Entschuldigung, ich versuche nicht, einer dieser lästigen Entwickler zu sein, die alle anderen dazu bringen, ihren Code zu debuggen. Ich bin ein Absolvent und neu in der Arbeit mit Bibliotheken von Drittanbietern in einer Angular 2-Umgebung

Hier ist mein aktualisiertes module.custom.d.ts

declare var moment: any;
declare var module: NodeModule;
interface NodeModule {
    id: string;
}
import * as _moment from 'moment';
export as namespace moment;
export = _moment;

Kein Problem. Wenn Sie Angular 2 verwenden, sollten Sie 2.0+ TS verwenden. Ich arbeite nicht in Angular, daher bin ich mir nicht sicher. Denken Sie daran, alles von Ihrer tsconfig.json einzufügen, und ich schaue nach, wenn ich wieder auf einem echten Computer bin.

Sicher!

Dies ist meine gesamte Datei tsconfig.es5.json im src-Verzeichnis meines Winkel-2-Moduls, das ich baue.
Ich freue mich übrigens über die Hilfe

{
  "compilerOptions": {
    "declaration": true,
    "module": "es2015",
    "target": "es5",
    "baseUrl": ".",
    "stripInternal": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "moduleResolution": "node",
    "outDir": "../build",
    "rootDir": ".",
    "lib": [
      "es2015",
      "dom"
    ],
    "skipLibCheck": true,
    "typeRoots": [
      "./node_modules/@types"
    ]
  },
  "compileOnSave": true,
  "exclude": [
    "node_modules",
    "./typings/**/*.d.ts",
    "./typings"
  ],
  "include": [
    "./typings/moment.custom.d.ts",
    "./src/**/*.ts"
  ],
  "angularCompilerOptions": {
    "annotateForClosureCompiler": true,
    "strictMetadataEmit": true,
    "skipTemplateCodegen": true,
    "flatModuleOutFile": "new-version-library.js",
    "flatModuleId": "new-version-library"
  },
  "files": [
    "./index.ts"
  ]
}

In welcher TS-Version kompilieren Sie? Sie sollten nur in der Lage sein, den Moment oben ohne meinen Hack zu importieren.

@mtgibbs Ich verwende v2.2, und das dachte ich mir. Leider funktioniert es nicht. Ich bin fast an dem Punkt angelangt, an dem ich meine eigene Version der Funktionalität schreibe, die wir von momentjs übernehmen, weil ich das anscheinend nicht zum Laufen bekomme.

@elSteeze

Okay, zurück hierher. Mir ist aufgefallen, dass Sie gesagt haben, dass Sie ein benutzerdefiniertes module.custom.d.ts , aber dann beziehen Sie sich auf mein moment.custom.d.ts in Ihrem tsconfig.json . Stellen Sie sicher, dass Sie moment.custom.d.ts und Ihrem Compiler hinzugefügt haben, nichts von diesem zusätzlichen Zeug, das Sie als Dinge deklarieren mussten. Stellen Sie dann sicher, dass Sie es oben in der Datei referenzieren, in der Sie es verwenden möchten.

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

Dies sollte es Ihnen ermöglichen, wie in meiner ursprünglichen Problemumgehung als globale Variable darauf zu verweisen.

Super danke
Ich habe meine Dateistruktur geändert, um Ihre Pfade zu unterstützen. Das sind also die richtigen Pfade.
Prost Kumpel!

Das funktioniert bei mir:

  • Kommentieren Sie // export = moment in der offiziellen Datei moment.d.ts aus
  • node_modules/moment/moment.d.ts zu tsconfig.json hinzufügen

Kopieren Sie alternativ das geänderte moment.d.ts an einen Ort Ihrer Wahl und fügen Sie den Pfad dazu in Ihrem tsconfig.json

Ich denke, das Hauptproblem besteht darin, dass Sie bei expliziter Verwendung von "module":"none" in tsconfig.json keinen Import oder Export auf oberster Ebene in Bibliotheken haben können (weil Sie dann Module verwenden).

Sie müssen zuerst in die Komponente importieren als
import * als Moment von "moment";

bei mir hat es gut geklappt

Sie müssen zuerst in die Komponente importieren als
import * als Moment von "moment";
bei mir hat es gut geklappt

Wenn Sie dies in einer Datei tun, wird die Namensraumauflösung für diese Dateien deaktiviert.

Bitte Leute +1 um das zu beheben

Warum beheben Sie dieses Problem nicht? Es ist sehr wichtig.

Das Hinzufügen von "module": "commonjs" zu den tsconfig.json es für mich behoben

Aber ich muss "module": "none" . Commonjs ist keine Lösung.

Wenn ich es richtig verstehe, wird dies mit der Importtypenfunktion von TypeScript 2.9 gelöst, die es ermöglicht, import Typdefinitionen zu erstellen, ohne den Modul-/Umgebungskontext zu beeinflussen.

Ich verwende TS 3.0.1, ist das jetzt gelöst? Es funktioniert zumindest nicht out of the box.

BEARBEITEN , Mit TS 3.0.1 könnte ich genau das tun:

declare var moment: typeof import("moment");

Hurra!

Mit tsconfig

{
    "compilerOptions": {
        "module": "none"
        "moduleResolution": "node", 
        // ...
    }
}

TS 3.0.1 scheint dieses Problem zu beheben (und es ist seit über anderthalb Jahren ohne Traktion geöffnet)

Hallo Rossipedia,
Ich stehe vor dem gleichen Problem im Angular-6-Projekt. Laut Ihren Kommentaren ist es in TS 3.0.1 behoben, aber die angle6 CLI unterstützt die TypeScript-Version 3.0.1 nicht.

Können Sie bitte helfen, dieses Problem zu lösen?

Ist jemand anderem auch das npm-Paket @types/moment begegnet, das nur ein Stub ist und Sie auffordert, die Datei zu verwenden, die vom normalen Moment-Paket bereitgestellt wird?

... Warum muss moment es anders machen als jedes andere Paket? Dies ist der Grund, warum dieses Problem existiert, und Tausende von Stunden wurden von Entwicklern damit verbracht, damit zu kämpfen.

Sicher, die Lösung von @Ciantic funktioniert in TS 3.0.1, aber ich muss für keines der anderen Pakete, die ich verwende, etwas wie declare var moment: typeof import("moment"); verwenden.

Es sieht nicht so aus, als hätte Typescript 3.0.1 dieses Problem behoben, es sieht so aus, als ob es uns nur einen Workaround bietet.

es sieht so aus, als ob es uns nur einen Workaround gibt.

Ja, genau das ist es. Dies ist keine akzeptable "Lösung".

Es ist erst ein Tag her und ich habe gerade festgestellt, dass der Workaround von TS 3.0.1 nur die moment Funktion importiert, nicht den Namespace/die Typen. Wenn Sie also ein Momentobjekt an eine Funktion übergeben möchten, passiert Folgendes:

image

Bitte öffnen Sie dieses Problem erneut, oder besser: Beheben Sie die .dts-Datei.

Keine Lösung für das ursprüngliche Problem, aber für Leute, die das später googeln: Die Angabe des folgenden in tsconfig.json hat es behoben (Typoskript 3.3.3 und Moment 2.24.0)

{
  "compilerOptions": {
    "module": "commonjs"
  }
}

Momentan nutze ich moment nicht mehr viel, aber ich freue mich, das Problem erneut zu öffnen, wenn es noch gültig ist.

FEHLER in src/app/services/get-list.service.ts(22,54): Fehler TS2304: Name '_' kann nicht gefunden werden.

was ist die lösung dafür??

@nagipogu Keine Lösung dafür, dieses Problem ist für moment.js , bitte öffnen Sie Ihr Problem im Github-Repository von underscore.js .

Ich stoße auf dieses Problem mit der neuesten Version von Moment mit der neuesten Version von TS. Hat jemand einen erfolgreichen Workaround?

Funktioniert immer noch nicht, die Lösung für mich war yarn add -W [email protected] .

Als ich die neueste Moment-Version installierte und in node_modules/moment/package.json nachsah, sah ich Folgendes: https://github.com/moment/moment/blob/develop/package.json#L29 - aber es gab kein vorhandenes Verzeichnis node_modules/moment/ts3.1-typings , daher überrascht es nicht, dass TS es nicht finden konnte. Ich denke, es könnte ein Fehler mit einem Installationsskript (oder einem Paket) oder so sein. Ja, wir haben "module": "esnext" in tsconfig.json.

Bei mir brach es mit 2.25.0:

Ich habe pnpm add [email protected] als temporäre

Bei mir brach es mit 2.25.0:

Ich habe pnpm add [email protected] als temporäre

funktioniert gut, danke

Bei mir brach es mit 2.25.0:

Ich habe pnpm add [email protected] als temporäre

Dasselbe hier fügte es hinzu: "dependencies" {"moment": "^2.24.0",
}...scheint zu funktionieren danke.

Ein Downgrade auf 2.24.0 hat bei mir auch funktioniert. Sieht aus wie eine Regression in 2.25.0.

Behebt 2.25.3 Ihre Probleme?

Es gibt so viele verschiedene Situationen, in denen Moment.js verwendet wird, geschweige denn TS 1.x, TS 2.x, TS 3.x...
Ich zögere, Änderungen vorzunehmen, die jede Gruppe dieser Benutzer beeinträchtigen.

Wenn Sie der Meinung sind, dass die Dokumentation verbessert werden kann, posten Sie bitte unter https://github.com/moment/momentjs.com/

Behebt 2.25.3 Ihre Probleme?

Ja.

Rollback auf 2.24.0, als 2.25.1 für mich in Angular 9 fehlgeschlagen ist. Mit 2.25.3 ist es wieder auf Kurs.

Okay, großartig. Ich schließe vorerst.

Bitte öffnen Sie erneut (oder eröffnen Sie eine neue Ausgabe), wenn Sie weiterhin Bedenken haben.

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen

Verwandte Themen

M-Zuber picture M-Zuber  ·  3Kommentare

ninigix picture ninigix  ·  3Kommentare

RobinvanderVliet picture RobinvanderVliet  ·  3Kommentare

nikocraft picture nikocraft  ·  3Kommentare

danieljsinclair picture danieljsinclair  ·  3Kommentare