I was asked that today and was not able to give a proper answer.
Typescript transpiles to JS. Then there is tree shaking, "less" (optional) and what else in the process of making a deployment. But nothing like that (afaik) has anything to do with "compiling". Everything gets bundled and heavily optimized, but it's not actually compiled, right?
There is even an "ahead of time"-compiler, which really does a noticeable job. What do I miss?
Javascript itself is still interpreted, right?
You're presuming compiling means taking the source code and producing machine code, low-level codes, etc. But compiling actually just means taking one source code and turning it into another. So it seems reasonable to say that taking Typescript and producing JavaScript is a form of compiling. It's not dissimilar to what (for example) c# does when its compiled into IL language.
That said, I'd say a better word for this is Transpiling. I'd suggest that the Typescript compiler is better described as a Transpiler.
The difference is subtle and a transpiler can be thought of as a type of compiler; but a (pure)compiled language is (usually) turning a high-level language to a low(er) level language (nearer to machine code), like the C# example. A transpiler turns a high-level language into a similar level (of abstraction) language (also high level).*
The result of the compiled code is typically not a language that you would write yourself. The result of a transpiler is another high-level language. In theory, you could write IL (as an example) but it's really designed to be produced by a compiler and there are no tools or support for doing this, you produce IL by compiling C#/vb.net, only. Whereas Javascript is a usable (and used) programming language in its own right.
*Lots of caveats as the definitions of these words and their usage are pretty vague
You seem to be asking three questions in one:
What is the difference between a compiler and a transpiler?
Do Angular and TypeScript implement compilers or transpilers?
Is there a separate Angular compiler? What does it compile?
What is the difference between a compiler and transpiler?
#JörgWMittag provided a very good answer to this question.
Do Angular and TypeScript implement compilers or transpilers?
Both TS and Angular implement real compilers. They follow the same stages of lexical analysis, parsing, semantic analysis, and code generation as C/C++ compilers that produce assembly code (except probably for optimization). You can see that the class/folder are named "compiler" in both Angular and TS.
The angular compiler is not really related to TypeScript compiler. These are very different compilers.
Is there a separate Angular compiler? What does it compile?
Angular has two compilers:
View Compiler
Module Compiler
The job of the view compiler is to transform the template you specify for the component template into the internal representation of a component which is a view factory that is then used to instantiate a view instance.
Besides transforming the template, the view compiler also compiles various metadata information in the form of decorators like #HostBinding, #ViewChild etc.
Suppose you define a component and its template like this:
#Component({
selector: 'a-comp',
template: '<span>A Component</span>'
})
class AComponent {}
Using this data the compiler generates the following slightly simplified component factory:
function View_AComponent {
return jit_viewDef1(0,[
elementDef2(0,null,null,1,'span',...),
jit_textDef3(null,['My name is ',...])
]
It describes the structure of a component view and is used when instantiating the component. The first node is element definition and the second one is text definition. You can see that each node gets the information it needs when being instantiated through parameters list. It’s a job of a compiler to resolve all the required dependencies and provide them at the runtime.
I strongly recommend reading these articles:
Here is what you need to know about dynamic components in Angular
Here is why you will not find components inside Angular
Also, see the answer to What is the difference between Angular AOT and JIT compiler.
The job of the module compiler is to create a module factory which basically contains merged definitions of the providers.
For more information, read:
Avoiding common confusions with modules in Angular
Typescript transpires to JS. Then there is tree shaking, "less" (optional) and what else in the process of making a deployment. But nothing like that (afaik) has anything to do with "compiling". Everything gets bundled and heavily optimized, but it's not actually compiled, right?
Compilation means transforming a program written in a language A into a semantically equivalent program written in language B such that evaluating the compiled program according to the rules of language B (for example interpreting it with an interpreter for B) yields the same result and has the same side-effects as evaluating the original program according to the rules of language A (for example interpreting it with an interpreter for A).
Compilation simply means translating a program from language A to language B. That's all it means. (Also note that it is perfectly possible for A and B to be the same language.)
In some cases, we have more specialized names for certain kinds of compilers, depending on what A and B are, and what the compiler does:
if A is perceived to be assembly language and B is perceived to be machine language, then we call it an assembler,
if A is perceived to be machine language and B is perceived to be assembly language, then we call it a disassembler,
if A is perceived to be lower-level than B, then we call it a decompiler,
if A and B are the same language, and the resulting program is in some way faster or lighter, then we call it an optimizer,
if A and B are the same languages, and the resulting program is smaller, then we call it a minifier,
if A and B are the same languages, and the resulting program is less readable, then we call it an obfuscator,
if A and B are perceived to be at roughly the same level of abstraction, then we call it a transpiler, and
if A and B are perceived to be at roughly the same level of abstraction and the resulting program preserves formatting, comments, and programmer intent such that it is possible to maintain the resulting the program in the same fashion as the original program, then we call it a re-engineering tool.
Also, note that older sources may use the terms "translation" and "translator" instead of "compilation" and "compiler". For example, C talks about "translation units".
You may also stumble across the term "language processor". This can mean either a compiler, an interpreter, or both compilers and interpreters depending on the definition.
Javascript itself is still interpreted, right?
JavaScript is a language. Languages are a set of logical rules and restrictions. Languages aren't interpreted or compiled. Languages just are.
Compilation and interpretation are traits of a compiler or interpreter (duh!). Every language can be implemented with a compiler and every language can be implemented with an interpreter. Many languages have both compilers and interpreters. Many modern high-performance execution engines have both at least one compiler and at least one interpreter.
These two terms belong on different layers of abstraction. If English were a typed language, "interpreted-language" would be a type error.
Note also that some languages have neither an interpreter nor a compiler. There are languages which have no implementation at all. Still, they are languages, and you can write programs in them. You just can't run them.
Also, note that everything is interpreted at some point: if you want to execute something, you must interpret it. Compilation just translates code from one language to another. It doesn't run it. Interpretation runs it. (Sometimes, when an interpreter is implemented in hardware, we call it a "CPU", but it's still an interpreter.)
Case in point: every single currently existing mainstream JavaScript implementation has a compiler.
V8 started out as a pure compiler: it compiled JavaScript straight to moderately optimized native machine code. Later, a second compiler was added. Now, there are two compilers: a lightweight compiler that produces moderately optimized code but the compiler itself is very fast and uses little RAM. This compiler also injects profiling code into the compiled code. The second compiler is a more heavyweight, slower, more expensive compiler, which, however, produces much tighter, much faster code. It also uses the results of the profiling code injected by the first compiler to make dynamic optimization decisions. Also, the decision which code to re-compile using the second compiler is made based on that profiling information. Note that at no time there is an interpreter involved. V8 never interprets, it always compiles. It doesn't even contain an interpreter. (Actually, I believe nowadays it does, I am describing the first two iterations.)
SpiderMonkey compiles JavaScript to SpiderMonkey bytecode, which it then interprets. The interpreter also profiles the code, and then the code which gets executed most often is compiled by a compiler to native machine code. So, SpiderMonkey contains two compilers: one from JavaScript to SpiderMonkey bytecode, and another from SpiderMonkey bytecode to native machine code.
Almost all JavaScript execution engines (with the exception of V8) follow this model of an AOT compiler that compiles JavaScript to bytecode, and a mixed-mode engine that switches between interpreting and compiling that bytecode.
You wrote in a comment:
I really was thinking that machine code is somewhere involved.
What does "machine code" even mean?
What is one man's machine language is another man's intermediate language and vice versa? For example, there are CPUs which can natively execute JVM bytecode, on such a CPU, JVM bytecode is native machine code. And there are interpreters for x86 machine code, when you run of those x86 machine code is interpreted bytecode.
There is an x86 interpreter called JPC written in Java. If I run x86 machine code on JPC running on a native JVM CPU … which is the bytecode and which is the native code? If I compile x86 machine code to JavaScript (yes, there are tools which can do that) and run it in a browser on my phone (which has an ARM CPU), which is the bytecode and which is the native machine code? What if the program I am compiling is a SPARC emulator, and I use it to run SPARC code?
Note that every language induces an abstract machine, and is machine language for that machine. So, every language (including very high-level languages) is native machine code. Also, you can write an interpreter for every language. So, every language (including x86 machine code) is not-native.
Getting the code you've written to run on a browser involves two things:
1) Transpiling the Typescript into JavaScript. This is kind of a solved problem. I think they just use webpack.
2) Compiling the angular abstractions into JavaScript. I mean things like a components, pipes, directives, templates etc. This is what the angular core team work on.
In case you're really interested in that second bit, the angular compiler, watch compiler author Tobias Bosch explain the Angular Compiler at AngularConnect 2016.
I think there's a bit of confusion going on here between transpiling and compilation. It sort of doesn't matter and is a matter of personal taste, they're both just transforms between representations of code. But the definition I personally use is that transpilation is between two different languages at a similar abstraction level (eg typescript to javascript), whereas compilation requires a step down in level of abstraction. I think from templates, components, pipes, directives etc to just javascript is a step down the abstraction ladder, and that's why it's called a compiler.
Angular Compiler
One of the most important changes from Angular 4 to 5 is that the compiler has been rewritten be faster and more thorough. In the past, Angular applications used what we call Just-in-Time (JIT) compilation, where the application was compiled at runtime in the browser before running. The compiler updates in Angular 5 advanced the move to AOT, which made the app run faster as it performes less compilation when running the app. AOT become enabled by default in any production build since the 1.5 version of the Angular CLI.
Let's say we want to build an application for deployment and run the following command:
ng build --prod
A few things happen: production version, minification, bunddles assets, filename hashing, tree shaking, AOT ... (we can enable/disable this using flags, ex. aot=false). In short, the prod flag creates an optimized bundle of the application by doing AOT compilation using the ngc (the Angular compiler) to create optimized code ready for the browser (Yes, it pre-compiles templates).
TypeScript Compiler
The TypeScript compiler, tsc, is responsible for compiling TypeScript files. It is the compiler that is responsible for implementing TypeScript features, such as static types, and the result is pure JavaScript from which the TypeScript keywords and expressions have been removed.
The TypeScript compiler has two main features: it is a transpiler and a type checker. The compiler transpiles TypeScript to JavaScript. It does the following transformations on your source code:
Remove all type annotations.
Compile new JavaScript features for old versions of JavaScript.
Compile TypeScript features that are not standard JavaScript.
Invoking it, the compiler searches for configurations loaded in tsconfig.json (A detailed list of all the compiler options, along with default values, can be found here).
In most respects, the TypeScript compiler works like any compiler. But there is one difference that can catch out the unwary: by default, the compiler continues to emit JavaScript code even when it encounters an error. Fortunately, this behavior can be disabled by setting the noEmitOnError configuration setting to true in the tsconfig.json file.
To note: tsc and ngc have different purposes and it's not about selecting one over the other. This answer might be of interest.
This answer was crafted based on the content from the following books
Cloe, M. (2018). "Angular 5 Projects: Learn to Build Single Page Web Applications Using 70+ Projects".
Dewey, B., Grossnicklaus, K., Japikse, P. (2017). "Building Web Applications with Visual Studio 2017: Using .NET Core and Modern JavaScript Frameworks".
Freeman, A. (2019). "Essential TypeScript: From Beginner to Pro".
Ghiya, P. (2018). "TypeScript Microservices".
Iskandar, A., Chivukulu, S. (2019). "Web Development with Angular and Bootstrap - Third Edition".
Hennessy, K., Arora, C. (2018). "Angular 6 by Example".
Jansen, R., Wolf, I., Vane, V. (2016). "TypeScript: Modern JavaScript Development".
Mohammed, Z. (2019). "Angular Projects".
Seshadri, S. (2018). "Angular: Up and Running".
Wilken, J. (2018). "Angular in Action".
Related
I wanted to investigate the internals of the Math object in JavaScript as running in Node. I assumed I would get information on what C++ methods the V8 engine called, etc. but I get information showing TypeScript interfaces for the Math object.
Can anyone explain why TypeScript interfaces are being shown when one displays information on V8's implementation of JavaScript's Math object?
The underlying detailed engine implementation of functions
Wouldn't make sense to the vast majority of script-writers
are not standardized - there are different environments, VSCode wouldn't assume that the file being examined would always be running in V8
In comparison, the TypeScript documentation for these sorts of built-in functions is standardized, and is relatively simple to understand, even for those who may not have seen it before.
In addition to what #CertainPerformance said:
How engines implement built-in functions is completely up to them: it could be a JavaScript implementation (in which case you could certainly argue that it could be instructive for IDEs like VSCode to show the source), it could be C++ (or whichever language the engine is written in), it could be hand-written assembly; in case of current versions of V8, Math.min is implemented using V8's own DSL ("domain specific language") called "Torque", which despite looking a bit like TypeScript is a totally different beast under the hood (in short: it gets compiled to C++ source, which in turn is compiled to an executable that produces assembly code which is then embedded into the V8 binary).
Compiled (C/C++/Rust/...) binaries in general (in Release builds) don't include information about which functions they consist of (much less those functions' source code), so there's no way for IDEs to get at that information even if they wanted to. (This is why "Debug" builds are a thing.)
If you still want to study V8's implementation, you can find many of the Math builtins here.
So, showing the TypeScript definitions of the signatures of the Math builtins is pretty much the best that a JavaScript IDE can do.
I saw those javascript front-end build tools, e.g. webpack, using the word "compile" from time to time. I am not sure what does compile javascript codes mean exactly, at least not like compile c/c++ codes.
I think I understand the "build" process in general, like bundle all js codes into one big file, minify/uglify the codes, using babel to transforms ES6 syntax(transpile). But what does compiling mean here, how does it fit in the whole building process or it is just another name for the whole build process?
Currently, I thought it may be just another name for using Babel to transforms ES6 syntax.
PS. after reading this SO Is Babel a compiler or transpiler? I believe my question is not same as that. Because it is not just related to Bable. For example, webpack also uses the term compiler https://webpack.js.org/api/compiler/ I do not understand its meaning there!
Browserify uses compiler as well e.g, https://github.com/robrichard/browserify-compile-templates "Compiles underscore templates from HTML script tags into CommonJS in a browserify transform"
It's better to describe the process as "transpilation."
Javascript always executes in a specific environment: in Chrome and Electron, it's the V8 engine; in Firefox, it's SpiderMonkey; etc. Each of these engines supports a specific set of language features and not others. As an example, some engines only support var and do not support const or let. Some support async/await, and others only support Promise.
But web developers know about these other features, and they want to use them, even when they're writing for an engine that doesn't support those features. Why? Most new language features are designed with the goal of making it possible to express complicated concepts in simpler and cleaner ways. This is extremely important, because the number one job of code is to make its purpose clear.
Thus, most language features are essentially syntactic sugar for existing functionality. In those cases, it's always possible to express a routine using both new and old syntax. This is a logical necessity.
A transpiler like Babel can read a script written using advanced syntax, and then re-express the script using a restricted set of language features. Relying on an intermediate representation called an abstract syntax tree, it can produce code that is guaranteed to be functionally equivalent, even though it does the work using very different, more widely-supported control structures.
Perhaps we web developers have gotten lazy in our terminology. When we talk of "compiling" javascript, we aren't usually talking about converting the script to something like bytecode. We're talking about transpilation.
Other kinds of build tasks are also becoming quite common. These days, the front-end is obsessed with a million flavors of "templating," because it's extremely tedious and confusing to describe DOM changes using pure javascript, and because application complexity is increasingly very rapidly. Some frameworks require you to convert source code to other intermediary forms that are later consumed by the web application at runtime. Others permit devs to describe UI using invented syntaxes that no browser is even attempting to support natively. Which tasks are needed varies by application depending on which frameworks are being used, the particulars of the application architecture, and the contours of the deployment environment, and that's just a start.
At its foundation, a web page is built using HTML, CSS, and javascript. That much hasn't changed. But today, most serious applications are built almost entirely in javascript (or something very much like it) and sass. Building the application is the process of applying a set of transformations to the source code to yield the final artifacts in those three bedrock languages.
We lump all that stuff under the term "compile."
You pretty much hit the nail on the head. When the Compile (or more appropriately transpilation) operation happens on a JavaScript project it can mean a number of things. As you mentioned these could range from minification, applying polyfills, shims, or the literal act of "compiling" the scripts into a single bundle file for platform/browser consumption.
Transpilation when using super sets of the JavaScript language such as TypeScript, ActionScript, or UnityScript describes the process of converting the source x-script back into native JavaScript which can be in turn be interpreted by a browser (since the browser doesn't recognize the superset languages).
However you are absolutely correct. We aren't compiling our JavaScript into binary, but the term gets thrown around a lot which can lead to confusion. All that said, we are closing in on the age of adoption of WebAssembly and ASMJs which promises to bring the age of bytecode running in the browser which will bring about some interesting possibilities, but alas... That's a story for another day ;)
You're right when you say these front-end Javascript tools don't use the word compile in same context in what your used to with build tools for languages like C/C++. C/C++ compilers turn source code into machine code.
These JavaScript build tools-- like Webpack-- use the word compile in a sense thats more metaphorical than conventional.
When web build tools use the word compile, they're using it in the sense that they are transpiling, minifying (a.k.a uglyfying), and bundling the source files so they are better optimized for client browsers and network requests. (Smaller file sizes, better browser compatibility, less HTTP requests from bundled assets, etc.)
Asm.js comes from a new category of JavaScript apps: C/C++ applications that’ve been compiled into JavaScript. It’s a subset of JavaScript that’s been spawned by Mozilla’s Emscripten project.
But how does it work, and why would I use it?
Why compile to JavaScript?
JavaScript is the only language which works in all web browsers. Although only JavaScript will run in the browser, you can still write in other languages and still compile to JavaScript, thereby allowing it to also run in the browser. This is made possible by a technology known as emscripten.
Emscripten is an LLVM based project that compiles C and C++ into highly performant JavaScript in the asm.js format. In short: near native speeds, using C and C++, inside of the browser. Even better, emscripten converts OpenGL, a desktop graphics API, into WebGL, which is the web variant of that API.
How does asm.js fit into the picture?
Asm.js, short for Assembly JavaScript, is a subset of JavaScript. An asm.js program will behave identically whether it is run in an existing JavaScript engine or an ahead-of-time (AOT) compiling engine that recognizes and optimizes asm.js—except for speed, of course!
In terms of speed, it’s difficult to offer a precise measurement of how it compares to native code, but preliminary benchmarks of C programs compiled to asm.js are usually within a factor of 2 slowdown over native compilation with clang, the compiler frontend for C, C++, and Obj-C programming languages. It’s important to note that this is a “best” case for single-threaded programs. More on this limitation of the JavaScript language below.
On the backend, Clang uses LLVM, which is a library for constructing, optimizing and producing intermediate and/or binary machine code (those 0s and 1s again). LLVM can be used as a compiler framework, where you provide the “front end” (parser and lexer such as Clang) and the “back end” (code that converts LLVM representation to actual machine code)
Further reading: Alon Zakai of Mozilla has a fantastic slide deck which goes into further detail about how this all works.
So how cool is asm.js? Well it has its own Twitter account, #asmjs. While the asm site is a bit sparse, it does cover the W3C spec, in addition to having a thorough FAQ. Even better, Mozilla coordinated the Humble Mozilla Bundle in 2014, which allowed you to buy a bunch of gamest that took advantage of asm.js.
Why not just turn your JavaScript code into asm.js?
JavaScript can’t really be compiled to asm.js and offer much of a benefit, because of its dynamic nature. It’s the same problem as when trying to compile it to C or even to native code – a VM with it would be necessary to take care of those non-static aspects. You could write asm.js by hand, however.
If one could already translate standard Javascript in a fully static manner, there would be no need for asm.js. Asm.js exists so for the promise that Javascript will get faster without any effort from the developer. It would be very difficult for the JIT to understand a dynamic language as well as a static compiler.
To better understand this, it is important to comprehend why asm.js offers a performance benefit at all; or why statically-typed languages perform better than dynamically-typed ones. One reason is “run-time type checking takes time,” and a more thought out answer would include the enhanced feasibility of optimizing statically-typed code. A final perk of going from a statically typed language such as C is the fact that the compiler knows the type of each object when it is being compiled.
Asm.js is a restricted subset of JS that can be easily translated to bytecode. The first step required would need to break down all the advanced features of JS to that subset for getting this advantage, which is a bit complicated. But JavaScript engines are optimized and designed to translate all those advanced features directly into bytecode – so an intermediate step like asm.js doesn’t offer much of an advantage.
I go into greater detail and pictures in this post.
Before using any library, framework etc. in JavaScript, I am interested in it mechanism.
I would like to find out how CoffeeScript works.
My assumption:
1st step: compiler gets string from:
<script type="text/coffeescript"></script>
2nd: it creates a js-code like a string:
it = "test" -> "var it = 'test';"
and the last step compiler uses eval() to implement a code.
P.S.:
Why does it become popular?
It has an influence upon performance, after all we spend a lot of time to execute .coffee files.
The usual approach is to compile CoffeeScript code server-side, and then link JavaScript in your HTML files. This is normally performed using the coffeee command line utility, but you can also find build systems that take care of it for you, such as Grunt, Brunch, etc. You can also write Makefiles or simple shell scripts to take care of this for you.
When using some of the build systems and the coffee tool, you have an option of having the tools monitor your CoffeeScript sources and recompile as soon as you save them. This can be quite handy. Look at the 'watch' feature in the documentation.
My guess for CoffeeScript popularity is that it gives you an arguably nicer syntax. Personally, I find the greatest merit of CoffeeScript is added syntactic sugar like list comprehensions and the fact it treats everything as an expression (e.g., ability to return for loops or if-else blocks from functions). You will also find languages that take this idea even further, like Coco, LiveScript.
One thing to note is that CoffeeScript is not an interpreted language. It's transpiled (compiled into another language) and then executed by the target runtime (JavaScript engine). Because of this, it has the same performance characteristics as equivalent JavaScript code. Whether you can manually write more performant code is another issue. You probably can. At any rate, it's a bit silly to talk about CoffeeScript 'performance'. As for the performance of compiled CoffeeScript, with good knowledge of JavaScript, you can probably optimize here and there, but I haven't had a need to do it ever.
The usual way of using Coffee Script is to compile in as a step in your build process. So you would write Coffee Script, then compile it to plain Javascript, and then use that in your web app.
This carries no runtime cost, because browser will load only Javascript, i.e.:
<script type="text/javascript" src="compiled-js-file.js"></script>
You can use coffee command directly to compile, or some more fancy build systems such as Gulp or Grunt.
You can see Coffe Script website to see what features it has (this is what attracts developers). Most useful, in my opinion, are:
array syntax for functions (JS will support it in ES6)
existential operator to protect you from null value errors
classes (also present in ES6)
destructuring assignment
Also, this means then when you are debugging such a webapp, you will not be able to see where exactly the error is (or setup break points in coffee sources). Fortunately, we have source maps for exactly that problem.
I am using GWT, which includes a Java-to-JavaScript compiler. Before this project, targeting the JavaScript runtime from a different language hadn't occurred to me, and I'm enjoying the GWT experience.
A quick search revealed Java2Script as another Java-to-JavaScript solution. Are there any other mature compilers that target the JavaScript runtime?
List of languages that compile to JS
You also have Haxe. It features static, structural, strong and inferred typing; algebraic data types; lambda expressions with closure support; a module system and can compile not only to JavaScript but also Flash, C++, Neko, PHP. Java support is under development too.
Pyjamas compiles Python to JavaScript.
HotRuby runs Ruby source code under JavaScript and Flash.
Orto is (was?) a JVM implemented in JavaScript. (Original site is down; link is to a blog entry.)
The ZK framework, which likes to compare themselves favorably against GWT, uses Java and XML to generate JavaScript. (They claim that it takes far less code than GWT to do the same stuff.)
And I have heard it well-argued that jQuery is a separate language that happens to be implemented in, and run under, JavaScript. :-)
OpenLaszlo is on open source XML -> Javascript (technically DHTML, also can compile to Flash) compiler. I've played with it a little bit and it seemed interesting, although have never used it seriously (bad IDE support when I tried it).
Objective-j is a similar project that resembles objective-c, although runs as javascript (not sure if it compiles it or has a js interpreter). I don't know much about it, but do see posts about it on the Ajaxian from time to time.
Parenscript is "a translator from a small Lispy language to JavaScript". It's not Common Lisp -- it's mostly just Lisp syntax for Javascript, though for simple things you can write the same code to target both, if you're careful. I'm not sure I'd call it "mature", either.
While there are other products which compile to javascript (noted in the other comments), I believe that GWT is, by far, the most mature one out there, in terms of real-world usage.
The simple fact that a number of Google's core applications use GWT (e.g.: the new adwords GUI, Google wave, etc) means you can have confidence the product is going to be maintained for at least the next few years, it isn't just going to fade away anytime soon.
Another thing to keep in mind is that GWT is far more than a java-to-javascript compiler, it also is an optimizing compiler, it has hosted mode, it is fully interoperable with native javascript, it does image bundling, it does code spliting in the new version, etc.
Script #
JSC
cappuccino (sort of)
The inventors of Clojure (a JVM based Lisp dialect) launched ClojureScript in mid-2011. ClojureScript compiles Clojure source code into JavaScript, making use of the Google Closure compiler and the Closure framework. ClojureScript code can run both in the browser client, or on node.js servers.
Here's a shameless plug for a project I started and am continuing to develop: scxml-js, a Statecharts-to-JavaScript compiler