node.js - Är det nödvändigt för MSBuild att transpilera .ts-filer i Angular2:s beroenden (i node_modules) för att Angular2 ska fungera?
Bakgrund
Jag har ett ASP.NET MVC-projekt integrerat med Angular2. Enligt Angular.io:s snabbstartsguide skapade jag en mapp i min lösningsfil med den standard Angular2-strukturen...
├── app
| └── ...
├── node_modules
| └── ...
├── typings
| └── ...
| systemjs.config.js
| tsconfig.json
| typings.json
| package.json
... och en standard package.json-fil:
"dependencies": {
"@angular/common": "2.0.0",
"@angular/compiler": "2.0.0",
"@angular/core": "2.0.0",
"@angular/forms": "2.0.0",
"@angular/http": "2.0.0",
"@angular/platform-browser": "2.0.0",
"@angular/platform-browser-dynamic": "2.0.0",
"@angular/router": "3.0.0",
"@angular/upgrade": "2.0.0",
"core-js": "^2.4.1",
"reflect-metadata": "^0.1.3",
"rxjs": "5.0.0-beta.12",
"systemjs": "0.19.27",
"zone.js": "^0.6.23",
"angular2-in-memory-web-api": "0.0.20",
"bootstrap": "^3.3.6"
},
"devDependencies": {
"concurrently": "^2.2.0",
"lite-server": "^2.2.2",
"typescript": "^2.0.2",
"typings":"^1.3.2"
}
Sedan använde jag npm install-kommandot för att installera Angular2:s beroenden i node_modules-mappen.
Problem
Roten till mitt problem är att MSBuild försöker kompilera varje .ts-fil i hela projektet.1 Dessa inkluderar .ts-filer som den hittar i node_modules-mappen. Detta ger många fel och förhindrar att lösningen byggs/publiceras.2
Fråga
Jag kan lösa problemet genom att ta bort alla tsconfig.json-filer förutom den som finns på projektets rotnivå - om jag gör det kommer MSBuild att sluta försöka kompilera AngularJS’ beroenden i node_modules.
Men är detta att rekommendera? Kommer Angular2:s beroenden att fungera korrekt om deras tsconfig.json-filer tas bort och deras Typescript-filer inte kompileras? Kommer SystemJS att kompilera Typescript-filerna ändå?
1 Jag använder Microsoft.Typescript.MSBuild NuGet-paketet för att transpilera .ts-filer (tsc.exe v2.0.3) och NodeJS v6.x.
2 Jag tror att detta beror på att innan Angular2-beroenden är installerade, har jag en enda tsconfig.json-fil i projektets rot - men efteråt innehåller node_modules ungefär tio olika tsconfig.json-filer - till exempel \node_modules\browser-sync\node_modulesx\ts\tsconfig.json.
Svar #1
Kommer Angular2-beroenden att fungera korrekt om deras tsconfig.json-filer tas bort och deras Typescript-filer inte kompileras?
Tredjepartsbibliotek distribueras redan som JS-filer. Detta gäller alla tredjepartsbibliotek. Bibliotek som stödjer TypeScript direkt kommer att inkludera TypeScript-definitionfiler (dessa filer slutar med .d.ts). När vi kompilerar våra applikationer, kompileras de mot definitionsfilen, inte källkodsfilen (.ts). Definitionsfilen tillhandahåller typningen som är tillräcklig för att TypeScript ska kunna kompilera mot den. Vi bör aldrig behöva röra själva källkoden.
Du har kanske också märkt att vissa tredjeparts JS-bibliotek inte stöder TypeScript direkt (dvs. distribuerar inte typning i biblioteket). I så fall behöver vi installera externa tredjepartstyper. Till exempel, säg att vi använder Moment JS. Om du installerar npm install momemt, kommer du märka att modulen inte har typings-filen. Så om vi vill använda Moment i TypeScript skulle vi npm:a installera @types/moment, och det skulle ge oss typningarna för Moment.
Också, om du ville skapa ditt eget TypeScript-bibliotek, vad du skulle göra är att lägga till compilerOptions.declaration: true i din tsconfig.json-fil. När projektet kompileras kommer det att skapa definitionsfiler åt dig, så att du inte behöver skriva dem manuellt.
Så här konsumeras/borde tredjepartsbibliotek användas i TypeScript. Om vi inte använde definitionsfiler och alltid importerade källkoden, skulle källkoden alltid kompileras, oavsett om du exkluderar den från tsconfig, eftersom koden vi skriver beror på den. Så istället är vi beroende av definitionsfiler. När du importerar till din projektkod, är det faktiskt definitionsfilen du importerar, inte källfilen.
Svar #2
Du bör inte kompilera TypeScript-filer under node_modules. För att säkerställa att du inte gör det, lägg till följande i din tsconfig-fil:
"exclude": [
"node_modules"
],
Det anses vara en dålig praxis att publicera ett bibliotek som TypeScript eftersom användaren skulle behöva återskapa hela byggmiljön för att använda det - typer och allt. Du skulle potentiellt också behöva rikta in dig på en specifik version av TypeScript-kompilatorn.
