2016-09-28 13 views
2

Ich habe Probleme, WebPack zu bekommen, um importierte Abhängigkeiten für ein in TypeScript geschriebenes Projekt zu injizieren. Mein erstes Problem ist, dass TypeScript das importierte Modul erkennt.TypScript-Modul Importieren & WebPack

Ich habe eine header.ts-Datei, die ein Modul erklärt, die unter vi.input verschachtelt ist und exportiert eine VIInputDirective Klasse. In der main.ts Datei, ich versuche, die exportierte VIInputDirective Klasse aus der header.ts Datei zu importieren, aber kann nicht scheinen, TypeScript zu bekommen, um es zu erkennen.

header.ts

module vi.input.header { 
    import IDirective = angular.IDirective; 

    export class VIInputDirective implements IDirective { 
    ... 
    } 
} 

main.ts

import {VIInputDirective} from "./header.ts"; // Nothing imported; Cannot Resolve issue 
VIInputDirective.whatever(); // Does not work 

material.dt.s

declare module vi.input { 
    ... 
} 

Wenn ichtauschenin dem main.ts Datei mit import VIMHeaderDirective = vi.input.header.VIInputDirective; es funktioniert gut, aber dann webpack auf transpile/inject gibt mir die folgende Fehlermeldung:

VM1469:1Uncaught ReferenceError: vi is not defined 

Ich habe versucht, die vi.input.header Modul direkt exportieren (dh Exportmodul vi.input.header), aber das hat nicht funktioniert. Ich versuchte auch, das Referenzsyntax zu verwenden, um die Datei einzuschließen, aber das funktionierte auch nicht: ///<reference path="file_path"/>.

Es ist ein Problem mit der Verschachtelung von Modulen, denn wenn ich das Modul entfernen und die VIInputDirective Klasse direkt exportieren, funktioniert es gut. Ich möchte es jedoch in einem verschachtelten Modul behalten.

+0

Haben Sie versucht, importieren * als x von "./header" dann neue x.vi.input.header.VIInputDirective – Banners

+0

Vielleicht sollten Sie auch versuchen, eine Exportanweisung zu der Moduldeklaration hinzufügen (jetzt in 'Namespace' in geändert Typoskript) – Banners

+0

Probieren Sie dies "Import * als VIInputDirective von" ./header.ts "und TypeScript ist nicht in der Lage, das Modul zu finden. Ich bekomme den Fehler Canlist Resolve File. Wenn ich nicht header.ts in ein Modul einpacken (ie Modul vi.input.header {}), es funktioniert gut, aber ich möchte das behalten. – sags

Antwort

2

Sie sind nicht-Module verwenden. Module verfügen über eine oder mehrere Top-Level-Anweisungen import oder export. Stattdessen verwenden Sie den globalen Namespace und erstellen Unternamespaces des globalen Namespace, um Ihr Programm zu organisieren. Dies wird das aufschlussreiche Modulmuster genannt. Es beinhaltet nicht die Verwendung von Modulen.

Leider verwendete TypeScript dieses Muster als Internal Modules. Diese Terminologie ist seither veraltet und die Verwendung der module x {} Syntax (beachten Sie das Fehlen von " s um x) wird dringend davon abgeraten. Die Sprache hat auch ein Stichwort eingeführt namespace, um die Verwirrung zu reduzieren.

JavaScript-Loader und -Bundler wie Webpack, RequireJS und SystemJS arbeiten mit Modulen, was TypeScript als externe Module bezeichnet.

folgende Konstrukte Um zu klären, die Sie erwähnen, sind nicht Modul

Zusammenhang
  1. Top-Level nicht ausgeführten module/namespace syntaktischen Erklärungen

    module vi.input.header { ... } 
    

    dies nun als

    geschrieben werden würde
    namespace vi.input.header { ... } 
    

    , um Verwirrung zu minimieren, aber irregardless hat die emit immer in Folge.

    var vi; 
    (function (vi) { 
        var input; 
        (function (input) { 
         var header; 
         (function (header) { 
         })(header = input.header || (input.header = {})); 
        })(input = vi.input || (vi.input = {})); 
    })(vi || (vi = {})); 
    

    Hinweis: dieser mutiert die globale Reichweite in einem Muster von verschiedenen Bibliotheken verwendet. namespace s (früher interne Module genannt) wie die oben genannte haben die interessante Eigenschaft, dass mehrere Dateien zu ihren Inhalten beitragen können, und dies ist in der Tat ihr Hauptzweck. Dies erklärt den Grad der Verschachtelung und die bedingten Zuordnungen zu Variablen in der obigen Ausgabe. Dies hat nichts zu tun mit Module.

  2. import Zuordnungen, die namespace Mitglieder wie

    import IDirective = angular.IDirective; 
    

    gelten nicht als Top-Level-import Erklärungen, und somit führen nicht ihre enthalten Datei ein Modul betrachtet werden verweisen. Dies gilt auch dann, wenn sie auf der obersten Ebene einer Datei stehen. Der Grund ist, dass Modulsysteme, seien es AMD, CommonJS, System oder ES2015, alle Strings als Modulspezifizierer verwenden, die aus solchen Strings importieren; welches übrigens Dateipfade, URLs, aufgelöste einfache Namen oder synthetische Modul-IDs darstellen kann.

Auch hier sind die import name = qualified.global.name Aussagen in Ihren Code ein Typoskript spezifische Funktion, die zu Module ohne Bezug ist. Sie können sehr nützlich für Aliasing geschachtelte Typen und Werte sein, aber Module, die sie nicht machen.

Hier ist, wo es interessant wird, und wo es mit Ihrer spezifischen Frage namespace s schneidet kann verwendet werden, und manchmal recht elegant, von innerhalbexternen Module, aber ihre Semantik ist sehr unterschiedlich

Betrachten

Dienstleistungen.ts

export namespace app { 
    export class SomeService { } 
} 

die in die folgenden JavaScript

export var app; 
(function (app) { 
    class SomeService { 
    } 
    app.SomeService = SomeService; 
})(app || (app = {})); 

main.ts

export namespace app { 
    export function bootstrap() { } 
} 

die sich in folgende JavaScript

export var app; 
(function (app) { 
    function bootstrap() { } 
    app.bootstrap = bootstrap; 
})(app || (app = {})); 
kompiliert kompiliert

Sowohl oberhalb von externen Modulen sind, das ist wahr Module, dass die Verwendung von Namespaces als interne Code Organisation Mechanismen aber sie Schlüssel zum Mitnehmen ist, dass sie nicht tun zu einem Sharedapp Namespace beisteuern, die jeweils ihre eigenen mit, Datei scoped app Variable. Weder hat impliziten Zugriff auf die Mitglieder des anderen, die Deklarationen von namespace app verschmelzen nicht über Dateien, und sie haben ein ähnliches internes Benennungsschema ist neben ihrer Modularität.

Wie hängt das alles von Ihrer Frage und den Vorschlägen ab, die Sie anwenden wollten?

uns kein Modul ist

headers.ts

module vi.input.header { 
    import IDirective = angular.IDirective; 

    export class VIInputDirective implements IDirective { 
    static whatever() { } 
    } 
} 

Diese Datei Mal sehen, wie oben erläutert, und verwendet den globalen Namespace seine Erklärungen zu belichten. Wenn wir dies heute schreiben würden, würden wir das Schlüsselwort namespace anstelle des Schlüsselwortes module per Konvention verwenden.

main.ts

import {VIInputDirective} from "./header.ts"; // Nothing imported; Cannot Resolve issue 
VIInputDirective.whatever(); // Does not work 

Tatsächlich funktioniert weder Linie, weil Sie headers.ts importieren, als ob es sich um ein Modul waren, aber wie wir es gerade ist ein Modul nicht gesehen haben. Darüber hinaus macht die erste Zeile, die eine import Anweisung der obersten Ebene ist, die aus einer Modulspezifikationszeichenfolge importiert, ironischerweise main.ts, ein Modul.

Kurz gesagt, die zwei Stile nicht gut mischen, und das Teilen von Code zwischen ihnen ist nicht einfach und ist nicht etwas, was Sie wahrscheinlich versuchen sollten (Ich habe das UMD-Format aus dieser Antwort zu versuchen, es relativ einfach zu halten).

Jetzt schließt sich der Kreis

starken Text

declare module vi.input { 
    .... 
} 

If I swap import {VIInputDirective} from "./header.ts"; in the main.ts file with import VIMHeaderDirective = vi.input.header.VIInputDirective; it works fine, but then webpack on transpile/inject gives me the following error:

der Tat, wie oben erläutert. Diese import, die nicht auf eine Modulspezifikationszeichenfolge abzielt und keine anderen Importe oder Exporte auf oberster Ebene enthält, ändert main.ts so, dass es kein Modul mehr ist.Dies bewirkt, dass TypeScript es korrekt schreibt. Globale Variablen, die sich gegenseitig referenzieren, sind import = namespace.value vollkommen legitim, aber dies sind keine Module und JavaScript-Tools, wie z. B. Webpack, funktionieren auf Modulen.

Also, wie würdest du diese App in dieser schönen neuen Welt schreiben? Da Sie ein Modulpaket-Tool, Webpack, verwenden, würden Sie es mit den richtigen Modulen schreiben.

main.ts

import {VIInputDirective} from "./header.ts"; 
VIInputDirective.whatever(); 

headers.ts

import {IDirective} from 'angular'; 

export class VIInputDirective implements IDirective { 
    static whatever() { } 
} 

material.d.ts sieht nicht mehr wie damals, als Sie dies schrieb, wie es gewesen ist aktualisiert, um mit den richtigen Modulen zu arbeiten. Wenn Sie etwas von ihm verweisen müssen, verwenden Sie das Modul Syntax

my-Dialog-options.ts

import {material} from 'angular'; 

const dialogOptions: material.IDialogOptions = { ... }; 

export default dialogOptions; 

ich versucht habe, nicht zu sehr zu vereinfachen, aber einige Handbewegung, die zur Vermeidung war ein Schreiben Novelle zu dem Thema, aber ich glaube, ich hoffe, die wichtigsten Punkte abgedeckt und vermittelt haben.

0

Sie suchen nach Namespaces nicht Modul, so.

header.ts

export namespace vi.input.header { 
    export class VIInputDirective { 

    } 
} 

main.ts

import { vi } from "./header.ts"; 
var foo = new vi.input.header.VIInputDirective(); 
+0

Nach Header aktualisieren. ts zu _export namespace_ und der TS-Compiler löst mit der Importsyntax den Fehler "Kopfzeilenname nicht finden" aus. Könnte das an meiner ** material.dt.s ** Datei liegen, wo ich _declare module vi.input {} _ deklariere? – sags

+0

Ich habe alles versucht und nichts scheint zu funktionieren, außer dem Entfernen des Namensraums. – sags

Verwandte Themen