add support for an optional runtime - closes #129
This commit is contained in:
parent
8ef5148870
commit
ab9cd4e630
4
Makefile
4
Makefile
@ -55,6 +55,8 @@ publish:
|
|||||||
make build
|
make build
|
||||||
cp dist/6to5.js browser.js
|
cp dist/6to5.js browser.js
|
||||||
|
|
||||||
|
node bin/6to5-runtime >runtime.js
|
||||||
|
|
||||||
node bin/cache-templates
|
node bin/cache-templates
|
||||||
test -f templates.json
|
test -f templates.json
|
||||||
|
|
||||||
@ -64,4 +66,4 @@ publish:
|
|||||||
|
|
||||||
git push --follow-tags
|
git push --follow-tags
|
||||||
|
|
||||||
rm -rf templates.json browser.js
|
rm -rf templates.json browser.js runtime.js
|
||||||
|
|||||||
90
README.md
90
README.md
@ -43,6 +43,7 @@ It's as easy as:
|
|||||||
- [Browser](#browser)
|
- [Browser](#browser)
|
||||||
- [Modules](#modules)
|
- [Modules](#modules)
|
||||||
- [Caveats](#caveats)
|
- [Caveats](#caveats)
|
||||||
|
- [Runtime](#runtime)
|
||||||
- [Differences](#differences)
|
- [Differences](#differences)
|
||||||
|
|
||||||
## [Features](FEATURES.md)
|
## [Features](FEATURES.md)
|
||||||
@ -177,7 +178,12 @@ to5.transformFile("filename.js", options, function (err, result) {
|
|||||||
|
|
||||||
// Set `sources[0]` on returned source map.
|
// Set `sources[0]` on returned source map.
|
||||||
// Default: `filename` option.
|
// 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
|
### 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
|
||||||
|
<script src="node_modules/6to5/browser.js"></script>
|
||||||
|
<script type="text/6to5">
|
||||||
|
class Test {
|
||||||
|
test() {
|
||||||
|
return "test";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var test = new Test;
|
||||||
|
test.test();
|
||||||
|
</script>
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Build
|
||||||
|
|
||||||
You can build a browser version of the compiler by running the following in the
|
You can build a browser version of the compiler by running the following in the
|
||||||
6to5 directory:
|
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`.
|
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
|
#### API
|
||||||
global `to5`.
|
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
to5.transform("class Test {}").code;
|
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)
|
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.
|
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
|
## Differences
|
||||||
|
|
||||||
### Philosophy
|
### Philosophy
|
||||||
|
|||||||
4
bin/6to5-runtime
Executable file
4
bin/6to5-runtime
Executable file
@ -0,0 +1,4 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
|
||||||
|
var runtime = require("../lib/6to5/runtime");
|
||||||
|
console.log(runtime(process.argv[2]));
|
||||||
@ -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("-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("-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("-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("-m, --modules [modules]", "Module formatter type to use [common]", "common");
|
||||||
commander.option("-w, --whitelist [whitelist]", "Whitelist of transformers to ONLY use", util.list);
|
commander.option("-w, --whitelist [whitelist]", "Whitelist of transformers to ONLY use", util.list);
|
||||||
@ -87,6 +88,7 @@ exports.opts = {
|
|||||||
blacklist: commander.blacklist,
|
blacklist: commander.blacklist,
|
||||||
whitelist: commander.whitelist,
|
whitelist: commander.whitelist,
|
||||||
sourceMap: commander.sourceMaps || commander.sourceMapsInline,
|
sourceMap: commander.sourceMaps || commander.sourceMapsInline,
|
||||||
|
runtime: commander.runtime,
|
||||||
modules: commander.modules
|
modules: commander.modules
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -5,7 +5,6 @@ var SHEBANG_REGEX = /^\#\!.*/;
|
|||||||
var transform = require("./transformation/transform");
|
var transform = require("./transformation/transform");
|
||||||
var generate = require("./generation/generator");
|
var generate = require("./generation/generator");
|
||||||
var Scope = require("./traverse/scope");
|
var Scope = require("./traverse/scope");
|
||||||
var acorn = require("acorn-6to5");
|
|
||||||
var util = require("./util");
|
var util = require("./util");
|
||||||
var t = require("./types");
|
var t = require("./types");
|
||||||
var _ = require("lodash");
|
var _ = require("lodash");
|
||||||
@ -19,6 +18,8 @@ function File(opts) {
|
|||||||
this.ast = {};
|
this.ast = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
File.declarations = ["extends", "class-props", "slice"];
|
||||||
|
|
||||||
File.normaliseOptions = function (opts) {
|
File.normaliseOptions = function (opts) {
|
||||||
opts = opts || {};
|
opts = opts || {};
|
||||||
|
|
||||||
@ -28,7 +29,8 @@ File.normaliseOptions = function (opts) {
|
|||||||
whitelist: [],
|
whitelist: [],
|
||||||
sourceMap: false,
|
sourceMap: false,
|
||||||
filename: "unknown",
|
filename: "unknown",
|
||||||
modules: "common"
|
modules: "common",
|
||||||
|
runtime: false
|
||||||
});
|
});
|
||||||
|
|
||||||
_.defaults(opts, {
|
_.defaults(opts, {
|
||||||
@ -36,6 +38,10 @@ File.normaliseOptions = function (opts) {
|
|||||||
sourceMapName: opts.filename
|
sourceMapName: opts.filename
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (opts.runtime === true) {
|
||||||
|
opts.runtime = "to5Runtime";
|
||||||
|
}
|
||||||
|
|
||||||
transform._ensureTransformerNames("blacklist", opts.blacklist);
|
transform._ensureTransformerNames("blacklist", opts.blacklist);
|
||||||
transform._ensureTransformerNames("whitelist", opts.whitelist);
|
transform._ensureTransformerNames("whitelist", opts.whitelist);
|
||||||
|
|
||||||
@ -43,18 +49,18 @@ File.normaliseOptions = function (opts) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
File.prototype.getModuleFormatter = function (type) {
|
File.prototype.getModuleFormatter = function (type) {
|
||||||
var ModuleLoader = transform.moduleFormatters[type];
|
var ModuleFormatter = transform.moduleFormatters[type];
|
||||||
|
|
||||||
if (!ModuleLoader) {
|
if (!ModuleFormatter) {
|
||||||
var loc = util.resolve(type);
|
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);
|
throw new ReferenceError("unknown module formatter type " + type);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new ModuleLoader(this);
|
return new ModuleFormatter(this);
|
||||||
};
|
};
|
||||||
|
|
||||||
File.prototype.parseShebang = function (code) {
|
File.prototype.parseShebang = function (code) {
|
||||||
@ -70,13 +76,26 @@ File.prototype.parseShebang = function (code) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
File.prototype.addDeclaration = function (name) {
|
File.prototype.addDeclaration = function (name) {
|
||||||
|
if (!_.contains(File.declarations, name)) {
|
||||||
|
throw new ReferenceError("unknown declaration " + name);
|
||||||
|
}
|
||||||
|
|
||||||
var declar = this.declarations[name];
|
var declar = this.declarations[name];
|
||||||
if (declar) return declar.uid;
|
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));
|
var uid = t.identifier(this.generateUid(name));
|
||||||
this.declarations[name] = {
|
this.declarations[name] = {
|
||||||
uid: uid,
|
uid: uid,
|
||||||
node: util.template(name)
|
node: ref
|
||||||
};
|
};
|
||||||
return uid;
|
return uid;
|
||||||
};
|
};
|
||||||
@ -118,7 +137,7 @@ File.prototype.generate = function () {
|
|||||||
var opts = this.opts;
|
var opts = this.opts;
|
||||||
var ast = this.ast;
|
var ast = this.ast;
|
||||||
|
|
||||||
var result = generate(this.code, ast, opts);
|
var result = generate(ast, opts, this.code);
|
||||||
|
|
||||||
if (this.shebang) {
|
if (this.shebang) {
|
||||||
// add back shebang
|
// add back shebang
|
||||||
@ -133,7 +152,10 @@ File.prototype.generate = function () {
|
|||||||
};
|
};
|
||||||
|
|
||||||
File.prototype.generateUid = function (name, scope) {
|
File.prototype.generateUid = function (name, scope) {
|
||||||
|
name = t.toIdentifier(name);
|
||||||
|
|
||||||
scope = scope || this.scope;
|
scope = scope || this.scope;
|
||||||
|
|
||||||
var uid;
|
var uid;
|
||||||
do {
|
do {
|
||||||
uid = this._generateUid(name);
|
uid = this._generateUid(name);
|
||||||
@ -142,17 +164,6 @@ File.prototype.generateUid = function (name, scope) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
File.prototype._generateUid = function (name) {
|
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 uids = this.uids;
|
||||||
var i = uids[name] || 1;
|
var i = uids[name] || 1;
|
||||||
|
|
||||||
|
|||||||
@ -2,6 +2,8 @@ var transform = require("./transformation/transform");
|
|||||||
var fs = require("fs");
|
var fs = require("fs");
|
||||||
var _ = require("lodash");
|
var _ = require("lodash");
|
||||||
|
|
||||||
|
exports.runtime = require("./runtime");
|
||||||
|
|
||||||
exports.register = function (opts) {
|
exports.register = function (opts) {
|
||||||
var register = require("./register");
|
var register = require("./register");
|
||||||
if (opts != null) register(opts);
|
if (opts != null) register(opts);
|
||||||
|
|||||||
44
lib/6to5/runtime.js
Normal file
44
lib/6to5/runtime.js
Normal file
@ -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;
|
||||||
|
};
|
||||||
@ -15,7 +15,8 @@
|
|||||||
"main": "lib/6to5/index.js",
|
"main": "lib/6to5/index.js",
|
||||||
"bin": {
|
"bin": {
|
||||||
"6to5": "./bin/6to5/index.js",
|
"6to5": "./bin/6to5/index.js",
|
||||||
"6to5-node": "./bin/6to5-node"
|
"6to5-node": "./bin/6to5-node",
|
||||||
|
"6to5-runtime": "./bin/6to5-runtime"
|
||||||
},
|
},
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"harmony",
|
"harmony",
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user