Typescript i VS 2015 ASP.NET 4 MVC 5 - vilka är de fungerande kombinationerna av inställningar och val?
Jag lägger till ett TypeScript-projekt till ett VS2015 MVC 5-projekt (vilket gör det till ASP.NET 4, inte ASP.NET 5 eller ASP.NET 6-kod: endast MVC är version 5). Detta är det enda målet för alla aspekter av min fråga, jag kan inte använda generaliserad eller teoretisk vägledning om TypeScript, Node.js, module loaders osv.
Problemet är enklare med ASP.NET Core. Men det är inte det jag står inför. Alla vanliga källor för exempel och vägledning undviker eller ger bara småbitar när det gäller ASP.NET 4 MVC 5 eftersom det är svårt. Och ingen kommer att säga exakt hur svårt det är eller vad exakt hindren är.
Värst, Typescript-dokumentation är som öppen källkod-dokumentation: du kan bara få ett problem, ett steg djupt. Detta skapar ett forskningsflöde som består av oändlig problemträdsrekursion.
Jag förstår åsikter, jag har till och med en själv. Men jag letar efter det erfarenhetsbaserade svaret, vad är den kombination som har visat sig fungera för ett produktionsteam.
Så här är de specifika punkterna som behöver åtgärdas och göras fungerande inom ramen för en fungerande, medelstor ASP.NET 4 MVC 5 LOB-app:
Visual Studios version av TypeScript. Detta är ett installationsproblem (att använda Node på det enklaste sättet) och inställningarna i Verktyg/Alternativ - TypeScript måste matcha.
Webbläsarbaserad testning (vanligtvis manuell TDD-arbetsflöde) eller node.js-testning (automatiserad). Detta måste väljas i förväg för att förhindra fler problemträd-rekursioner. Vi går med webbläsarbaserad... phantomjs med WallabyJs.
NPM @types/library-name: ska fylla en node_modules-mapp med både library-name och library-name.d.ts baserat endast på en package.json med @Types-referenser. Men det kräver faktiskt att package.json innehåller en referens för både @types/library-name och library-name för att fungera i mitt VS 2015 ENT v3 och asp.net 4 mvc 5-projekt. Och alla versioner som anges kräver sedan manuell korrigering, och även då är versionsuppslagsprocessen lite misstänkt. Denna @types-process kanske inte är rätt väg att gå med ASP.NET 4 MVC 5, men jag kan inte säga vad alternativet för korrigering skulle vara. @Types är för närvarande det enda rekommenderade alternativet för TypeScript.
Vilken version av ECMAScript: es6 är tydligen för långt fram. es2015 är sannolikt, men detta (kanske) verkar ha samband med flera av de andra problemen. Påstås att dessa beteckningar är desamma, men det finns två ställen där de kan anges. Jag har valt es2015 i verktyg/alternativ/typescript. Men att få något av dessa (nu 3) inställningar fel kan vara ett problem.
Modulsystem: CommonJs är för Node och automatiserad testning, och VS-utvecklingstestning är automatiserad endast för serversidan, och VS UI-tester är en manuell process. Så AMD, require JS är troligen ett alternativ för VS, men det lägger till sitt eget arbetsflöde och underhåll samt överväganden som är väldigt svåra att få rätt i ASP.NET. Att använda ASP.NET-buntning och triple-slash-referenser (pålitliga) kan fungera, men efter att du har lagt biblioteken i node-modules, skulle du vilja använda hela sökvägen till node-modules i filnamnsslaget i en import-sats. Allt detta är väldigt klumpigt och involverar mest gissningar. Men att lösa hela denna punkt kan vara 'nyckeln' för den övergripande frågan.
Det finns förmodligen många andra, mindre problem. Men någon som har gjort detta kommer att ha löst alla nämnda punkter och de andra också.
Det jag letar efter är alla inställningar över alla dessa frågor i detalj baserat på en fungerande Typescript-app i ASP.NET 4 MVC 5-implementation för webbläsarbaserade enhets-/beteendetester i VS 2015. De som har gjort det kommer att förstå.
Tack så mycket för din omtanke.
Svar #1
Det du saknar är separation av ansvar, trots den initiala fördelen med sådana startmallar, börjar de orsaka oavsiktliga beroenden och komplicera den mentala modellen. Det är mycket enklare att ha ditt front-end i ett separat projekt.
Oavsett :
Visual Studios version av TypeScript.
Använd alltid den allra senaste tillgängliga. Detta styr vilken version av TypeScript som driver IDE:n. Du kommer troligtvis att kompilera i en separat process eller i webbläsaren under utvecklingen. Återigen vill du använda den senaste men den kommer sannolikt att installeras med en annan pakethanterare.
Webbläsarstilstestning (vanligtvis manuell TDD-arbetsflöde) eller node.js-testning (automatiserad). Detta måste väljas i förväg för att förhindra mer problem-träd-rekursion.
För det första håller jag definitivt med om vikten av att välja i förväg men, om det fortfarande är möjligt, är det bara obehagligt att lägga till tester i ett befintligt projekt.
TDD-arbetsflöden involverar automatiserad testning eftersom de är beroende av snabb återkoppling. Detta är oberoende av om du kör dina tester i webbläsaren eller med NodeJS.
Du bör använda det tillvägagångssätt som är mest meningsfullt för din applikation och det kan vara en blandning av båda.
Eftersom du skriver en frontend JavaScript-applikation kommer du troligen vilja köra några tester i webbläsaren. Men som Uncle Bob (Robert C. Martin) har sagt, bör vyer vara dumma och kräva lite testning. Min tolkning av detta är att vi inte bör lägga för mycket tid på att testa saker som Angular- eller React-komponenter för att säkerställa att de renderas korrekt, utan istället fokusera på att testa beteendemässiga element i systemet såsom tjänster och vanliga funktioner.
Det sagt, kan du mycket väl vilja köra tester av dina klienttjänster mot en faktisk webbläsar-miljö, istället för bara Node.js, och det är rimligt.
Det finns ett antal testbibliotek som kan hjälpa dig med detta. Jag har ingen specifik rekommendation förutom att säga att du bör hitta en pålitlig testrunner och ett enkelt assertionsbibliotek. Beprövade testbibliotek som QUnit och Tape är exempel på stabila alternativ.
En sista anteckning, det är viktigt att man inte förväxlar begreppet integration testing med att köra tester i en webbläsare, det är helt giltigt att köra TDD-stil tester, vilket innebär enhetstester, i en webbläsare.
NPM @types/library-name: ska fylla en node_modules-mapp med både library-name och library-name.d.ts, men kräver att package.json innehåller en referens för både @types/library-name och library-name för att fungera i mitt VS 2015 ENT v3 och asp.net 4 mvc 5-projekt.
Enkelt uttryckt handlar detta om att separera din front-end från din back-end. Visual Studio och definitivt ASP.NET har inget att göra med versionering av dina typ-paket.
Om ett paket kommer med sina egna typdeklarationer behöver du inte installera ett extra typ-paket, annars gör du det.
Oavsett vilket, installera JavaScript- och TypeScript-beroenden med en JavaScript-orienterad pakethanterare (såsom NPM, JSPM eller Yarn).
Använd inte NuGet för dessa!
Som du föreslår finns det versionshanteringsproblem, det är för närvarande ett svårt problem i TypeScript. Men återigen har det inget att göra med ASP.NET eller Visual Studio.
Vilken version av ECMAScript: es6 är uppenbarligen för långt fram. es2015 är troligt, men detta verkar ha (kanske) relationer till flera av de andra problemen.
ES6 är samma som ES2015, det sistnämnda är namnet under vilket det förstnämnda slutligen släpptes. ECMAScript följer nu ungefär en årlig rytm, med ES2017 precis runt hörnet.
Det trevliga med att ha en transpiler, som TypeScript, är att du kan använda de senaste funktionerna från es2017 och ändå rikta in dig på es5 för utskrift och du kommer att klara dig bra.
Modulsystem: CommonJS är för NodeJS och automatiserad testning, och VS utvecklingstestning är automatiserad endast för serversidan, och VS UI-tester är en manuell process. Så AMD/UMD som kräver JS är förmodligen alternativet för VS, men det tillför eget arbetsflöde, underhåll och överväganden. Att använda trippel-slagreferenser (pålitligt) kan fungera, men efter att du har lagt dina/deras bibliotek i node-modules vill du använda hela sökvägen till node-modules i filnamnssluggen i ett importuttryck. (Att lösa hela denna punkt kan vara 'nyckeln' för den övergripande frågan).
Detta är ett mycket komplext ämne och förmodligen det enda av dina frågor som du verkligen behöver ägna mycket tid åt att överväga. Som jag sa tidigare är användningen av NodeJS eller inte ortogonal mot automatiserad testning. Men om du riktar dig mot NodeJS nativt med din testkod så kommer du att behöva använda CommonJS-utmatning.
För den faktiska applikationskoden har valet överhuvudtaget ingenting att göra med huruvida du använder Visual Studio eller inte, jag ber om ursäkt för att jag upprepar detta men det är verkligen viktigt att du skiljer på dessa idéer.
Frågan om vilken modulformat som ska användas för din front-end-applikationskod är en mycket viktig och omtvistad fråga.
Triple ///-referenser är inte ett modulformat utan snarare ett sätt att deklarera beroenden mellan globala variabler som deklareras och refereras över flera filer.
De skalar inte väl och fungerar acceptabelt när du bara har ett fåtal filer.
Trippla ///-referenser bör inte användas. De är inte en mekanism för modulärhet och deras användning är helt annorlunda än att använda något av modul systemen/modulformaten du nämner, inklusive CommonJS.
Kombinera dem aldrig med ett modulsystem, vilket är vad du skulle behöva göra för att köra dina tester under NodeJS eller ladda din app med RequireJS eller något annat.
RequireJS är ett utmärkt alternativ som skulle innebära AMD-moduler som du säger. RequireJS kräver inte någon användning av trippla snedstrecksreferenser. Faktum är att de bör undvikas som pesten när man använder detta format eller något annat modulformat!
Jag avråder starkt från att använda UMD-moduler. Isomorf JavaScript är en problematisk idé och det ger dig inga fördelar eftersom du skapar en webbläsarapplikation med en .NET-backend.
Många utvecklare använder faktiskt CommonJS-moduler i en webbläsare. Detta kräver att de kontinuerligt bundlas, med hjälp av verktyg som Webpack. Denna metod har både fördelar och nackdelar. De främsta fördelarna är möjligheten att dra nytta av befintliga NodeJS JavaScript-serververktyg, såsom npm, via Webpack eller Browserify. Detta kanske inte låter som en stor fördel, men mängden rika verktyg som finns tillgängliga för CommonJS-moduler är inget att förakta, vilket gör det till ett starkt alternativ.
Överväg att använda System-modulformatet och SystemJS-laddaren via jspm för att både hantera dina paket och ladda din kod. Med detta tillvägagångssätt får du fördelarna med RequireJS, kan köra dina tester under NodeJS och webbläsaren med jspm run utan att behöva byta målformat eller paketera din kod bara för att testa den. Det finns heller inget behov av att paketera din kod under utveckling, även om detta stöds. Viktigare är att du får fördelen av att skriva framtidssäker kod, eftersom det erbjuder det enda modulformat och laddare som korrekt modellerar de semantiker som ES-moduler så småningom kommer att ha när de implementeras nativt i webbläsare. JSPM har förstaklassigt stöd för TypeScript, Babel och Traceur. För eftervärlden är här beskrivningen av System-modulformatet taget från länken ovan:
System.register kan betraktas som ett nytt modulfomat som är utformat för att stödja den exakta semantiken hos ES6-moduler inom ES5. Det är ett format som utvecklades genom samarbete och stöds som modulutdata i Traceur (som instantiate), Babel och TypeScript (som system). Alla dynamiska bindningar och cirkulära referensbeteenden som stöds av ES6-moduler stöds av detta format. På detta sätt fungerar det som ett säkert och omfattande målformat för polyfill-vägen till ES6-moduler.
Ansvarsfriskrivning: Jag är medlem i JSPM GitHub-organisationen, spelar en roll i att underhålla registret och har gjort mycket små bidrag till jspm CLI.