JS Module Transpiler is an experimental compiler that allows you to write your JavaScript using a subset of the current ES6 module syntax, and compile it into AMD modules (and soon, CommonJS modules)
WARNING: The ES6 module syntax is still undergoing a lot of churn, and will definitely still change before final approval.
JS Module Transpiler will track ES6 syntax, and not attempt to maintain backwards compatibility with syntax that ultimately did not succeed as part of ES6.
This compiler provides a way to experiment with ES6 syntax in real world scenarios to see how the syntax holds up. It also provides a nicer, more declarative way to write AMD (or CommonJS) modules.
The easiest way to use the transpiler is via the command line:
$ gem install js_module_transpiler
$ compile-modules foo.js --to compiled
Here is the basic usage:
compile-modules INPUT --to OUTPUT [--type=TYPE]
[--anonymous] [--module-name=NAME]
[--global=GLOBAL] [--imports=IMPORTS]
INPUT
An input file or glob pattern relative to the current
directory to process.
OUTPUT
An output directory relative to the current directory.
If it does not exist, it will be created.
TYPE
One of `amd` (for AMD output), `cjs` (for CommonJS
output) or `globals` (for outputting to `window`).
ANONYMOUS
If you use the --anonymous flag with the AMD type, the
transpiler will output a module with no name.
NAME
You can supply a name to use as the module name.
By default, the transpiler will use the name of the
file (without the ending `.js`) as the module name.
You may not use this option if your INPUT resolves
to multiple files.
GLOBAL
This option is only supported when the type is
`globals`. By default, the `globals` option will
attach all of the exports to `window`. This option
will attach the exports to a single named variable
on `window` instead.
IMPORTS
This option is only supported when the type is
`globals`. It is a hash option. If your module
includes imports, you must use this option to
map the import names onto globals. For example,
`--imports ember:Ember underscore:_`
You can also use the transpiler as a library:
require "js_module_transpiler"
compiler = JsModuleTranspiler::Compiler.new(string, name)
compiler.to_amd # AMD output
If you want to emit globals output, and your module has
imports, you must supply an imports
hash. You can also
use the global
option to specify that exports should
be added to a single global instead of window
.
require "js_module_transpiler"
imports = { "underscore" => "_", "ember" => "Ember" }
options = { imports: imports, global: "RSVP" }
compiler = JsModuleTranspiler::Compiler.new(string, name, options)
compiler.to_globals # AMD output
The string
parameter is a string of JavaScript written using
the declarative module syntax.
The name
parameter is an optional name that should be used
as the name of the module if appropriate (for AMD, this maps
onto the first parameter to the define
function).
Again, this syntax is in flux and is closely tracking the module work being done by TC39.
There are two ways to do exports.
var get = function(obj, key) {
return obj[key];
};
var set = function(obj, key, value) {
obj[key] = value;
return obj;
};
export { get, set };
You can also write this form as:
var get = function(obj, key) {
return obj[key];
};
export get;
var set = function(obj, key, value) {
obj[key] = value;
return obj;
};
export set;
Both of these export two variables: get
and set
. Below,
in the import section, you will see how to use these exports
in another module.
You can also export a single variable as the module itself:
var jQuery = function() {};
jQuery.prototype = {
// ...
};
export = jQuery;
If you want to import variables exported individually from another module, you use this syntax:
import { get, set } from "ember";
To import a module that set its export using export =
,
you use this syntax:
import "jquery" as jQuery;
As you can see, the import and export syntaxes are symmetric.
This input:
var get = function(obj, key) {
return obj[key];
};
var set = function(obj, key, value) {
obj[key] = value;
return obj;
};
export { get, set };
will compile into this AMD output:
define("ember",
[],
function(__exports__) {
var get = function(obj, key) {
return obj[key];
};
var set = function(obj, key, value) {
obj[key] = value;
return obj;
};
__exports__.get = get;
__exports__.set = set;
});
The output is the same whether you use the single-line
export (export { get, set }
) or multiple export lines,
as above.
This input:
var jQuery = function() {};
jQuery.prototype = {
// ...
};
export = jQuery;
will compile into this AMD output:
define("ember",
[],
function() {
var jQuery = function() {};
jQuery.prototype = {
// ...
};
return jQuery;
});
This input:
import { get, set } from "ember";
will compile into this AMD output:
define("app",
["ember"],
function(__dependency1__) {
var get = __dependency1__.get;
var set = __dependency1__.set;
});
This input:
import "jquery" as jQuery;
will compile into this AMD output:
define("app",
["jquery"],
function(jQuery) {
});
Add this line to your application's Gemfile:
gem 'js_module_transpiler'
And then execute:
$ bundle
Or install it yourself as:
$ gem install js_module_transpiler
- Fork it
- Create your feature branch (
git checkout -b my-new-feature
) - Commit your changes (
git commit -am 'Add some feature'
) - Push to the branch (
git push origin my-new-feature
) - Create new Pull Request