jquery - Installera flera TypeScript-typsdefinitioner som deklarerar samma globala variabel
Jag bygger en applikation med TypeScript, Node och Electron.
Jag använder jquery i applikationen och jag har installerat @types/jquery-paketet för att få intellisense-förslag.
Nästa skapade jag ett test med mocha och spectron. Spectron använder webdriverio och exponerar sitt API genom vissa egenskaper. Jag behöver använda dessa egenskaper, så jag installerade @types/webdriverio för att få intellisense-ledtrådar.
Nu, varje gång jag kör tsc-verktyget för att kompilera projektet får jag följande fel:
node_modules/@types/jquery/index.d.ts(36,15): error TS2451: Cannot redeclare block-scoped variable '$'.
node_modules/@types/webdriverio/index.d.ts(1898,18): error TS2451: Cannot redeclare block-scoped variable '$'.
node_modules/@types/webdriverio/index.d.ts(1899,18): error TS2451: Cannot redeclare block-scoped variable '$'.
Problemet är att båda paketen deklarerar en global $-variabel. Du kan också verifiera det på deras npm-sidor under "Global values":
https://www.npmjs.com/package/@types/jquery
https://www.npmjs.com/package/@types/webdriverio
Det jag inte förstår är varför tsc försöker kompilera dem tillsammans eftersom jag inte använder jquery och webdriverio i samma .ts-fil?
Dessutom, även om jag kommenterar bort testet, så jag inte refererar till webdriverio någonstans, när jag kör tsc får jag samma fel. Troligen kompilerar tsc alla källor i node_modules/@types tillsammans. Faktum är att om jag tar bort mappen node_modules/@types/webdriverio och kör tsc igen, får jag inget fel (naturligtvis, så länge jag håller testkoden kommenterad).
Detta är min tsconfig.json som ligger i projektets rot:
{
"compilerOptions": {
"target": "ES6",
"module": "commonjs",
"sourceMap": false,
"inlineSourceMap": true,
"inlineSources": true,
"declaration": false,
"outDir": "dist"
},
"include": [
"src/**/*"
]
}
All min källkod finns i katalogen src. Tester finns i src/test.
Finns det någon konfiguration jag kan göra för att hålla webdriverio och jquery-typer separerade vid kompilering? Dessutom har jag sett några kodexempel skrivna i js där de används tillsammans: är detta inte möjligt i typescript?
Svar #1
Det har gått lång tid, men jag hittade lösningen!
Du behöver definiera två separata tsconfig: en för huvudprojektet och en för testerna.
tsconfig.project.json
{
"compilerOptions": {
"target": "ES6",
"module": "commonjs",
"sourceMap": false,
"inlineSourceMap": true,
"inlineSources": true,
"watch": false,
"declaration": false,
"outDir": "dist",
"typeRoots": ["./typings"],
},
"include": [
"src/**/*"
],
"exclude": [
"src/test/*"
]
}
tsconfig.test.json
{
"compilerOptions": {
"target": "ES6",
"module": "commonjs",
"sourceMap": false,
"inlineSourceMap": true,
"inlineSources": true,
"watch": false,
"declaration": false,
"outDir": "dist",
"typeRoots": ["./typings"],
},
"include": [
"src/test/*"
]
}
Sedan, i filen package.json definiera två olika skript för att köra tsc mot de två tsconfig du just definierade:
{
...
"scripts": {
"test": "tsc -p tsconfig.test.json && mocha --exit dist/test",
"tsc": "tsc -p tsconfig.project.json",
...
},
...
}
Huvudpunkten är typeRoots-konfigurationen som skriver över standardbeteendet för TypeScript-kompilatorn. Standardbeteendet är att ladda varje paket som definieras under någon @types-mapp (så varje @types som installeras i node_modules-mappen inkluderas). Genom att skriva över denna konfiguration inkluderas @types i node_modules endast när de refereras. Alternativt kan du ersätta typeRoots-konfigurationen med
"types": []
Från https://www.typescriptlang.org/docs/handbook/tsconfig-json.html
@typer, typeRötter och typer
Som standard inkluderas alla synliga “@types” paket i din kompilering. Paket i node_modules/@types i någon omgivande mapp betraktas som synliga; specifikt betyder det paket inom ./node_modules/@types/, ../node_modules/@types/, ../../node_modules/@types/, och så vidare.
Om typeRoots anges kommer endast paket under typeRoots att inkluderas.
...
Specificera "types": [] för att inaktivera automatisk inkludering av @types-paket.
Tänk på att automatisk inkludering bara är viktig om du använder filer med globala deklarationer (till skillnad från filer som deklareras som moduler). Om du till exempel använder ett import "foo"-uttalande kan TypeScript fortfarande söka igenom node_modules och node_modules/@types-mapparna för att hitta foo-paketet.
En annan viktig punkt är att separera konfigurationsfilerna. På detta sätt kan du exkludera testfilerna när du kompilerar huvudprojektet och vice versa. Detta är viktigt eftersom huvudprojektet inkluderar jquery, medan testfilerna inkluderar webdriverio. Om du kompilerar dem tillsammans skulle du få samma fel som beskrivs i frågan.
