Ok so there’s a few nice things that MS have done with typescript, but Dev time vs build time vs deploy time they don’t all work the same, so there’s a few things we’ve done to make the F5 experience nice while making sure the build and deployed results are the same.
In the below examples we are using
- Visual Studio 2015
- Team City
- Octopus Deploy
Firstly TypeScript in Visual Studio has this nice feature to wrap up your typescript into a single js file while your coding. It’ll save to this file as you are saving your TS files, so its nice for making code changes on the fly while debugging, and you get a single file output.
Also this will build when TeamCity runs msbuild as well. But don’t check this file in, its compile ts output, it should be treated like binary output from a C# project.
And you can further minify and compact this using npm (see this post for details).
This isn’t prefect though, because we shovel our static content to a separate CDN that is spared between environments (Folder per version), and we have environment specific JavaScript variables that need to be set, this can’t be done in a TypeScript file as they all compile into a single file. I could use npm to generate the TypeScript into 2 files but this conflicts too much with the developers local setup in using the above feature from my tests.
So we pulled it into a js file that is separate form the type script, this obviously though causes the type script to break as the object doesn’t exist. So we added a declaration file for it like below:
declare var AppSetting: {
url: string;
baseCredential: string;
ApiKey: string;
}
Then drop the actual object in a JavaScript file with the tokens ready for octopus, with a simple if statement to drop in the Developers local settings when running locally.
var AppSetting; (function (AppSetting) { if (window.location.hostname == "localhost") { AppSetting.url= "http://localhost:9129/"; AppSetting.baseCredential= "XXXVVVWWW"; AppSetting.ApiKey= "82390189wuiuu"; } else { AppSetting.url= "#{url}"; AppSetting.baseCredential= "#{baseCredential}"; AppSetting.ApiKey= "#{ApiKey}"; } })(AppSetting || (AppSetting = {}));
This does mean we need a extra http request to pull down the appSetting js file for our environment, but it means we can maintain our single CDN for static content/code like we have traditionally done.