Rollup-plugin-typescript2: Eingabedatei im falschen Ordner innerhalb des Objekts als `Input` Rollup generiert

Erstellt am 5. Feb. 2019  ·  33Kommentare  ·  Quelle: ezolenko/rollup-plugin-typescript2

Was passiert und warum es falsch ist

Möglicherweise ist dies eine Fehlkonfiguration von meiner Seite, aber es sieht aus wie ein Fehler. Wenn Sie object als input Eigenschaft für die Rollup-Konfiguration verwenden, wird die Typisierungsdatei für die Eingabedateien im Stammordner des Repositorys generiert (derselbe Ordner wie die Rollup-Konfigurationsdatei) und nicht das Zielausgabeverzeichnis (hier ./dist ) zusammen mit der gebündelten JS-Datei.

Versionen

  • Typoskript: 3.2.4
  • Rollup: 1.1.2
  • rollup-plugin-typescript2: 0.19.2

rollup.config.js

{
    ...
    input: {
        Lib1: './src/Lib1.tsx',
        Lib2: './src/Lib2.tsx'
    },
    output: {
        dir: './dist',
        format: 'cjs',
        sourcemap: true,
        entryFileNames: '[name].js'
    }
}

tsconfig.json

{
  ...
  "compilerOptions": {
    "outDir": "./dist"
  },
}

Ergebnis:

// These files are created
./Lib1.d.ts
./Lib2.d.ts

// instead of (expected):
./dist/Lib1.d.ts
./dist/Lib2.d.ts

Seltsamerweise, wenn Sie entryFileNames: 'dist/[name].js' eingeben, wird ein überflüssiger Unterordner namens dist innerhalb des Ordners dist erstellt und dort erstellt.

bug more info needed

Hilfreichster Kommentar

Jep. das scheint der einzige Weg zu sein, es sei denn, Sie lassen tsc die End-to-End-Bündelung durchführen.
Diese Rollup-Plugins scheinen tsc effektiv zu bitten, zwei verschiedene Aufgaben zu erledigen:

  1. "Überprüfen Sie alle diese einzelnen Module und konvertieren Sie sie in JavaScript" und lassen Sie mich (dh Rollup) das Bündeln und Schreiben auf die Festplatte übernehmen.
  2. "Machen Sie alle Deklarationen für diesen TS-Projektordner und legen Sie sie dort ab."

Die Ergebnisse von 1 und 2 stimmen nicht überein und können nicht übereinstimmen, wenn Sie eine "Eingabezuordnung" und Code-Splitting usw. verwenden. – AFAICT.

...es sei denn, Sie machen das Rollup-Plugin viel stärker in den Prozess der Typdeklaration ein.

Alle 33 Kommentare

Die Plugin-Option useTsconfigDeclarationDir ist vorerst ein Workaround.

Dies könnte durch #142 behoben werden, veröffentlicht in 0.20.0

Hallo @ezolenkom & @jakearchibald , eigentlich kein Glück.

Beim Hinzufügen der Option useTsconfigDeclarationDir in meinem Rollup-Plugin werden die Deklarationsdateien überhaupt nicht mehr erstellt. Und das Update auf 0.20.1 hat leider keinen Unterschied gemacht.

@benkeen Wenn Sie die Plugin-Option useTsconfigDeclarationDir: true Sie auch den Wert declarationDir in tsconfig.json

habe ähnliche Probleme, mein Projektlayout sieht so aus:

export default [ 
  {
    input: 'src/subFolder1/one.ts,
    output: [
                    {
                      file: 'dist/one.js'
                      .....                      
                     }
    ],
    plugins: [
           typescript({
                typescript: require('typescript'),
            }),
    ]
  },
      input: 'src/subFolder2/two.ts,
      output: [
                    {
                      file: 'dist/two.js'
                      .....                      
                     }
    ],
     ...
  },
]

Als Ausgabe habe ich:

  |---subFolder1
  |          |--------one.d.ts
  |
  |---subFolder2
  |          |---------two.d.ts
  |-----one.js
  |-----two.js

Funktioniert bei mir auf 0.20.1 mit useTsconfigDeclarationDir: false -- d.ts-Dateien werden in die Ordner verschoben, die in output.[].dir . @benkeen könntest du es nochmal versuchen?

@AntonPilyak , das ist subFolder1/one.ts und subFolder2/one.ts , würde einer davon einen anderen überschreiben.

@ezolenko : Diese Funktion verursacht meiner Meinung nach mehr Unannehmlichkeiten, als ein echtes Problem zu lösen (da es schwierig ist, all diese Verzeichnisstrukturen beizubehalten). Ich muss ein Skript erstellen, das all diese Typdeklarationen in das Stammverzeichnis des Bundles kopiert und die Verzeichnisse zu .npmignore hinzufügen, um ein Bundle zu erstellen, das einfach einzubinden ist. Ich würde vorschlagen, diese zusätzlichen Verzeichnisse NUR für die Typdateien mit den gleichen Namen zu erstellen. Verwenden Sie für den Rest ein Verzeichnis, das im Abschnitt 'output' von rollup.config.json definiert ist.

@AntonPilyak Sie können möglicherweise die Option useTsconfigDeclarationDir: true , indem Sie declarationDir in tsconfig einrichten. Dadurch sollte typescript selbst die Eingabepfade verarbeiten.

Die Entscheidung, ob Unterverzeichnisse aufgrund der Eindeutigkeit der Pfade verwendet werden sollen, wäre in einem sich entwickelnden Projekt ein Albtraum. Plötzlich würde Ihre Eingabe in einen Unterordner verschoben, nur weil Sie eine neue Datei mit demselben Namen in einem anderen Ordner hinzugefügt haben.

Normalerweise, wenn Sie schöne Eingaben wollen, möchten Sie sie sowieso in eine Datei zusammenführen (es gab ein npm-Modul, dessen Namen ich immer wieder vergesse).

Ich verwende die Version 0.22.0 und habe so ziemlich das gleiche Problem wie @AntonPilyak

{
    ...
    input: {
        foo: 'src/lorem/foo.ts',
        bar: 'src/ipsum/bar.ts'
    },
    output: {
        dir: 'dist',
        format: 'cjs',
        sourcemap: true,
    }
}

Und das bekomme ich raus:

dist/
    lorem/
        foo.d.ts
    ipsum/
        bar.d.ts
    foo.js
    foo.js.map
    bar.js
    bar.js.map

Natürlich möchte ich, dass die *.d.ts Dateien neben den *.js und *.js.map Dateien stehen.

Ich habe versucht, mit useTsconfigDeclarationDir und declarationDir herumzuspielen, ohne Erfolg.

Die Definitionsdateien landen immer in den Unterordnern lorem bzw. ipsum und niemals in einer flachen Liste.

Darüber hinaus scheint es Deklarationsdateien für jede .ts-Datei zu erstellen, die es findet, nicht nur für die Einstiegspunkte.

dist/
    lorem/
        foo.d.ts
    ipsum/
        utils/
            bar-helper.d.ts
        bar.d.ts
     some_other_ts_file/
         not_imported_by/
             neither_foo_nor_bar/
                  wat.d.ts
    foo.js
    foo.js.map
    bar.js
    bar.js.map

Ich habe versucht, options.tsconfigOverride.input nur auf die Einstiegspunkte zu beschränken, aber das scheint keine Auswirkungen zu haben. Tatsächlich bin ich mir nicht einmal sicher, ob tsconfigOverride.input funktioniert.

Das ist alles etwas verwirrend.

...

Ich meine, fair genug, wenn es eine Deklarationsdatei für utils/bar-helper.ts erstellen muss, aber mindestens wat.ts sollte aus dem Ganzen weggelassen werden.

Ja, es generiert Deklarationen für alle von tsconfig gefundenen Dateien. Wenn Sie nicht möchten, dass eine bestimmte Datei berührt wird, stellen Sie sicher, dass sie ausgeschlossen oder nicht in tsconfig enthalten ist. Um eine Liste der Dateien anzuzeigen, die von Typskript gefunden wurden, führen Sie das Plugin mit Verbosity 3 aus und suchen Sie nach dem Eintrag "parsed tsconfig".

Für den Definitionspfad, wo in Ihrem Beispiel möchten Sie, dass die Definition für 'src/ipsum/foo.ts' sitzt?

Da es sich um eine Definition für dist/foo.js ich angenommen, dass es daneben enden würde – genau wie die Quell-Map-Datei – also in dist/foo.d.ts .

Kann TypeScript dist/foo.js und dist/lorem/foo.d.ts paaren?

Das vollständige Szenario, in dem dies zusammenbricht, ist:
src/dir1/foo.ts
src/dir2/foo.ts

dir1/foo.ts wird als Rollup-Eingabe festgelegt und importiert dir2/foo.ts. Rollup erstellt das Paket dist/foo.js, das relevante Teile beider Quelldateien enthält, aber Typescript muss irgendwo 2 Typdefinitionsdateien mit demselben Namen erstellen.

Eine einfache Lösung besteht darin, Unterordner zu verwenden, die das Quelllayout spiegeln. Ich denke, das macht tsc auch, es sei denn, Sie weisen es an, Typdefinitionen zusammenzuführen (rpt2 unterstützt das Zusammenführen von Definitionen nicht).

Und ja, Typoskript weiß, wo Typdefinitionen zu finden sind. Abgesehen davon, dass es ein bisschen chaotisch ist, sollte dies kein Problem sein. Wenn Sie ein Paket mit Typen auf npm bereitstellen möchten, legen Sie "types" in package.json auf die d.ts-Datei für Ihren Einstiegspunkt fest. Typoskript wird die Dinge von dort finden.

Ah, dieses Plugin verwaltet also keinen Teil des Deklarationserstellungsprozesses. Es startet einfach tsc , um seine Sache zu erledigen, unabhängig von Rollups Prozess?

Wenn ich jedoch nur ein paar Module präsentiere/veröffentliche, warum sollte ich dann wollen, dass TypeScript *.d.ts Dateien für jede einzelne ts-Datei generiert,

Die Sache ist, ich exportiere eine Reihe von eigenständigen Modulen ( import tool1 from 'myTools/tool1'; usw.), sodass es keinen einzigen Einstiegspunkt gibt, der in pkg.types . Jede Definitionsdatei muss sich neben ihrem *.js Gegenstück befinden, damit VSCode sie aufnehmen kann.

Schlimmer noch, wenn ich es habe

{
    ...
    input: {
        fooscript: 'src/foo/index.ts',
        barscript: 'src/bar/index.ts'
    },
    output: {
        dir: 'dist',
        format: 'cjs',
        sourcemap: true,
    }
}

Ich bekomme:

dist/
    foo/
        index.d.ts
    bar/
        index.d.ts
    fooscript.js
    fooscript.js.map
    barscript.js
    barscript.js.map

Und jetzt gibt es für TypeScript keine Möglichkeit, dist/fooscript.js und dist/foo/index.d.ts zu paaren.

...

Gibt es keine Möglichkeit, dass Ihr Plugin TypeScript den Ziel-/Ausgabepfad für jede JavaScript-Bundle-Datei zuführen kann? Es scheint, dass tsc den ursprünglichen Dateinamen des Eintrags empfängt und ihn beim Generieren der Deklarationen festhält.
...oder suchen Sie für jede der Eingabedateien nach der entsprechenden *.d.ts Datei und verschieben+benennen Sie sie in das Zuordnungsziel der Eingabedatei um. (Ihr merkt vielleicht, dass ich hier aus meinem Arsch rede, also... ;-)

Dies ist etwas, was ich nach dem Abschluss von Rollup unbedingt manuell versuchen werde - aber es wäre so viel schöner, wenn das Plugin dies automatisch verarbeiten würde.

Nein, das Plugin verwendet LanguageServices (die gleichen Typoskript-API-IDEs werden normalerweise verwendet), sodass ich eine gewisse Kontrolle darüber habe, was und wo geschrieben werden soll.

Um eine Typdefinition pro Rollup-Eingabe zu schreiben, müssen wir Definitionen für alle Importe für diese Eingabe zusammenführen. Rollup sieht möglicherweise eine Eingabe-ts-Datei, aber es könnte beim Erstellen eine beliebige Anzahl von Quelldateien importieren und bündeln, die ebenfalls generierte Typen benötigen.

Derzeit irre ich mich bei der Generierung von Definitionen für alles, was Typskript beim Betrachten der tsconfig-Datei findet. Wenn ich nur Typen für transpilierte Module erzeuge, werden Nur-Typ-Dateien ignoriert.

Ich muss diesen Teil vielleicht noch einmal besuchen, die API hat sich seit der Fertigstellung dieses Teils erheblich geändert ...

Ich muss mir mal ansehen, wie dein Beispiel funktioniert. Möglicherweise ist eine bessere Unterstützung für mehrere Bundles in einer Rollup-Konfiguration erforderlich.

Wie verbrauchen Sie dieses Paket, nachdem Sie es erstellt haben? Es ist nicht etwas, das Sie auf npm veröffentlichen und nach Paketnamen importieren können ...

Ich erstelle eine Sammlung von eigenständigen Dienstprogrammen. Der Stammordner des veröffentlichten/installierten Pakets enthält alle erstellten Moduldateien in einer flachen Liste.

(Ich schreibe sie in TS/ES6 in einer verschachtelten Ordnerstruktur mit eingemischten Testdateien und verlasse mich auf Rollup, um sie in eine flache Liste von CJS-Dateien mit einer effizienten Mischung aus Code-Splitting und Inlining für alle zu konvertieren geteilter Code.)

Ich konsumiere diese Tools dann, indem ich sie nach Dateinamen importiere – so:

import tool1 from 'myTools/tool1';
import tool2 from 'myTools/tool2';

Die Idee ist, dass ich ohne einen einzigen Einstiegspunkt für das gesamte Toolkit (keine pkg.main oder pkg.module Einträge) sorgenfrei selten verwendete und sogar experimentelle Tools hinzufügen kann ohne zusätzliches Gewicht/Aufblähen für nachgelagerte Verbraucher (die möglicherweise kein effizientes Tree-Shaking haben).

...Ich habe jetzt ein bisschen mit tsc auf der Kommandozeile gespielt, und ich glaube, ich sehe jetzt die Einschränkungen, mit denen Sie zu tun haben.

Mir ist jedoch aufgefallen, dass, wenn Sie tsc ausführen und das Modul-/Ausgabeformat entweder auf "amd" oder "system" , eine einzelne *.d.ts Datei mit einer übersichtlichen Liste aller generiert wird die notwendigen declare module "..." Blöcke inline.

Ich frage mich, ob dieses Verhalten irgendwie ausgenutzt werden könnte - über das Umbenennen/Verschieben der Datei und das Auspacken/Umschreiben der letzten (Haupt-)Moduldeklaration?


Randbemerkung: Mir ist auch aufgefallen, dass tsc nicht viel Mühe darauf zu verwenden scheint, diese Deklarationsdatei durcheinander zu bringen. In einem Fall sehe ich ein Hauptmodul (Einstiegspunkt), das eine einzelne, sehr einfache Funktionssignatur exportiert, und dennoch legt die Deklarationsdatei Deklarationsblöcke für alle privaten Module offen, die "hinter den Kulissen" verwendet werden. Komisch. :-)

Hallo nochmal.
Im Moment stelle ich ein benutzerdefiniertes declarationDir für tsc , um alle *.d.ts zu speichern, und führe dann ein eigenständiges Skript aus, das die gleiche Eintragsdatei in- output-file-Objekt, wenn ich Rollup füttere, und es generiert Deklarationsdateien auf Bundle-Zielebene, die einfach export * from die eigentliche Deklarationsdatei sind.

Im Wesentlichen generiere ich dist/fooscript.d.ts das nur

export *  from './__types/foo/index';

Es ist ein hässlicher eigenständiger Hack, aber er liefert vorhersehbar korrekte Ergebnisse.

Ich frage mich, ob rollup-plugin-typescript2 etwas Ähnliches tun könnte?

Das würde funktionieren, ja.

Ich habe ein paar Ideen (wenn ich dazu komme), zum Beispiel <bundlename>.d.ts generieren, das eine Menge von /// <reference types=""/> für jeden beteiligten d.ts enthält.

Zuerst muss ich möglicherweise einen verwandten Fehler beheben, bei dem zu viele Typdeklarationen generiert wurden, und dies auf die Root-Datei und alles, was sie tatsächlich importiert, beschränken.

Ein paar Gedanken:

IMO, der einzige wirklich hässliche Teil meines Hacks ist die Tatsache, dass er sich vom Rollup-Prozess unterscheidet. Die Vermittler *.d.ts sind eigentlich eine ziemlich nette und idiomatische Möglichkeit, zwischen Rollups generierten Bundles und den Definitionen von tsc zu überbrücken.

Da die tsc -generierten Deklarationsdateien über relative Pfade aufeinander verweisen, wird diese Datei-/Ordnerstruktur wahrscheinlich am besten in Ruhe gelassen – damit Sie nicht am Ende Teile der Rollup-Funktionalität für eine benutzerdefinierte Sprachsyntax neu implementieren.

Und wenn rollup-plugin-typescript2 etwas wie output.dir + '__types' als Standard- declarationDir rollup-plugin-typescript2 festlegt, dann wird jedes Durcheinander, das durch die Übereifer von tsc verursacht wird, ordentlich aus dem Weg geräumt. Blick in einen klar benannten Ordner. Auf diese Weise werden die überflüssigen Definitionsdateien für IMO zu einem sehr geringen Problem.


FWIW, hier ist das Fleisch meines Skripts:

const { makeInputMap, getEntrypoints, distFolder, srcFolder } = require('./buildHelpers');
const { writeFileSync } = require('fs');
const { relative } = require('path');

const srcPrefixRe = new RegExp('^' + srcFolder + '/');
const tsExtRe = /\.tsx?$/;

const declDirRelative = './' + relative(
  distFolder,
  require('../tsconfig.json').compilerOptions.declarationDir
);

const tsEntrypoints = getEntrypoints()
  .filter((fileName) => tsExtRe.test(fileName));

Object.entries(makeInputMap(tsEntrypoints))
  .forEach(([moduleName, sourcePath]) => {
    const tscDeclFile = sourcePath
      .replace(srcPrefixRe, declDirRelative + '/')
      .replace(tsExtRe, '');
    const outFile = distFolder + '/' + moduleName + '.d.ts';
    writeFileSync(
      outFile,
      [
        'export * from "' + tscDeclFile + '";',
        'import x from "' + tscDeclFile + '";',
        'export default x;',
        '',
      ].join('\n')
    );
  });

console.info('Created local declaration files for TypeScripted entrypoints.');

Ich habe das obige Beispiel aktualisiert, da es den Anschein hat, dass Standardexporte explizit erneut exportiert werden müssen.

Vorläufige Tests zeigen, dass ein blinder Reexport von default aus einer Deklarationsdatei ohne default Export harmlos ist und stillschweigend ignoriert wird. (Zumindest von VSCode.)

Hallo, sollte dieses Problem in v0.23.0 behoben werden?

(...ich frage mich, ob ich versuchen sollte, mein Projekt zu aktualisieren, um alle benutzerdefinierten Faffings zu löschen)

0.23 generiert keine Deklaration für alles, was in Sicht ist, aber es generiert Deklarationen, die Sie tatsächlich in ihren jeweiligen Unterordnern importieren. Sie können wahrscheinlich aktualisieren und leichtere Typen verwenden, aber es gibt noch nichts zum Generieren von Root-Typ-Deklarationen.

Mein benutzerdefiniertes Workaround-Build-Skript (siehe oben) schleicht sich allmählich in immer mehr meiner Projekte ein. o_O

Zu Ihrer Information: Die Entwicklung des offiziellen @rollup/plugin-typescript-Pakets wurde seitdem wieder aufgenommen und bietet jetzt eine Typprüfung und Ausgabe von Deklarationsdateien, also stelle ich persönlich auf diese um.
Die Einschränkungen sind jedoch ähnlich.

@maranomynet Verlassen Sie sich immer noch auf Ihr Skript, um die Deklarationsdateien zu verschieben, nachdem das Rollup seine Sache erledigt hat? Ich hatte nicht viel Glück beim Wechseln.

Jep. das scheint der einzige Weg zu sein, es sei denn, Sie lassen tsc die End-to-End-Bündelung durchführen.
Diese Rollup-Plugins scheinen tsc effektiv zu bitten, zwei verschiedene Aufgaben zu erledigen:

  1. "Überprüfen Sie alle diese einzelnen Module und konvertieren Sie sie in JavaScript" und lassen Sie mich (dh Rollup) das Bündeln und Schreiben auf die Festplatte übernehmen.
  2. "Machen Sie alle Deklarationen für diesen TS-Projektordner und legen Sie sie dort ab."

Die Ergebnisse von 1 und 2 stimmen nicht überein und können nicht übereinstimmen, wenn Sie eine "Eingabezuordnung" und Code-Splitting usw. verwenden. – AFAICT.

...es sei denn, Sie machen das Rollup-Plugin viel stärker in den Prozess der Typdeklaration ein.

Ah ja, das habe ich mir gedacht, danke! Ich habe dir ein 👍 für deine hilfreiche Antwort gegeben und das 👎 ist für meine Meinung dazu.

Irgendein Glück damit?

Für jede kämpfende Seele da draußen, die die gleiche src-Ordnerstruktur hat wie @maranomynet und ich.

Ich bin auf eine schnelle Lösung gestoßen, die vielleicht eine andere hässliche Methode ist, aber für mich funktioniert.

Ich verwende rollup-plugin/typescript2, also gehe ich mit seiner Konfiguration in dieser Antwort vor:
Definieren Sie Ihr eigenes DeclarationDir in Ihrer tsconfig.json, damit Ihr Projekt alle *.d.ts-Dateien in einem eigenen Pfad in der gebündelten Dist speichern kann. Und stellen Sie sicher, dass useTsConfigDeclarationDir in Ihrem Typoskript-Plugin in der Rollup-Konfigurationsdatei auf true gesetzt ist.
Wenn Sie die Ausgabepfade für Ihre einzelnen Komponentenpakete in Ihrer rollup.config.js (und package.json) definieren, ändern Sie diese Pfade außerdem so, dass sie mit Ihrem 'declarationDir' + 'wie Ihre src-Komponentenroute ist' übereinstimmen. Wenn Ihre Komponente in src also wie folgt aussieht:

src/homepage/foo.tsx

Und Ihre ErklärungDir lautet:

dist/MyDeclarationDir

Ihr Ausgabepfad muss also wie folgt aussehen:

dist/MyDeclarationDir/homepage/foo.js

Auf diese Weise enthält Rollup Ihre Typen im selben Verzeichnis wie Ihre Komponente main.js und Ihr TS-Consumer-Projekt nimmt die Typisierungen auf.

Das Bundle sieht also etwa so aus:

Entfernung/

    declarationDirPath/
                  component1/
                        foo.js/
                              foo.js
                              foo.map.js
                        foo.d.ts
                   component2/
                        bar.js/
                               bar.js
                               bar.map.js
                        bar.d.ts
War diese Seite hilfreich?
0 / 5 - 0 Bewertungen