web-dev-qa-db-fra.com

Comment avoir des chemins d'importation absolus dans un projet de bibliothèque?

J'ai une bibliothèque avec un espace de travail contenant deux projets, un pour la bibliothèque elle-même et un pour une application de test.

├── projects
    ├── midi-app
    └── midi-lib

Dans l'espace de travail tsconfig.json fichier j'en ai configuré @app et @lib chemins:

"paths": {
  "@app/*": ["projects/midi-app/src/app/*"],
  "@lib/*": ["projects/midi-lib/src/lib/*"],
  "midi-lib": [
    "dist/midi-lib"
  ],
  "midi-lib/*": [
    "dist/midi-lib/*"
  ]
}

Il y a un projects/midi-lib/tsconfig.lib.json fichier qui s'étend sur le dessus tsconfig.json fichier:

"extends": "../../tsconfig.json",

Il y a un public-api.ts fichier contenant:

export * from './lib/midi-lib.module';

Je peux très bien utiliser cette bibliothèque avec l'application de test.

Mais lorsque j'essaie de l'utiliser dans une autre application cliente, dans un autre espace de travail, importée en tant que module Node, j'obtiens de nombreuses erreurs sur les chemins inconnus Can't resolve '@lib/...'

Comment exprimer les chemins de bibliothèque pour qu'ils soient exposés dans une application cliente? Ou comment traduire les chemins d'accès à la bibliothèque lors de l'empaquetage de la bibliothèque?

En guise de question secondaire, je me demande pourquoi l'extension ne se fait pas dans l'autre sens. Pourquoi n'est-ce pas le tsconfig.json fichier qui s'étend sur le projects/midi-lib/tsconfig.lib.json fichier ?

Voici comment j'emballe et utilise ensuite la bibliothèque:

Pour empaqueter la bibliothèque, ajoutez les scripts suivants dans le tableau de scripts du parent package.json fichier

"copy-license": "cp ./LICENSE.md ./dist/midi-lib",
"copy-readme": "cp ./README.md ./dist/midi-lib",
"copy-files": "npm run copy-license && npm run copy-readme",
"build-lib": "ng build midi-lib",
"npm-pack": "cd dist/midi-lib && npm pack",
"package": "npm run build-lib && npm run copy-files && npm run npm-pack",

et exécutez la commande: npm run package

puis installez la dépendance

npm install ../midi-lib/dist/midi-lib/midi-lib-0.0.1.tgz

et importez le module dans le module d'application Dans le app.module.ts le fichier a:

import { MidiLibModule } from 'midi-lib';
@NgModule({
  imports: [
    MidiLibModule

enfin insérer le composant dans un modèle

<midi-midi-lib></midi-midi-lib>

Lorsque la bibliothèque est installée dans une application cliente, elle contient beaucoup de .d.ts fichiers dans le node_modules/midi-lib répertoires:

├── bundles
├── esm2015
│   └── lib
│       ├── device
│       ├── keyboard
│       ├── model
│       │   ├── measure
│       │   └── note
│       │       ├── duration
│       │       └── pitch
│       ├── service
│       ├── sheet
│       ├── soundtrack
│       ├── store
│       ├── synth
│       └── upload
├── esm5
│   └── lib
│       ├── device
│       ├── keyboard
│       ├── model
│       │   ├── measure
│       │   └── note
│       │       ├── duration
│       │       └── pitch
│       ├── service
│       ├── sheet
│       ├── soundtrack
│       ├── store
│       ├── synth
│       └── upload
├── fesm2015
├── fesm5
└── lib
    ├── device
    ├── keyboard
    ├── model
    │   ├── measure
    │   └── note
    │       ├── duration
    │       └── pitch
    ├── service
    ├── sheet
    ├── soundtrack
    ├── store
    ├── synth
    └── upload

Comme celui-ci lib/service/melody.service.d.ts fichier

import { SoundtrackStore } from '@lib/store/soundtrack-store';
import { ParseService } from '@lib/service/parse.service';
import { CommonService } from './common.service';
export declare class MelodyService {
    private soundtrackStore;
    private parseService;
    private commonService;
    constructor(soundtrackStore: SoundtrackStore, parseService: ParseService, commonService: CommonService);
    addSomeMelodies(): void;
    private addSoundtrack;
    private generateNotes;
}

Comme on peut le voir, il contient des références à @lib mappage de chemin, qui n'est pas connu dans l'application cliente.

J'ai également essayé d'utiliser la propriété baseUrl comme solution de contournement, mais cela n'a pas aidé non plus, car lors de l'installation de la bibliothèque, cette valeur baseUrl n'était pas spécifiée.

Pourquoi empaqueter la bibliothèque avec la commande npm run package ne résout pas les mappages paths?

12
Stephane

Comme d'autres l'ont dit, TypeScript ne modifie pas votre @app et @lib importations. J'ai rencontré le même problème en essayant d'utiliser des chemins absolus dans un package de bibliothèque. Ce dont vous avez besoin est de préparer votre bibliothèque pour la publication avec rollup ou quelque chose de similaire.

Rollup a différents plugins, et je ne couvrirai pas la configuration complète, mais ce dont vous avez besoin est un plugin qui réécrira vos importations. Ce plugin ressemble à ça: https://github.com/bitshiftza/rollup-plugin-ts-paths

Pour le reste de la configuration du cumul, vous aurez probablement besoin de rollup-plugin-node-resolver et rollup-plugin-commonjs , ainsi que d'un plugin pour gérer TypeScript ( rollup-plugin-TypeScript ), ou vous pouvez emprunter la nouvelle voie d'utilisation de babel. Recherchez des guides, car il existe des bibliothèques populaires écrites en TypeScript qui utilisent le cumul pour préparer leur code pour l'empaquetage (React, pour un).

Codage heureux.

0
Matthias