diff --git a/Makefile b/Makefile
index 2274e81ee4..96de83b3d0 100644
--- a/Makefile
+++ b/Makefile
@@ -55,6 +55,8 @@ publish:
make build
cp dist/6to5.js browser.js
+ node bin/6to5-runtime >runtime.js
+
node bin/cache-templates
test -f templates.json
@@ -64,4 +66,4 @@ publish:
git push --follow-tags
- rm -rf templates.json browser.js
+ rm -rf templates.json browser.js runtime.js
diff --git a/README.md b/README.md
index f58af6a14b..d01ec44642 100644
--- a/README.md
+++ b/README.md
@@ -43,6 +43,7 @@ It's as easy as:
- [Browser](#browser)
- [Modules](#modules)
- [Caveats](#caveats)
+- [Runtime](#runtime)
- [Differences](#differences)
## [Features](FEATURES.md)
@@ -177,7 +178,12 @@ to5.transformFile("filename.js", options, function (err, result) {
// Set `sources[0]` on returned source map.
// Default: `filename` option.
- sourceFileName: "filename"
+ sourceFileName: "filename",
+
+ // Optionally replace all 6to5 helper declarations with a referenece to this
+ // variable. If set to `true` then the default namespace is used "to5Runtime".
+ // Default: false
+ runtime: true
}
```
@@ -226,6 +232,33 @@ require("6to5/register")({
### Browser
+A browser version of 6to5 is available from `browser.js` inside the 6to5
+directory in an npm release.
+
+#### Scripts
+
+While it's not recommended for serious use, when the browser version is included
+all scripts with the type `text/ecmascript-6` and `text/6to5` are automatically
+compiled and ran.
+
+For example:
+
+```html
+
+
+```
+
+#### Build
+
You can build a browser version of the compiler by running the following in the
6to5 directory:
@@ -233,8 +266,7 @@ You can build a browser version of the compiler by running the following in the
This will output the files `dist/6to5.js` and `dist/6to5.min.js`.
-Just include one of those in the browser and access the transform method via the
-global `to5`.
+#### API
```javascript
to5.transform("class Test {}").code;
@@ -320,6 +352,58 @@ class Bar extends Foo {
The [regenerator runtime](https://github.com/facebook/regenerator/blob/master/runtime.js)
and an [ES6 polyfill](#polyfill) are required in order for generators to work.
+## Runtime
+
+6to5 has a few helper functions that'll be placed at the top of the generated
+code so it's not inlined multiple times throughout that file. This may become an
+issue if you have multiple files, especially when you're sending them to the
+browser. gzip alleviates most of this concern but it's still not ideal.
+
+You can tell 6to5 to not place any declarations at the top of your files and
+instead just point them to a reference contained within the runtime.
+
+Simply use the following option if you're using the [Node API](#node-1):
+
+```javascript
+{
+ runtime: true
+}
+```
+
+or the following flag if you're using the [CLI](#cli):
+
+ $ 6to5 --runtime
+
+Then just include the runtime before your generated code.
+
+### Getting the runtime
+
+You can get the runtime via either:
+
+ $ 6to5-runtime
+
+or
+
+```javascript
+require("6to5").runtime();
+```
+
+or from an npm release in `runtime.js` from the 6to5 directory.
+
+### Customising namespace
+
+You can also customise the runtime namespace by passing an optional namespace
+argument:
+
+```javascript
+require("6to5").runtime("myCustomNamespace");
+```
+
+ $ 6to5-runtime myCustomNamespace
+
+See [Options - runtime](#options) for documentation on changing the reference in
+generated code.
+
## Differences
### Philosophy
diff --git a/bin/6to5-runtime b/bin/6to5-runtime
new file mode 100755
index 0000000000..a19e68f826
--- /dev/null
+++ b/bin/6to5-runtime
@@ -0,0 +1,4 @@
+#!/usr/bin/env node
+
+var runtime = require("../lib/6to5/runtime");
+console.log(runtime(process.argv[2]));
diff --git a/bin/6to5/index.js b/bin/6to5/index.js
index a3991603f4..b492dbb1b7 100755
--- a/bin/6to5/index.js
+++ b/bin/6to5/index.js
@@ -10,6 +10,7 @@ commander.option("-t, --source-maps-inline", "Append sourceMappingURL comment to
commander.option("-s, --source-maps", "Save source map alongside the compiled code");
commander.option("-f, --filename [filename]", "Filename to use when reading from stdin - this will be used in source-maps, errors etc [stdin]", "stdin");
commander.option("-w, --watch", "Recompile files on changes");
+commander.option("-r, --runtime", "Replace 6to5 declarations with references to a runtime");
commander.option("-m, --modules [modules]", "Module formatter type to use [common]", "common");
commander.option("-w, --whitelist [whitelist]", "Whitelist of transformers to ONLY use", util.list);
@@ -87,6 +88,7 @@ exports.opts = {
blacklist: commander.blacklist,
whitelist: commander.whitelist,
sourceMap: commander.sourceMaps || commander.sourceMapsInline,
+ runtime: commander.runtime,
modules: commander.modules
};
diff --git a/lib/6to5/file.js b/lib/6to5/file.js
index 9bbf157cf8..9e8d6a674b 100644
--- a/lib/6to5/file.js
+++ b/lib/6to5/file.js
@@ -5,7 +5,6 @@ var SHEBANG_REGEX = /^\#\!.*/;
var transform = require("./transformation/transform");
var generate = require("./generation/generator");
var Scope = require("./traverse/scope");
-var acorn = require("acorn-6to5");
var util = require("./util");
var t = require("./types");
var _ = require("lodash");
@@ -19,6 +18,8 @@ function File(opts) {
this.ast = {};
}
+File.declarations = ["extends", "class-props", "slice"];
+
File.normaliseOptions = function (opts) {
opts = opts || {};
@@ -28,7 +29,8 @@ File.normaliseOptions = function (opts) {
whitelist: [],
sourceMap: false,
filename: "unknown",
- modules: "common"
+ modules: "common",
+ runtime: false
});
_.defaults(opts, {
@@ -36,6 +38,10 @@ File.normaliseOptions = function (opts) {
sourceMapName: opts.filename
});
+ if (opts.runtime === true) {
+ opts.runtime = "to5Runtime";
+ }
+
transform._ensureTransformerNames("blacklist", opts.blacklist);
transform._ensureTransformerNames("whitelist", opts.whitelist);
@@ -43,18 +49,18 @@ File.normaliseOptions = function (opts) {
};
File.prototype.getModuleFormatter = function (type) {
- var ModuleLoader = transform.moduleFormatters[type];
+ var ModuleFormatter = transform.moduleFormatters[type];
- if (!ModuleLoader) {
+ if (!ModuleFormatter) {
var loc = util.resolve(type);
- if (loc) ModuleLoader = require(loc);
+ if (loc) ModuleFormatter = require(loc);
}
- if (!ModuleLoader) {
+ if (!ModuleFormatter) {
throw new ReferenceError("unknown module formatter type " + type);
}
- return new ModuleLoader(this);
+ return new ModuleFormatter(this);
};
File.prototype.parseShebang = function (code) {
@@ -70,13 +76,26 @@ File.prototype.parseShebang = function (code) {
};
File.prototype.addDeclaration = function (name) {
+ if (!_.contains(File.declarations, name)) {
+ throw new ReferenceError("unknown declaration " + name);
+ }
+
var declar = this.declarations[name];
if (declar) return declar.uid;
+ var ref;
+ var runtimeNamespace = this.opts.runtime;
+ if (runtimeNamespace) {
+ name = t.identifier(t.toIdentifier(name));
+ return t.memberExpression(t.identifier(runtimeNamespace), name);
+ } else {
+ ref = util.template(name);
+ }
+
var uid = t.identifier(this.generateUid(name));
this.declarations[name] = {
uid: uid,
- node: util.template(name)
+ node: ref
};
return uid;
};
@@ -118,7 +137,7 @@ File.prototype.generate = function () {
var opts = this.opts;
var ast = this.ast;
- var result = generate(this.code, ast, opts);
+ var result = generate(ast, opts, this.code);
if (this.shebang) {
// add back shebang
@@ -133,7 +152,10 @@ File.prototype.generate = function () {
};
File.prototype.generateUid = function (name, scope) {
+ name = t.toIdentifier(name);
+
scope = scope || this.scope;
+
var uid;
do {
uid = this._generateUid(name);
@@ -142,17 +164,6 @@ File.prototype.generateUid = function (name, scope) {
};
File.prototype._generateUid = function (name) {
- // replace all non-valid identifiers with dashes
- name = name.replace(/[^a-zA-Z0-9]/g, "-");
-
- // remove all dashes and numbers from start of name
- name = name.replace(/^[-0-9]+/, "");
-
- // camel case
- name = name.replace(/[-_\s]+(.)?/g, function (match, c) {
- return c ? c.toUpperCase() : "";
- });
-
var uids = this.uids;
var i = uids[name] || 1;
diff --git a/lib/6to5/index.js b/lib/6to5/index.js
index c1b0a2db3a..29e73fc64c 100644
--- a/lib/6to5/index.js
+++ b/lib/6to5/index.js
@@ -2,6 +2,8 @@ var transform = require("./transformation/transform");
var fs = require("fs");
var _ = require("lodash");
+exports.runtime = require("./runtime");
+
exports.register = function (opts) {
var register = require("./register");
if (opts != null) register(opts);
diff --git a/lib/6to5/runtime.js b/lib/6to5/runtime.js
new file mode 100644
index 0000000000..ee77d65c60
--- /dev/null
+++ b/lib/6to5/runtime.js
@@ -0,0 +1,44 @@
+var generator = require("./generation/generator");
+var util = require("./util");
+var File = require("./file");
+var t = require("./types");
+var _ = require("lodash");
+
+module.exports = function (namespace) {
+ var body = [];
+ var container = t.functionExpression(null, [], t.blockStatement(body));
+
+ var tree = {
+ type: "Program",
+ body: [t.expressionStatement(t.callExpression(container, []))]
+ };
+
+ body.push(t.variableDeclaration("var", [
+ t.variableDeclarator(t.identifier("self"), t.conditionalExpression(
+ t.binaryExpression("===",
+ t.unaryExpression("typeof", t.identifier("global"), true),
+ t.literal("undefined")
+ ),
+ t.identifier("window"),
+ t.identifier("global"))
+ )
+ ]));
+
+ var namespace = t.identifier(namespace || "to5Runtime");
+
+ body.push(t.variableDeclaration("var", [
+ t.variableDeclarator(
+ namespace,
+ t.assignmentExpression("=", t.memberExpression(t.identifier("self"), namespace), t.objectExpression([]))
+ )
+ ]));
+
+ _.each(File.declarations, function (name) {
+ var key = t.identifier(t.toIdentifier(name));
+ body.push(t.expressionStatement(
+ t.assignmentExpression("=", t.memberExpression(namespace, key), util.template(name))
+ ));
+ });
+
+ return generator(tree).code;
+};
diff --git a/package.json b/package.json
index cf7bac9c35..53a7c7220b 100644
--- a/package.json
+++ b/package.json
@@ -15,7 +15,8 @@
"main": "lib/6to5/index.js",
"bin": {
"6to5": "./bin/6to5/index.js",
- "6to5-node": "./bin/6to5-node"
+ "6to5-node": "./bin/6to5-node",
+ "6to5-runtime": "./bin/6to5-runtime"
},
"keywords": [
"harmony",