The JavaScript compiler

Ceylon code can be compiled to JavaScript. There are two styles that can be used:

  • Lexical scope, which is the default, and
  • Prototype style, also known as optimized.

Lexical scope style

In lexical scope style, a type´s methods and attributes are assigned to each new instance as it is created. This offers good encapsulation but incurs in some performance costs.

Prototype style

In prototype style, all methods and attributes are assigned to the type´s prototype, so that new instances automatically have all those methods and attributes. This has much better performance but all methods and attributes are visible in native JavaScript.

Declaration names

A Ceylon module is compiled as a CommonJS module, but since this format has no notion of packages, all the packages in the Ceylon module will be contained in the same CommonJS file. To avoid naming collisions, there are some rules used when generating names for top-level declarations:

  • If the declaration is in the module´s root package, then its name is basically the same.
  • If the declaration is in a subpackage, its name will have the subpackage name appended to it.

For example, for a module my.module the declaration my.module.MyClass will simply be called MyClass but my.module.sub1.sub2.MyClass will be called MyClass$sub1$sub2.

Compile order

When compiling to JavaScript, the order in which the files are processed by the compiler can be important, especially when mixing native code with code generated by the compiler. You can mix native code simply by adding a .js file to the list of sources to be compiled, for example:

ceylon compile-js unit1.ceylon unit2.ceylon some_native_stuff.js unit3.ceylon

The compiler will generate a CommonJS module containing the results of processing unit1.ceylon, then unit2.ceylon, then copying the contents of some_native_stuff.js and finally processing unit3.ceylon.

Runnable methods

When compiling for the JVM, any top-level method can be used as an entry point to run a program. The default is run but you can specify any other top-level method.

When compiling to JavaScript, only shared top-level methods can be used as entry points to run a program with the run-js command. This is because a command is executed that loads the specified module and runs the specified method from it, and since only shared top-level declarations are directly added to the exports object of the CommonJS module, only a shared top-level method can be run.

See also