web-dev-qa-db-fra.com

Alias ​​du chemin d'importation TypeScript

Je travaille actuellement sur une application TypeScript composée de plusieurs modules Node) écrits en TypeScript et installés dans le répertoire node_modules.

Avant de continuer, je voudrais noter que j'utilise TypeScript 2.0 et que, si nécessaire, je suis également opposé à l’utilisation de la version 2.1. Je veux juste que ça marche.

La structure de chaque module Node) ressemble à quelque chose comme:

dist/
    es2015/
        index.js
        utils/
            Calculator.js
            Calculator.d.ts
            Date.js
            Date.d.ts
            Flatpack.js
            Flatpack.d.ts
src/
    index.ts
    utils/
        Calculator.ts
        Date.ts
        Flatpack.ts

Le dossier dist est la source générée, ce chemin étant configuré avec outDir à l'intérieur de mon fichier tsconfig.json. J'ai également configuré la propriété main dans mon package.json Pour qu'elle soit dist/es2015/index.js.

Points importants à noter:

  • Dans mon projet, j'utilise moduleResolution type de node
  • J'utilise TypeScript 2.0
  • Je ne demande pas comment importer un fichier à partir du package. J'installe le paquet via Npm puis je l'importe via packagename/ Depuis une application utilisant ce module.

Maintenant vient ma question/problème. Lors de l'importation de fichiers de ce module, j'aimerais pouvoir faire ceci:

import {Sin, Cos, Tan} from "common-utils/utils/Calculator";

Toutefois, le fichier ne peut pas être résolu dans le répertoire dist/es2015/utils. Idéalement, j'aimerais que mes importations soient résolues à partir de ce dossier spécifique dist et non à partir de la racine, ce qui semble se produire.

L'importation ci-dessus doit être écrite comme suit pour que cela fonctionne:

import {Sin, Cos, Tan} from "common-utils/dist/es2015/utils/Calculator";

Cependant, écrire dist/es2015 À chaque fois n'est pas idéal et donne l'impression que certaines des importations ont l'air très longues. Est-il possible de configurer mon module pour le résoudre dans le répertoire dist/es2015? Je ne veux pas avoir à mettre en place des remplacements à l'intérieur de mon projet, idéalement, chaque module devrait spécifier où les fichiers sont résolus.

Si vous ne savez toujours pas ce que je vous demande (et je m'excuse si cela est déroutant) dans Jspm lorsque vous créez un plugin/module à utiliser avec Jspm, vous pouvez spécifier dans le package.json Du module quelque chose comme le suivant:

  "jspm": {
    "registry": "npm",
    "jspmPackage": true,
    "main": "my-module",
    "format": "AMD",
    "directories": {
      "dist": "dist/AMD"
    },

Je cherche l'équivalent de ce qui précède dans TypeScript (s'il existe). Une directive de mappage, donc lorsque l'utilisateur final exécute npm install my-cool-package Puis essaie d'importer quelque chose dans son application, toutes les importations par défaut sont résolues dans le répertoire commonjs (l'exemple ci-dessus pour Jspm utilise AMD, mais même prémisse).

Est-ce possible ou ai-je mal compris quelque chose ici? Je sais que de nouvelles fonctionnalités de mappage de chemin ont été ajoutées à la dernière version, mais la documentation sur leur utilisation est presque inexistante.

49
Dwayne Charrington

Donc, après avoir lu votre commentaire, j'ai réalisé que j'avais mal compris votre question! Si vous souhaitez contrôler les chemins du point de vue d'un paquet importé, utilisez simplement set la propriété main de votre package.json vers un fichier qui représente correctement le graphe d'objets de votre module.

{
  "main": "common-utils/dist/es2015/index.js"
}

Si vous essayez de contrôler les chemins d'importation du point de vue d'un projet, vous recherchez la nouvelle fonctionnalité de mappage des chemins d'accès de TypeScript 2 pour la résolution des modules. Vous pouvez activer le mappage de chemin en configurant votre tsconfig.json comme suit:

{
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "angular2/*": ["../path/to/angular2/*"],
      "local/*": ["../path/to/local/modules/*"]
    }
  }
}

Ensuite, dans vos fichiers TypeScript, vous pouvez importer les modules comme suit:

import { bootstrap } from 'angular2/bootstrap';
import { module } from 'local/module';

Pour plus de détails sur la fonctionnalité de mappage de chemin d'accès dans TypeScript 2, voir problème de Github .

Dans votre cas, je pense que la configuration suivante devrait fonctionner:

{
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "common-utils/utils/*": ["./node_modules/common-utils/dist/es2015/utils/*"]
    }
  }
}
105
fny

Si vous utilisez des chemins, vous devrez reconvertir les chemins absolus en chemins relatifs pour que celui-ci fonctionne après la compilation de TypeScript en javascript ordinaire à l'aide de tsc.

La solution la plus populaire pour cela a été tsconfig-path jusqu'à présent.

Je l'ai essayé, mais cela n'a pas fonctionné pour mon installation compliquée. En outre, il résout les chemins au moment de l’exécution, ce qui signifie une surcharge en termes de taille de votre package et de résolution des performances.

J'ai donc écrit une solution moi-même, tscpaths .

Je dirais que c'est globalement meilleur parce que cela remplace les chemins au moment de la compilation. Cela signifie qu'il n'y a pas de dépendance à l'exécution ni de surcharge de performances. C'est assez simple à utiliser. Vous devez juste ajouter une ligne à vos scripts de compilation dans package.json.

Le projet est assez jeune, il pourrait donc y avoir des problèmes si votre configuration est très compliquée. Cela fonctionne parfaitement pour ma configuration, bien que ma configuration soit assez complexe.

4
Joon