Ecrire des modules NPM dans Typescript

103

Je travaille sur mon premier module NPM. J'ai brièvement travaillé avec dactylographié auparavant et un gros problème était que pour de nombreux modules, il n'y avait pas de fichiers de définition disponibles. J'ai donc pensé que ce serait une bonne idée d'écrire mon module en tapuscrit.

Cependant, je ne trouve aucune information sur la meilleure façon de procéder. J'ai trouvé cette question connexe " Puis-je écrire le package npm dans coffeescript? " Où les gens suggèrent de publier uniquement les fichiers javascript. Mais contrairement aux fichiers coffeescript, les fichiers dactylographiés peuvent en fait être utiles s'ils sont utilisés dans une application dactylographiée.

Dois-je inclure des fichiers Typescript lors de la publication d'un module NPM, ou dois-je publier uniquement les fichiers javascript et fournir les fichiers .d.ts générés à DefinitelyTyped?

Andreas Gassmann
la source
2
Notes utiles: J'ai écrit le projet, copee , avec un article de blog pour vous guider dans la configuration d'un projet TS pour émettre des définitions de type avec les cibles CJS et ESM avant de publier sur npm. Cela maximisera l'utilisation avec node.js et les navigateurs à l'avenir.
styfle

Réponses:

84

Voici un exemple de module Node écrit en TypeScript: https://github.com/basarat/ts-npm-module

Voici un exemple de projet TypeScript qui utilise cet exemple de module https://github.com/basarat/ts-npm-module-consume

Fondamentalement, vous devez:

  • compiler avec commonjsetdeclaration:true
  • générer un .d.tsfichier

Puis

  • Demandez à votre idée de lire le fichier généré .d.ts.

Atom-TypeScript fournit juste un bon flux de travail autour de ceci: https://github.com/TypeStrong/atom-typescript#packagejson-support

basarat
la source
Le lien d'ancrage Atom-TypeScript doit être mis à jour (l'ancre n'est plus valide).
Fidan Hakaj
@basarat, dans ts-npm-module vous utilisez "version": "1.5.0-alpha". Je suppose que c'est la version de Typescript avec laquelle vous transposez. Est-ce important de laisser cela de côté? (ce n'est pas fait automatiquement par le plugin Atom). Si une version est utilisée, cela obligera-t-il d'autres utilisateurs à utiliser la version exacte pour transpiler (ou seulement les plus récentes)? (ou peut-être que c'est la version de tsconfig.json?)
justin
Avez-vous un cas d'utilisation avec des modules dépendant d'autres bibliothèques? Pour éviter le problème de définition en double, vous devez configurer tsconfig.json, mais cela semble trop manuel à mon avis.
Sérgio Michels
1
préconiseriez-vous toujours cette approche au quatrième trimestre 2016?
SuperUberDuper
7
C'était un bon guide pratique
tsmean.com/articles/how-to-write-a-typescript-library
78

Avec TypeScript 3.x ou TypeScript 2.x, les étapes suivantes décrivent ce que vous devez faire pour créer une bibliothèque (package npm) avec TypeScript:

  • Créez votre projet comme vous le feriez normalement (avec des tests et tout)
  • Ajoutez declaration: trueà tsconfig.jsonpour générer des typages.
  • Exportez l'API via un index.ts
  • dans le package.json , pointez sur vos typages générés. Par exemple, si outDirc'est le cas dist, ajoutez "types": "dist/index.d.ts"à votre package json.
  • dans le package.json , pointez sur votre fichier d'entrée principal. Par exemple, si votre outDirest distet le fichier d'entrée principal est index.js, ajoutez "main": "dist/index.js"à votre package.json.
  • Créez un .npmignorepour ignorer les fichiers inutiles (par exemple la source).
  • Publiez sur npm avec npm publish. Utiliser les spécifications semver pour les mises à jour (correctif / correction de boguenpm version patch , ajouts sans rupture npm version minor, changements de rupture d'API npm version major)

Puisqu'il m'a fallu un certain temps pour passer au crible toutes les ressources obsolètes sur ce sujet sur Internet (comme celle de cette page ...), j'ai décidé de conclure dans comment-écrire-une-bibliothèque-typographique avec un exemple minimal de travail à jour.

bersling
la source
Dois-je enregistrer les js dans le contrôle de code source? Ou npm conserve-t-il sa propre version du code?
Olian04 le
1
@ Olian04 Vous dites à create an .npmignorefile d'indiquer à npm quels fichiers ignorer lors de la publication (les .tsfichiers) et .gitignoreà a d'indiquer à git quels fichiers ignorer ( dist/)
Purag
@ Olian04 non, vous n'avez pas besoin de (et IMO ne devrait pas) valider le (s) fichier (s) JS généré (s). Ceux-ci ne font pas partie de la source du projet.
Josh M.
59

Voici une réponse plus récente utilisant TypeScript 1.8.10:

La structure de mon projet est:

|
|--- 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

J'ai ajouté ce qui suit .npmignorepour éviter d'inclure des fichiers superflus et garder le strict minimum pour que le package soit importé et fonctionne:

node_modules/
*.log
*.tgz

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

Mon .gitignorea:

typings

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

Mon package.jsona:

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

Maintenant je cours: npm pack

Le fichier résultant (une fois décompressé) a la structure suivante:

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

Maintenant, je vais au projet où je veux utiliser ceci comme bibliothèque et tapez: npm install ./project-1.0.0.tgz

Il s'installe avec succès.

Maintenant je crée un fichier index.ts dans mon projet où je viens d'installer le npm import Project = require("project");

Dactylographie Project. me donne les options Intellisense qui étaient le point de tout cet exercice.

J'espère que cela aidera quelqu'un d'autre à utiliser leurs projets TypeScript npm comme bibliothèques internes dans leurs projets plus importants.

PS: Je crois que cette approche de compilation de projets en modules npm qui peuvent être utilisés dans d'autres projets rappelle le .dlldans le.NET monde. Je pourrais bien imaginer des projets organisés dans une solution dans VS Code où chaque projet produit un package npm qui peut ensuite être utilisé dans un autre projet de la solution en tant que dépendance.

Puisqu'il m'a fallu beaucoup de temps pour comprendre cela, je l'ai publié au cas où quelqu'un serait coincé ici.

Je l'ai également posté pour un bug fermé à: https://github.com/npm/npm/issues/11546


Cet exemple a été téléchargé sur Github: vchatterji / tsc-seed

Varun Chatterji
la source
pourriez-vous télécharger un exemple sur github? Cela aiderait beaucoup! :)
Han Che
3
L'exemple a été téléchargé sur Github: github.com/vchatterji/tsc-seed
Varun Chatterji
Comment peut-il également être utilisé dans des projets non typographiques?
SuperUberDuper
5

Vous devez publier les sources dactylographiées d'origine au lieu de la définition de type. Dans package.jsonlaissez la propriété 'types' pointer vers le fichier * .ts.

*.d.ts sont bons pour annoter les bibliothèques JS existantes, mais en tant que consommateur, je préfère lire le code dactylographié plutôt que de basculer entre les définitions de type et le code JS généré de bas niveau.

Sven Efftinge
la source
1
Le compilateur TypeScript ne semble pas être adapté à cela jusqu'à présent. Voir ce numéro github.com/Microsoft/TypeScript/issues/14479
Sven Efftinge
2
L'inclusion actuelle *.d.tsest la manière recommandée de le faire, même si je suis d'accord avec vous les avantages d'inclure des *.tsfichiers, typescriptlang.org/docs/handbook/declaration-files/…
Tim
5

Je suis principalement la suggestion de Varun Chatterji

Mais, je voudrais montrer un exemple complet avec des tests unitaires et une couverture de code et le publier npmet les importer en utilisant javascriptoutypescript

Ce module est écrit en utilisant typescript 2.2et il est important de configurer le prepublishhook pour compiler le code en utilisanttsc avant de le publier sur npm

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

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

Tim
la source
1
C'est un exemple très utile, merci pour le partage! J'essaie actuellement également de comprendre la création de packages de cette manière.
Jeffrey Westerkamp le
1
En juillet 2017, c'est la meilleure structure de projet que j'ai rencontrée. Merci à Tim et Varun Chatterji
adgang
3

Vous pouvez utiliser autodts pour gérer la distribution et l'utilisation de .d.tsfichiers de npm également sans prise en charge de l'IDE Atom.

autodts generateregroupera tous vos propres .d.tsfichiers pour les publier sur npm, et autodts linkgère les références à d'autres packages installés, qui peuvent ne pas toujours être directement sous node_modulesdans un projet plus vaste divisé en plusieurs sous-packages.

Les deux commandes lisent leurs paramètres depuis package.jsonet tsconfig.jsondans le style «convention sur la configuration».

Il y a une autre réponse sur stackoverflow et un article de blog avec plus de détails.

jjrv
la source