Scrittura di moduli NPM in Typescript


103

Sto lavorando al mio primo modulo NPM. Ho lavorato brevemente con il dattiloscritto prima e un grosso problema era che per molti moduli non c'erano file di definizione disponibili. Quindi ho pensato che sarebbe stata una buona idea scrivere il mio modulo in dattiloscritto.

Tuttavia, non riesco a trovare alcuna informazione sul modo migliore per farlo. Ho trovato questa domanda correlata " Posso scrivere il pacchetto npm in coffeescript? " In cui le persone suggeriscono di pubblicare solo i file javascript. Ma a differenza dei file coffeescript, i file dattiloscritti potrebbero effettivamente essere utili se vengono utilizzati all'interno di un'applicazione dattiloscritta.

Devo includere file Typescript quando pubblico un modulo NPM, o devo pubblicare solo i file javascript e fornire i file .d.ts generati a DefinitelyTyped?


2
Note utili: ho scritto il progetto, copee , insieme a un post sul blog per guidarti attraverso l'impostazione di un progetto TS per emettere definizioni di tipo insieme a obiettivi CJS ed ESM prima della pubblicazione su npm. Ciò massimizzerà l'utilizzo con node.js e browser in futuro.
stile

Risposte:


84

Ecco un modulo Node di esempio scritto in TypeScript: https://github.com/basarat/ts-npm-module

Ecco un progetto TypeScript di esempio che utilizza questo modulo di esempio https://github.com/basarat/ts-npm-module-consume

Fondamentalmente devi:

  • compilare con commonjsedeclaration:true
  • generare un .d.tsfile

E poi

  • Chiedi al tuo ide di leggere il file generato .d.ts.

Atom-TypeScript fornisce solo un bel flusso di lavoro attorno a questo: https://github.com/TypeStrong/atom-typescript#packagejson-support


Il collegamento di ancoraggio Atom-TypeScript deve essere aggiornato (l'ancora non è più valida).
Fidan Hakaj

@basarat, in ts-npm-module stai usando "version": "1.5.0-alpha". Presumo che questa sia la versione di Typescript con cui stai transpilando. È importante lasciarlo fuori? (non viene eseguito automaticamente dal plugin Atom). Se viene utilizzata una versione, questo richiederà ad altri utenti di utilizzare la versione esatta per il transpile (o solo quelli più recenti)? (o forse è la versione di tsconfig.json?)
justin

Hai qualche caso d'uso con moduli dipendenti da altre librerie? Per evitare il problema della duplicazione della definizione è necessario configurare tsconfig.json, ma a mio parere questo sembra troppo manuale.
Sérgio Michels

1
Sosterreste ancora questo approccio nel quarto trimestre del 2016?
SuperUberDuper


78

Con TypeScript 3.x o TypeScript 2.x, i seguenti passaggi descrivono cosa è necessario fare per creare una libreria (pacchetto npm) con TypeScript:

  • Crea il tuo progetto come faresti normalmente (con test e tutto)
  • Inserisci declaration: true a tsconfig.jsonper generare digitazioni.
  • Esporta l'API tramite un file index.ts
  • Nella package.json, punta alle tue digitazioni generate. Ad esempio, se lo outDirè dist, aggiungi"types": "dist/index.d.ts" al tuo pacchetto json.
  • In package.json, punta al tuo file di ingresso principale. Ad esempio, se il tuo outDirè diste il file della voce principale è index.js, aggiungi "main": "dist/index.js"al tuo package.json.
  • Crea un .npmignoreper ignorare i file non necessari (es. L'origine).
  • Pubblica su npm con npm publish. Usa le specifiche semver per gli aggiornamenti (patch / correzione di bug npm version patch, aggiunte senza interruzioni npm version minor, modifiche alle API interrotte npm version major)

Dato che mi è servito un po 'di tempo per vagliare tutte le risorse obsolete su questo argomento su Internet (come quella in questa pagina ...), ho deciso di racchiuderlo nella libreria di come scrivere un dattiloscritto con una esempio minimo di lavoro aggiornato.


Dovrò registrare il js nel controllo del codice sorgente? O npm mantiene la propria versione del codice?
Olian04

1
@ Olian04 Dici a creare un .npmignorefile per dire a npm quali file ignorare durante la pubblicazione (i .tsfile) e a .gitignoreper dire a git quali file ignorare ( dist/)
Purag

@ Olian04 no, non è necessario (e IMO non dovrebbe) eseguire il commit dei file JS generati. Quelli non fanno parte della fonte del progetto.
Josh M.

59

Questa è una risposta più recente utilizzando TypeScript 1.8.10:

La struttura del mio progetto è:

|
|--- src
|--- test
|--- dist     <= My gulp file compiles and places the js, sourcemaps and .d.ts files here
|      |--- src
|      |--- test
|--- typings
.gitignore
.npmignore
gulpfile.js
package.json
README.md
tsconfig.json
tslint.json
typings.json

Ho aggiunto quanto segue .npmignoreper evitare di includere file estranei e mantenere il minimo indispensabile per importare e funzionare il pacchetto:

node_modules/
*.log
*.tgz

src/
test/
gulpfile.js
tsconfig.json
tslint.json
typings.json
typings
dist/test

Il mio .gitignoreha:

typings

# ignore .js.map files
*.js.map
*.js
dist

Il mio package.jsonha:

"main": "dist/src/index.js",
"typings":  "dist/src/index.d.ts",

Adesso corro: npm pack

Il file risultante (quando decompresso) ha la seguente struttura:

|
|--- dist
|       |--- src
|              |
|              index.js
|              index.js.map
|              index.d.ts
|
package.json
README.md

Ora vado al progetto in cui voglio usarlo come libreria e digito: npm install ./project-1.0.0.tgz

Si installa con successo.

Adesso creo un file index.ts nel mio progetto in cui ho appena installato npm import Project = require("project");

Digitando Project. mi offre le opzioni Intellisense che erano il punto di tutto questo esercizio.

Spero che questo aiuti qualcun altro a utilizzare i loro progetti npm TypeScript come librerie interne nei loro progetti più grandi.

PS: credo che questo approccio alla compilazione di progetti in moduli npm che possono essere utilizzati in altri progetti ricordi il.dll il .NETmondo. Potrei ben immaginare progetti organizzati in una soluzione in VS Code in cui ogni progetto produce un pacchetto npm che può quindi essere utilizzato in un altro progetto nella soluzione come dipendenza.

Dato che ci è voluto un bel po 'di tempo per capirlo, l'ho pubblicato nel caso qualcuno fosse bloccato qui.

L'ho anche pubblicato per un bug chiuso su: https://github.com/npm/npm/issues/11546


Questo esempio è stato caricato su Github: vchatterji / tsc-seed


potresti caricare un esempio su GitHub? Questo aiuterebbe molto! :)
Han Che

3
L'esempio è stato caricato su Github: github.com/vchatterji/tsc-seed
Varun Chatterji

Come può essere utilizzato anche in progetti non dattiloscritti?
SuperUberDuper

5

Dovresti pubblicare le fonti originali del dattiloscritto invece della definizione del tipo. In package.jsonlet la proprietà 'types' punta al file * .ts.

*.d.ts sono utili per annotare le librerie JS esistenti, ma come consumatore preferisco leggere il codice dattiloscritto piuttosto che passare da una definizione di tipo a un codice JS di livello inferiore e generato.


1
Il compilatore TypeScript sembra non essere adatto a questo finora. Vedi questo numero github.com/Microsoft/TypeScript/issues/14479
Sven Efftinge

2
attualmente includere *.d.tsè il modo consigliato per farlo, anche se sono d'accordo con te sui vantaggi di includere *.tsfile, typescriptlang.org/docs/handbook/declaration-files/…
Tim

5

Seguo principalmente il suggerimento di Varun Chatterji

Tuttavia, vorrei mostrare un esempio completo con test di unità e copertura del codice e pubblicarlo in npme importarli utilizzandojavascript otypescript

Questo modulo è scritto usando typescript 2.2ed è importante configurare l' prepublishhook per compilare il codice usandotsc prima di pubblicarlo su npm

https://github.com/sweetim/haversine-position

https://www.npmjs.com/package/haversine-position


1
Questo è un esempio molto utile, grazie per la condivisione! Attualmente sto anche cercando di imparare a creare pacchetti in questo modo.
Jeffrey Westerkamp

1
A partire da luglio 2017, questa è la migliore struttura di progetto in cui mi sono imbattuto. Grazie a Tim e Varun Chatterji
adgang

3

È possibile utilizzare autodts per gestire la distribuzione e l'utilizzo di .d.tsfile da npm anche senza il supporto dell'IDE Atom.

autodts generateraggrupperà tutti i tuoi .d.tsfile insieme per la pubblicazione su npm e gestirà autodts linki riferimenti ad altri pacchetti installati, che potrebbero non essere sempre direttamente sotto node_modulesin un progetto più grande diviso in diversi sottopacchetti.

Entrambi i comandi leggono le loro impostazioni da package.jsone tsconfig.jsonnello stile "convenzione sulla configurazione".

C'è un'altra risposta su stackoverflow e un post sul blog con maggiori dettagli.


Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.