83 votes

Comment utiliser les références de projet dans TypeScript 3.0 ?

Il y a cette nouvelle fonctionnalité dans TypeScript 3.0 appelée Références du projet . Il suggère une meilleure interaction de *.ts entre eux. Malheureusement, c'est tout ce que j'ai pu obtenir de la documentation officielle, bien qu'elle semble être écrite de manière assez claire et simple.

Quelqu'un peut-il m'aider à comprendre exactement, quels sont les problèmes qu'il résout, comment il le fait, et comment j'en bénéficierais ? J'ai un projet avec une structure similaire, donc il pourrait (ou ne pourrait pas) être très utile pour lui. Merci d'avance !


UPD : La structure du projet est à peu près la même :

project/
    lib/
        index.ts # defines the original code
    test/
        index.spec.ts # requires lib/index.ts
    package.json
    tsconfig.json

154voto

Dmitry Parzhitsky Points 704

TL;DR :

Cette fonctionnalité permet de définir des parties du projet en tant que modules TypeScript distincts. Cela permet, entre autres, de configurer ces modules différemment, de les construire séparément, etc.


Avant

Au départ, le structure du projet Une fois simplifié, le résultat est similaire à ceci :

/
    src/
        entity.ts # exports an entity
    test/
        entity.spec.ts # imports an entity
    tsconfig.json

Une entité est <a href="https://github.com/parzh/re-scaled/blob/50afae2e1ad7c2dd1799a4b92e77efd7d58aa1f9/src/index.ts#L3" rel="noreferrer">défini dans <code>src/entity.ts</code> module </a>et ensuite <a href="https://github.com/parzh/re-scaled/blob/50afae2e1ad7c2dd1799a4b92e77efd7d58aa1f9/test/unit/combined.spec.ts#L5" rel="noreferrer">utilisé dans <code>test/entity.spec.ts</code> fichier </a>.

Remarquez qu'il n'y a qu'un seul tsconfig.json ici, dans le dossier Root. Cela signifie essentiellement que ce dossier contient un gros projet TypeScript solide. Ce projet comprend un certain nombre de fichiers, organisés en dossiers ; certains de ces fichiers sont utilisés pour en tester d'autres.

Cette structure impose cependant un problème : le processus de compilation du projet (à savoir, tsc ) compile également les fichiers de test, créant ainsi dist/test/entity.spec.{js|d.ts} dans la sortie. Cela ne devrait pas se produire, c'est pourquoi l'option tsconfig.json est légèrement modifié pour n'inclure que les fichiers/dossiers destinés à un usage extérieur :

{
    "compilerOptions": {
        // compiler options
    },
    "include": [
        "./src"
    ]
}

Cela résout le problème, mais dans mon cas, cela a également conduit à ce que tous les fichiers du répertoire /test étant occasionnellement ignorés par le compilateur TypeScript au cours du processus de développement. En outre, cette approche exclusive peut ne pas convenir à tout le monde.


Après

Après en utilisant la fonction la structure du projet a changé comme suit :

/
    src/
        entity.ts # exports an entity
        tsconfig.json
    test/
        entity.spec.ts # imports an entity
        tsconfig.json
    tsconfig-base.json

Passons en revue les changements :

  1. Renommer /tsconfig.json a /tsconfig-base.json est une chose assez importante en soi : le dossier Root n'est plus un projet TypeScript, puisque tsc exige que le tsconfig.json doit être présent.
  2. D'autre part, l'ajout de src/tsconfig.json y test/tsconfig.json Les fichiers tournent à la fois src y test en deux projets TypeScript distincts, indépendants l'un de l'autre.

Le contenu de /{src|test}/tsconfig.json sont similaires car aucune modification de la configuration n'était attendue, c'est-à-dire que la "rigueur", le dossier de sortie, ainsi que d'autres paramètres de ce type, devraient être préservés. Afin de les rendre similaires sans copier-coller quoi que ce soit, toutes les configurations sont placées dans un fichier arbitraire accessible depuis les deux endroits ; dans ce cas, la tsconfig-base.json dans le dossier racine a été sélectionné pour cela :

// the contents of /tsconfig-base.json
{
    "compilerOptions": {
        // compiler options, common to both projects
    }
}

Ce fichier est "hérité" alors par /{src|test}/tsconfig.json avec l'ajout de toute autre option si nécessaire :

// the contents of /{src|test}/tsconfig.json
{
    "extends": "../tsconfig-base.json",
    "compilerOptions": {
        // additional compiler options, specific to a project
    }
}

Remarquez que ce modèle est similaire à la définition d'un abstract class avec une implémentation incomplète, puis en l'étendant par deux classes "concrètes" distinctes.

Maintenant, /src y /test Les dossiers contiennent essentiellement deux projets TypeScript distincts avec des configurations similaires. La dernière chose à faire est de spécifier la relation entre les deux. Puisque test dépend de src le test doit d'une certaine manière "savoir" à propos src . Cela se fait en deux étapes assez évidentes :

  • permettre src pour être "référencé" de l'extérieur en le déclarant comme "composite" :

    // in /src/tsconfig.json
    {
        "extends": "../tsconfig-base.json",
        "compilerOptions": {
            // compiler options
            "composite": true
        }
    }
  • référence src de test :

    // in /test/tsconfig.json
    {
        "extends": "../tsconfig-base.json",
        "references": [
            { "path": "../src" }
        ]
    }

El "include" dans /tsconfig-base.json n'est pas nécessaire maintenant puisque l'exclusion du code se fait en "dessinant de nouvelles frontières".

MISE À JOUR : la section suivante semble être périmée depuis TypeScript 3.7

Maintenant, le test le projet nécessite *.d.ts pour le src projet pour être présent. Cela signifie qu'avant d'exécuter les tests, le projet src devrait déjà être construit, séparément. Ceci est fait par en utilisant le nouveau mode de tsc déclenché par le --build option :

tsc --build src

Cette commande construit le src et place la sortie dans le dossier de sortie spécifié (dans ce cas, /dist ), sans pour autant briser test et ne perd pas d'erreurs de compilation.

2 votes

Merci d'avoir pris le temps d'écrire ceci Dmitry, j'apprécie votre perspicacité.

1 votes

@Clark Heureux d'aider !

45 votes

J'aimerais que les documents officiels soient aussi clairs que cette réponse. Merci !

3voto

JasonS Points 1312

C'est pour les bibliothèques TypeScript que vous développez, qui sont utilisées par d'autres applications TypeScript. Donc par exemple, si vous créez une bibliothèque util comme lodash mais que vous le développez activement en même temps que votre application dépendante, la references dans ``tsconfig.json`` vous permet de référencer le code source, et de faire en sorte que votre application dépendante soit reconstruite automatiquement lorsque la source util change (c'est-à-dire : tsc détecte les changements de code source dans la librairie util ts)

Dans mon cas précis, j'utilise le references en collaboration avec npm link et git submodules et ça marche beaucoup mieux que dans le passé. ts 2.x jours.

0 votes

J'ai ajouté une représentation approximative de la structure du projet. Si j'ai bien compris votre réponse, il serait logique de créer project/test/tsconfig.json en spécifant project/lib/index.ts dans son references n'est-ce pas ? Cela semble un peu bizarre, alors corrigez-moi si je me trompe.

0 votes

@DmitryParzhitsky vous pouvez regarder mon projet open source typescript pour un exemple. cherchez npm pour "xlib" et "phantomjscloud". le premier est la bibliothèque, le second l'utilise. Localement, je fais en sorte que phantomjscloud référence xlib via npm link xlib

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X