четверг, 30 апреля 2015 г.

Getting started with .net on OS X and Visual Studio Code

I am a big fan of .net platform. From the other hand, I like apple devices and do my first steps in discovering unix systems philosophy. Not very long time ago, these two passions were completely separated worlds. They are not anymore!
With the announcement of Visual Studio Code on build conference it is finally possible to run .net applications on mac using full Microsoft technology stack, from .net libraries up to code editor, I decided to finally give it a try. Below my experience of setting things up and getting a web server running asp.net 5 application on mac os x machine. I bumped into some caveats and I hope my experience could save some time to those who decide to get a hands on experience of new tech as soon as possible.

Setting up the environment

To get everything up and running you need to do several things.
The easy part is get an editor - just download it from Visual Studio Code site.
If you are used to MS VisualStudio integrated experience, you have to forget about it. You will have to do many things manually using the terminal. 
First of all, you will need a node package manager installed. You probably already have one, it's easy to check it, just run a following command in your terminal:
 npm -v  

If you see a version number, you are good. If not - just follow this guide.

By that time you should have npm and HomeBrew installed and we can move on.
In order to get the project boilerplate code generated for you, you will need a scaffolding tool, such as yeoman and a couple of other js such as bower - javascript package manager and grunt - javascript build tool.
All of the above could be installed with a single command (thanks to this useful guide):
 npm install -g yo grunt-cli generator-aspnet bower  

After that you can generate an asp.net using the following command:

 yo aspnet  
and choosing WebApplication template from the list.

Here's where things get interesting. In order to run a .net application on OS X, you need to install .net version manager

In order to do so, add a .net repository to HomeBrew sources with tap command:

 brew tap aspnet/dnx   

update it with
 brew update  

and finally install .net version manager:
 brew install dnvm  

Here is the first unevident thing I bumped into: if you try to run dnvm command, you will see an error. The case is that you need to manually register dnvm command within your shell. Brew gives you a small hint, but its easy to overlook it:
So, let's do what brew suggests - run
 source dnvm.sh  

Now dnvm command should be available and you are ready to build and run your generated asp.net application.

Run, troubleshoot, repeat

In order to run the asp.net application, navigate to the folder with a generated application via terminal, or open this folder with Visual Studio Code application.
Now we can use some GUI at last! 
First of all we need to restore packages via dnu restore command (dnu stands for dnx utility). Just press cmd+p in the editor and start typing:
Hit enter and wait for dnu to restore the packages. A terminal window will open and restoration process will start. It will take a while the first time, so you can literally go and get some coffee now.
Note that you can achieve the same thing using only a terminal - just run the same dnu restore command.

Now when you have all the packages restored, the application server could be started. Linux and OS X use Kestrel server to host and run asp.net applications. Start it with kestrel command:
 Or from the terminal:
 dnx . kestrel  

Mind the dot there, it is important part of a command.

If you see no error messages in your terminal - congrats! You now have an asp.net application running on your mac, fantastic isn't it? Except that you probably do not. Check if everything is alright by visiting localhost:5001 in your browser.
Here's what I've seen there:

IOException: kqueue() FileSystemWatcher has reached the maximum nunmber of files to watch.
It turned out to be a known bug in Mono, which asp.net uses under cover for now, while .net Core is not yet ported to OS X. In order to fix it, you need to set up an environment variable:

 export MONO_MANAGED_WATCHER=false  

By the way, if you like me wonder how to stop a kestrel server as an common control+c shortcut doesn't work with it. Just hit Enter key in the terminal - as easy as that.
So, stop the server and run the export command. Now everything should be fine - just start a kestrel again. Except it may be not!
I've bumped in the following exception when navigation to my aspnet site:
TypeLoadException: Could not load type 'Microsoft.Framework.Runtime.ILibraryExport'

If you get something like this, you get a version mismatch of your current .net version and a .net version your packages are build against. So you need to make sure they are in accord. In my case I had two versions of .net installed (you can check it with dnvm list command):

I had the 1.0.0-beta5-11657 version as active and default.
If you look to the project.js file in your project, you can see that the project dependencies are actually need beta4 .net version:
Activate the required version with the following command:

 dnvm use 1.0.0-beta4 -p  

Use command switches an active environment, and -p flag also makes the new environment the default one.

So, everything seems to be ok. Take a deep breath, start kestrel again, reload the page and... boom!
I have a web server running asp.net application on my mac! That's just so awesome. Wonderful things are happening. Can't wait to get my hands on actual coding with new Visual Studio Code editor and further discover the features and caveats of cross-platform .net development, where cross-platform finally means exactly that, and not the fact that your application will run on different windows versions. Cheers!