I am very partial to saltarelle. It supports c# 5.0 constructs like async, c# 2.0 constructs like generics, and everything in between. It has a full suite of tests and relatively active. I have a lot of full projects implemented in it from 60fps canvas games to just normal sites. If anyone is interested in seeing some stuff, or just chatting about it, let me know.
Saltarelle is great; just worth making the clear distinction: Saltarelle is a C# compiler, JSIL is a .NET translator.
The distinction matters for cases where you want to use huge piles of existing .NET code, sometimes written in other languages. VB.net and F# already have partial functionality in JSIL without any dedicated support, and there's a partially functional MonoGame port that only took a small amount of fiddling. You could of course manually port all that stuff over to Saltarelle-compatible C# (and get great results!) but it's a different approach.
EDIT: One other distinction is that the .NET translation approach results in broader feature support. JSIL supports features Saltarelle may never support, like pointers and structs.
As a bit of self promotion, if anyone is interested in helping on this project, or any other web based c# -> js game, shoot me an email dested@gmail :-)
So, if one were to use this or something like it, how would you handle DOM interaction? Write JavaScript by hand for that, and have it call out to JSIL-generated code?
Like gecko said, you can use C#'s 'dynamic' feature to grab references to JS objects from the DOM and do late-bound manipulation of them.
Functions can also have their body entirely replaced by a JavaScript expression, and it's done using an attribute so that it doesn't affect how your code runs in native .NET. This is used in parts of the runtime library and in some of the examples, like so:
You can also directly embed raw JavaScript into function bodies, like this:
var a = 2;
var b = 5;
Verbatim.Expression("print($0 + $1)", a, b);
That allows you to embed particular JavaScript constructs that the compiler won't normally generate, call out to things like jQuery directly, etc. The downside to this is that you've now written something that won't run in any other .NET environment, but you can always wrap it in a JavaScript-only conditional.
I'd rather it'd go the other way: please generate hopelessly unreadable but optimal javascript. However, include the original source as comments in some debug mode.
In my experience with coffeescript, the idea that the source is really readable is only somewhat true. Sure, you can read what's going on. But fancier features aren't always trivially translated; and even where a translation is trivial the small differences in syntax mean that in a large enough codebase it can take some time to find the corresponding source line.
Furthermore, because the code is supposedly "easy to read" that means it must be fairly close to javascript native, and that means (for instance) either a heavy abstraction (JSIL) that's probably slow, or exposing lots of unfortunate javascript quirks (coffeescript) such as 0 vs. null vs. undefined vs. false and/or => vs. ->. Basically, to reason about coffeescript you often enough need to understand in detail how it's translated to javascript; at that point you've lost any productivity gains you were hoping for but are still paying the costs in terms of poor tooling and browser integration.
If you're using javascript like assembly, treat it like that: please don't waste my time being sorta-almost-but-not-quite readable. Just make fast, robust, no-leaky-abstraction javascript, please.
The generated code used to be a lot prettier and more idiomatic, but JavaScript is such a pain in the ass that it's really not possible to do - too many behavioral differences, performance issues, etc. Basically all the readability problems are caused by compromises that ensure adequate runtime performance in V8 and SpiderMonkey.
Were I to start from scratch I'd probably drop the goal of producing readable JS entirely.
With sourcemaps, this is unimportant. For example, Closure Compiler, Dart, and GWT support source maps which let you see and debug the original source inside the browsers that support sourcemaps, even if the underlying representation is heavily optimized and minified JS.
XNA/MonoGame are not yet ported to TypeScript (and I guess never will). Also the idea is to avoid having to look at JS at all (for obviou reasons) by using a language that is generally better.
What happens if your program uses classes from the .NET Framework, like List or Dictionary? Does the framework IL get translated to JavaScript and sent to the browser too?
To add my 2c: We have a great esxperience using JSIL for executing some C# business logic on the clinet to make the page more responsible. By chaninig single c# file we get updated functionality both on client and on the server.
- http://sharpkit.net/ (commercial)
- http://scriptsharp.com/ (closed compiler)
- http://www.saltarelle-compiler.com/ (open source)