Comment décider si @ types / * va dans `dependencies` ou` devDependencies`?

229

J'utilise TypeScript 2 dans mon projet. Je voudrais utiliser une bibliothèque js, mais aussi des typages pour cette bibliothèque. Je peux installer des types avec simple npm install @types/some-library. Je ne sais pas si je devrais --saveou --save-deveux. Il me semble que même le fichier readme de DefinetelyTyped GitHub mentionne les deux versions, mais ne les explique jamais. Je pense que @types devrait être dans devDependencies, car les types sont nécessaires pour le développement et ne sont pas utilisés dans le runtime, mais j'ai vu plusieurs fois @types juste dependencies. Je suis confus.

Comment dois-je décider si @ types / * entre dependenciesou devDependencies? Existe-t-il en fait des instructions plus ou moins officielles?

Kamyl
la source
Générez-vous un bundle ou s'agit-il d'un package qui sera utilisé par d'autres? Selon moi, il vous suffit de faire la distinction entre dependencieset devDependenciesdans ce dernier cas.
Valentin
Je crée un jeu en js / ts à partir de zéro. Je regroupe tout avec webpack. Il n'y a pas de backend du tout, mais il est possible que j'emballe tout cela dans Electron pour le rendre autonome un jour. Je ne pense pas que quiconque l'utilisera jamais comme dépendance dans sa propre application, mais je suppose que cela pourrait être possible (pensez aux mini-jeux dans les jeux GTA; et mon jeu est open source). Pourtant, je veux apprendre et suivre les meilleures pratiques et c'est la principale raison pour laquelle je crée ce jeu. J'espère avoir suffisamment clarifié mon cas d'utilisation. :)
kamyl
1
Oui, cela a du sens, je voulais juste m'assurer que ma réponse originale était pertinente pour votre cas d'utilisation. Je pense toujours que la distinction entre devDependencieset dependenciesn'est pas pertinente lors de la construction d'un bundle, c'est quelque chose qui create-react-apps'applique aussi mais finalement c'est à vous de choisir
Valentin

Réponses:

158

Supposons que vous développiez un package "A" contenant le package @ types / some-module dans devDependencies. Pour une raison quelconque, vous exportez le type depuis @ types / some-module

import {SomeType} from 'some-module';
export default class APackageClass {
     constructor(private config: SomeType) {

     }
}

Pour le moment, les consommateurs Typescript du paquet "A" ne peuvent pas deviner ce qu'est SomeType, puisque devDependencies du paquet "A" ne sont PAS installés.

Dans ce cas particulier, vous DEVEZ placer le package @ types / * avec des "dépendances" régulières. Pour les autres cas, "devDependencies" est suffisant.

wookieb
la source
8
Donc, vous impliquez que, si j'utilise uniquement le type dans l'implémentation, sa définition de type peut être devDependencies?
Franklin Yu
8
Oui @FranklinYu. Dès que le type apparaît dans le fichier de déclaration, vous devez le placer dependencies. Sinon, devDependenciesc'est bien
wookieb
1
Mais un package fonctionne à la fois pour TS et JS. Les développeurs JS n'ont pas besoin de ces types pour compiler leur code. L'ajout de la définition de type dependenciesrendra l'arborescence des dépendances gonflée.
Tyler Long
2
@TylerLong Correct. Ce n'est pas parfait mais c'est la réalité. En option, vous pouvez également utiliser "optionalDependencies" mais je pense qu'à grande échelle, cela peut être très ennuyeux.
wookieb
59

Si vous ne faites que générer un bundle, il n'est peut-être pas nécessaire de faire la distinction entre dependencieset devDependencies. Cette fonctionnalité de npmest généralement utile lors de la publication d'un package qui peut être utilisé par d'autres et vous ne voulez pas les spammer avec des dépendances redondantes.

Il peut y avoir d'autres cas d'utilisation où le fractionnement des dépendances peut être utile, mais à moins que vous n'en ayez un besoin express, mon conseil est de choisir l'un ou l'autre et de tout y placer. Il n'est pas difficile de les diviser par la suite si le besoin s'en fait sentir.

Un exemple bien connu de cette pratique IRL est create-react-app, par défaut, le passe-partout non éjecté dans lequel il crée place tout dependencies, voir ce fil et cette réponse

Valentin
la source
9
Si vous ne publiez pas le package, c'est correct, mais si vous l'êtes, cela n'a rien à voir avec le développement par rapport à l'exécution et tout ce qui est nécessaire pour créer ce package par rapport à ce qui est nécessaire pour utiliser ce package .
Yogu
1
@Yogu C'est pourquoi j'ai fait la distinction en premier lieu alors oui, je suis complètement d'accord avec vous
Valentin
16
Je ne suis pas d'accord avec ce conseil. devDependenciesne sont pas installés lorsque vous le faites npm install --production(ou npm ci --production) et ne sont donc pas disponibles lors de l'exécution du code de production. C'est une différence très significative pour un service, pas seulement pour une bibliothèque.
Brad Wilson
2
@BradWilson Vous avez raison, il existe de nombreux workflows npm sous le soleil, si votre cas d'utilisation vous oblige à faire la distinction, alors faites-le. N'hésitez pas à apporter votre propre réponse à ce dilemme.
Valentin
J'ai mis à jour ma réponse pour mentionner l'existence d'autres cas d'utilisation où la distinction peut être significative et j'ai donné des exemples du monde réel. Merci pour les commentaires!
Valentin
20

Dans le cas particulier du déploiement d'une application Node.js en production, on souhaite installer uniquement les dépendances nécessaires à l'exécution de l'application.

npm install --production ou

npm ci --production ou

yarn --production

Dans ce cas, les types doivent être dans le devDependencies, pour les empêcher de gonfler l'installation.

Remarque: je sais que cela a été mentionné dans un commentaire de Brad Wilson à une autre réponse. Ce point semble toutefois digne d'être une réponse.

Carsten Führmann
la source