move some babel-plugins into the main repo

This commit is contained in:
Sebastian McKenzie
2015-09-01 06:58:53 +01:00
parent f33c96c276
commit 9f9d9cd84b
61 changed files with 1779 additions and 0 deletions

View File

@@ -0,0 +1,3 @@
node_modules
*.log
src

View File

@@ -0,0 +1,35 @@
# babel-plugin-constant-folding
Compile static constants (ie. code that we can statically determine to be constant at runtime)
## Installation
```sh
$ npm install babel-plugin-constant-folding
```
## Usage
### Via `.babelrc` (Recommended)
**.babelrc**
```json
{
"plugins": ["constant-folding"]
}
```
### Via CLI
```sh
$ babel --plugins constant-folding script.js
```
### Via Node API
```javascript
require("babel-core").transform("code", {
plugins: ["constant-folding"]
});
```

View File

@@ -0,0 +1,19 @@
{
"name": "babel-plugin-constant-folding",
"version": "1.0.1",
"description": "Compile static constants (ie. code that we can statically determine to be constant at runtime)",
"repository": "babel-plugins/babel-plugin-constant-folding",
"license": "MIT",
"main": "lib/index.js",
"devDependencies": {
"babel": "^5.6.0"
},
"scripts": {
"build": "babel-plugin build",
"push": "babel-plugin publish",
"test": "babel-plugin test"
},
"keywords": [
"babel-plugin"
]
}

View File

@@ -0,0 +1,74 @@
export default function ({ Plugin, types: t }) {
return new Plugin("constant-folding", {
metadata: {
group: "builtin-prepass",
experimental: true
},
visitor: {
AssignmentExpression() {
var left = this.get("left");
if (!left.isIdentifier()) return;
var binding = this.scope.getBinding(left.node.name);
if (!binding || binding.hasDeoptValue) return;
var evaluated = this.get("right").evaluate();
if (evaluated.confident) {
binding.setValue(evaluated.value);
} else {
binding.deoptValue();
}
},
IfStatement() {
var evaluated = this.get("test").evaluate();
if (!evaluated.confident) {
// todo: deopt binding values for constant violations inside
return this.skip();
}
if (evaluated.value) {
this.skipKey("alternate");
} else {
this.skipKey("consequent");
}
},
Scopable: {
enter() {
var funcScope = this.scope.getFunctionParent();
for (var name in this.scope.bindings) {
var binding = this.scope.bindings[name];
var deopt = false;
for (var path of (binding.constantViolations: Array)) {
var funcViolationScope = path.scope.getFunctionParent();
if (funcViolationScope !== funcScope) {
deopt = true;
break;
}
}
if (deopt) binding.deoptValue();
}
},
exit() {
for (var name in this.scope.bindings) {
var binding = this.scope.bindings[name];
binding.clearValue();
}
}
},
Expression: {
exit() {
var res = this.evaluate();
if (res.confident) return t.valueToNode(res.value);
}
}
}
});
}

View File

@@ -0,0 +1,3 @@
node_modules
*.log
src

View File

@@ -0,0 +1,35 @@
# babel-plugin-dead-code-elimination
Eliminate dead code
## Installation
```sh
$ npm install babel-plugin-dead-code-elimination
```
## Usage
### Via `.babelrc` (Recommended)
**.babelrc**
```json
{
"plugins": ["dead-code-elimination"]
}
```
### Via CLI
```sh
$ babel --plugins dead-code-elimination script.js
```
### Via Node API
```javascript
require("babel-core").transform("code", {
plugins: ["dead-code-elimination"]
});
```

View File

@@ -0,0 +1,19 @@
{
"name": "babel-plugin-dead-code-elimination",
"version": "1.0.2",
"description": "Eliminate dead code",
"repository": "babel-plugins/babel-plugin-dead-code-elimination",
"license": "MIT",
"main": "lib/index.js",
"devDependencies": {
"babel": "^5.6.0"
},
"scripts": {
"build": "babel-plugin build",
"push": "babel-plugin publish",
"test": "babel-plugin test"
},
"keywords": [
"babel-plugin"
]
}

View File

@@ -0,0 +1,157 @@
export default function ({ Plugin, types: t }) {
function toStatements(node) {
if (t.isBlockStatement(node)) {
var hasBlockScoped = false;
for (var i = 0; i < node.body.length; i++) {
var bodyNode = node.body[i];
if (t.isBlockScoped(bodyNode)) hasBlockScoped = true;
}
if (!hasBlockScoped) {
return node.body;
}
}
return node;
}
var visitor = {
ReferencedIdentifier(node, parent, scope) {
var binding = scope.getBinding(node.name);
if (!binding || binding.references > 1 || !binding.constant) return;
if (binding.kind === "param" || binding.kind === "module") return;
var replacement = binding.path.node;
if (t.isVariableDeclarator(replacement)) {
replacement = replacement.init;
}
if (!replacement) return;
// ensure it's a "pure" type
if (!scope.isPure(replacement, true)) return;
if (t.isClass(replacement) || t.isFunction(replacement)) {
// don't change this if it's in a different scope, this can be bad
// for performance since it may be inside a loop or deeply nested in
// hot code
if (binding.path.scope.parent !== scope) return;
}
if (this.findParent((path) => path.node === replacement)) {
return;
}
t.toExpression(replacement);
scope.removeBinding(node.name);
binding.path.dangerouslyRemove();
return replacement;
},
"ClassDeclaration|FunctionDeclaration"(node, parent, scope) {
var binding = scope.getBinding(node.id.name);
if (binding && !binding.referenced) {
this.dangerouslyRemove();
}
},
VariableDeclarator(node, parent, scope) {
if (!t.isIdentifier(node.id) || !scope.isPure(node.init, true)) return;
visitor["ClassDeclaration|FunctionDeclaration"].apply(this, arguments);
},
ConditionalExpression(node) {
var evaluateTest = this.get("test").evaluateTruthy();
if (evaluateTest === true) {
return node.consequent;
} else if (evaluateTest === false) {
return node.alternate;
}
},
BlockStatement() {
var paths = this.get("body");
var purge = false;
for (var i = 0; i < paths.length; i++) {
let path = paths[i];
if (!purge && path.isCompletionStatement()) {
purge = true;
continue;
}
if (purge && !path.isFunctionDeclaration()) {
path.dangerouslyRemove();
}
}
},
IfStatement: {
exit(node) {
var consequent = node.consequent;
var alternate = node.alternate;
var test = node.test;
var evaluateTest = this.get("test").evaluateTruthy();
// we can check if a test will be truthy 100% and if so then we can inline
// the consequent and completely ignore the alternate
//
// if (true) { foo; } -> { foo; }
// if ("foo") { foo; } -> { foo; }
//
if (evaluateTest === true) {
return toStatements(consequent);
}
// we can check if a test will be falsy 100% and if so we can inline the
// alternate if there is one and completely remove the consequent
//
// if ("") { bar; } else { foo; } -> { foo; }
// if ("") { bar; } ->
//
if (evaluateTest === false) {
if (alternate) {
return toStatements(alternate);
} else {
return this.dangerouslyRemove();
}
}
// remove alternate blocks that are empty
//
// if (foo) { foo; } else {} -> if (foo) { foo; }
//
if (t.isBlockStatement(alternate) && !alternate.body.length) {
alternate = node.alternate = null;
}
// if the consequent block is empty turn alternate blocks into a consequent
// and flip the test
//
// if (foo) {} else { bar; } -> if (!foo) { bar; }
//
if (t.isBlockStatement(consequent) && !consequent.body.length && t.isBlockStatement(alternate) && alternate.body.length) {
node.consequent = node.alternate;
node.alternate = null;
node.test = t.unaryExpression("!", test, true);
}
}
}
};
return new Plugin("dead-code-elimination", {
metadata: {
group: "builtin-pre",
experimental: true
},
visitor
});
}

View File

@@ -0,0 +1,3 @@
node_modules
*.log
src

View File

@@ -0,0 +1,49 @@
# babel-plugin-eval
Compile eval calls with string literals
## Example
**In**
```javascript
eval("(() => 'foo')");
```
**Out**
```javascript
eval("(function () { return 'foo'; })");
```
## Installation
```sh
$ npm install babel-plugin-eval
```
## Usage
### Via `.babelrc` (Recommended)
**.babelrc**
```json
{
"plugins": ["eval"]
}
```
### Via CLI
```sh
$ babel --plugins eval script.js
```
### Via Node API
```javascript
require("babel-core").transform("code", {
plugins: ["eval"]
});
```

View File

@@ -0,0 +1,14 @@
{
"name": "babel-plugin-eval",
"version": "1.0.1",
"description": "Compile eval calls with string literals",
"repository": "babel-plugins/babel-plugin-eval",
"license": "MIT",
"main": "lib/index.js",
"devDependencies": {
"babel": "^5.6.0"
},
"keywords": [
"babel-plugin"
]
}

View File

@@ -0,0 +1,23 @@
export default function ({ Plugin, parse, traverse }) {
return new Plugin("eval", {
metadata: {
group: "builtin-pre",
},
visitor: {
CallExpression(node) {
if (this.get("callee").isIdentifier({ name: "eval" }) && node.arguments.length === 1) {
var evaluate = this.get("arguments")[0].evaluate();
if (!evaluate.confident) return;
var code = evaluate.value;
if (typeof code !== "string") return;
var ast = parse(code);
traverse.removeProperties(ast);
return ast.program;
}
}
}
});
}

View File

@@ -0,0 +1,3 @@
node_modules
*.log
src

View File

@@ -0,0 +1,35 @@
# babel-plugin-inline-environment-variables
Inline environment variables
## Installation
```sh
$ npm install babel-plugin-inline-environment-variables
```
## Usage
### Via `.babelrc` (Recommended)
**.babelrc**
```json
{
"plugins": ["inline-environment-variables"]
}
```
### Via CLI
```sh
$ babel --plugins inline-environment-variables script.js
```
### Via Node API
```javascript
require("babel-core").transform("code", {
plugins: ["inline-environment-variables"]
});
```

View File

@@ -0,0 +1,11 @@
{
"name": "babel-plugin-inline-environment-variables",
"version": "1.0.1",
"description": "Inline environment variables",
"repository": "babel-plugins/babel-plugin-inline-environment-variables",
"license": "MIT",
"main": "lib/index.js",
"keywords": [
"babel-plugin"
]
}

View File

@@ -0,0 +1,18 @@
export default function ({ Plugin, types: t }) {
return new Plugin("inline-environment-variables", {
metadata: {
group: "builtin-pre"
},
visitor: {
MemberExpression(node) {
if (this.get("object").matchesPattern("process.env")) {
var key = this.toComputedKey();
if (t.isLiteral(key)) {
return t.valueToNode(process.env[key.value]);
}
}
}
}
});
}

View File

@@ -0,0 +1,3 @@
node_modules
*.log
src

View File

@@ -0,0 +1,35 @@
# babel-plugin-jscript
Babel plugin to fix buggy JScript named function expressions
## Installation
```sh
$ npm install babel-plugin-jscript
```
## Usage
### Via `.babelrc` (Recommended)
**.babelrc**
```json
{
"plugins": ["jscript"]
}
```
### Via CLI
```sh
$ babel --plugins jscript script.js
```
### Via Node API
```javascript
require("babel-core").transform("code", {
plugins: ["jscript"]
});
```

View File

@@ -0,0 +1,11 @@
{
"name": "babel-plugin-jscript",
"version": "1.0.4",
"description": "Babel plugin to fix buggy JScript named function expressions",
"repository": "babel-plugins/babel-plugin-jscript",
"license": "MIT",
"main": "lib/index.js",
"keywords": [
"babel-plugin"
]
}

View File

@@ -0,0 +1,24 @@
export default function ({ Plugin, types: t }) {
return new Plugin("jscript", {
metadata: {
group: "builtin-trailing"
},
visitor: {
FunctionExpression: {
exit(node) {
if (!node.id) return;
node._ignoreUserWhitespace = true;
return t.callExpression(
t.functionExpression(null, [], t.blockStatement([
t.toStatement(node),
t.returnStatement(node.id)
])),
[]
);
}
}
}
});
}

View File

@@ -0,0 +1,3 @@
node_modules
*.log
src

View File

@@ -0,0 +1,55 @@
# babel-plugin-member-expression-literals
Turn valid member expression property literals into plain identifiers
## Example
**In**
```javascript
obj["foo"] = "isValid";
obj.const = "isKeyword";
obj["var"] = "isKeyword";
```
**Out**
```javascript
obj.foo = "isValid";
obj["const"] = "isKeyword";
obj["var"] = "isKeyword";
```
## Installation
```sh
$ npm install babel-plugin-member-expression-literals
```
## Usage
### Via `.babelrc` (Recommended)
**.babelrc**
```json
{
"plugins": ["member-expression-literals"]
}
```
### Via CLI
```sh
$ babel --plugins member-expression-literals script.js
```
### Via Node API
```javascript
require("babel-core").transform("code", {
plugins: ["member-expression-literals"]
});
```

View File

@@ -0,0 +1,11 @@
{
"name": "babel-plugin-member-expression-literals",
"version": "1.0.1",
"description": "Turn valid member expression property literals into plain identifiers",
"repository": "babel-plugins/babel-plugin-member-expression-literals",
"license": "MIT",
"main": "lib/index.js",
"keywords": [
"babel-plugin"
]
}

View File

@@ -0,0 +1,20 @@
export default function ({ Plugin, types: t }) {
return new Plugin("member-expression-literals", {
metadata: {
group: "builtin-trailing"
},
visitor: {
MemberExpression: {
exit(node) {
var prop = node.property;
if (node.computed && t.isLiteral(prop) && t.isValidIdentifier(prop.value)) {
// foo["bar"] => foo.bar
node.property = t.identifier(prop.value);
node.computed = false;
}
}
}
}
});
}

View File

@@ -0,0 +1,3 @@
node_modules
*.log
src

View File

@@ -0,0 +1,57 @@
# babel-plugin-property-literals
Turn valid property key literals to plain identifiers
## Example
**In**
```javascript
var obj = {
"foo": "isValid",
var: "isKeyword",
"const": "isKeyword"
};
```
**Out**
```javascript
var obj = {
foo: "isValid",
"var": "isKeyword",
"const": "isKeyword"
};
```
## Installation
```sh
$ npm install babel-plugin-property-literals
```
## Usage
### Via `.babelrc` (Recommended)
**.babelrc**
```json
{
"plugins": ["property-literals"]
}
```
### Via CLI
```sh
$ babel --plugins property-literals script.js
```
### Via Node API
```javascript
require("babel-core").transform("code", {
plugins: ["property-literals"]
});
```

View File

@@ -0,0 +1,11 @@
{
"name": "babel-plugin-property-literals",
"version": "1.0.1",
"description": "Turn valid property key literals to plain identifiers",
"repository": "babel-plugins/babel-plugin-property-literals",
"license": "MIT",
"main": "lib/index.js",
"keywords": [
"babel-plugin"
]
}

View File

@@ -0,0 +1,20 @@
export default function ({ Plugin, types: t }) {
return new Plugin("property-literals", {
metadata: {
group: "builtin-trailing"
},
visitor: {
Property: {
exit(node) {
var key = node.key;
if (t.isLiteral(key) && t.isValidIdentifier(key.value)) {
// "foo": "bar" -> foo: "bar"
node.key = t.identifier(key.value);
node.computed = false;
}
}
}
}
});
}

View File

@@ -0,0 +1,3 @@
node_modules
*.log
src

View File

@@ -0,0 +1,75 @@
# babel-plugin-proto-to-assign
The `proto-to-assign`plugin will transform all `__proto__` assignments to a method that will do a shallow copy of
all properties.
This means that the following **will** work:
```javascript
var foo = { a: 1 };
var bar = { b: 2 };
bar.__proto__ = foo;
bar.a; // 1
bar.b; // 2
```
however the following **will not**:
```javascript
var foo = { a: 1 };
var bar = { b: 2 };
bar.__proto__ = foo;
bar.a; // 1
foo.a = 2;
bar.a; // 1 - should be 2 but remember that nothing is bound and it's a straight copy
```
This is a case that you have to be aware of if you intend to use this plugin.
## Example
**In**
```javascript
bar.__proto__ = foo;
```
**Out**
```javascript
var _defaults = ...;
_defaults(bar, foo);
```
## Installation
```sh
$ npm install babel-plugin-proto-to-assign
```
## Usage
### Via `.babelrc` (Recommended)
**.babelrc**
```json
{
"plugins": ["proto-to-assign"]
}
```
### Via CLI
```sh
$ babel --plugins proto-to-assign script.js
```
### Via Node API
```javascript
require("babel-core").transform("code", {
plugins: ["proto-to-assign"]
});
```

View File

@@ -0,0 +1,14 @@
{
"name": "babel-plugin-proto-to-assign",
"version": "1.0.4",
"description": "Babel plugin for turning __proto__ into a shallow property clone",
"repository": "babel-plugins/babel-plugin-proto-to-assign",
"license": "MIT",
"main": "lib/index.js",
"keywords": [
"babel-plugin"
],
"dependencies": {
"lodash": "^3.9.3"
}
}

View File

@@ -0,0 +1,66 @@
import pull from "lodash/array/pull";
export default function ({ Plugin, types: t }) {
function isProtoKey(node) {
return t.isLiteral(t.toComputedKey(node, node.key), { value: "__proto__" });
}
function isProtoAssignmentExpression(node) {
var left = node.left;
return t.isMemberExpression(left) && t.isLiteral(t.toComputedKey(left, left.property), { value: "__proto__" });
}
function buildDefaultsCallExpression(expr, ref, file) {
return t.expressionStatement(t.callExpression(file.addHelper("defaults"), [ref, expr.right]));
}
return new Plugin("proto-to-assign", {
metadata: {
secondPass: true
},
visitor: {
AssignmentExpression(node, parent, scope, file) {
if (!isProtoAssignmentExpression(node)) return;
var nodes = [];
var left = node.left.object;
var temp = scope.maybeGenerateMemoised(left);
if (temp) nodes.push(t.expressionStatement(t.assignmentExpression("=", temp, left)));
nodes.push(buildDefaultsCallExpression(node, temp || left, file));
if (temp) nodes.push(temp);
return nodes;
},
ExpressionStatement(node, parent, scope, file) {
var expr = node.expression;
if (!t.isAssignmentExpression(expr, { operator: "=" })) return;
if (isProtoAssignmentExpression(expr)) {
return buildDefaultsCallExpression(expr, expr.left.object, file);
}
},
ObjectExpression(node, parent, scope, file) {
var proto;
for (var i = 0; i < node.properties.length; i++) {
var prop = node.properties[i];
if (isProtoKey(prop)) {
proto = prop.value;
pull(node.properties, prop);
}
}
if (proto) {
var args = [t.objectExpression([]), proto];
if (node.properties.length) args.push(node);
return t.callExpression(file.addHelper("extends"), args);
}
}
}
});
}

View File

@@ -0,0 +1,3 @@
node_modules
*.log
src

View File

@@ -0,0 +1,35 @@
# babel-plugin-react-constant-elements
Treat React JSX elements as value types and hoist them to the highest scope
## Installation
```sh
$ npm install babel-plugin-react-constant-elements
```
## Usage
### Via `.babelrc` (Recommended)
**.babelrc**
```json
{
"plugins": ["react-constant-elements"]
}
```
### Via CLI
```sh
$ babel --plugins react-constant-elements script.js
```
### Via Node API
```javascript
require("babel-core").transform("code", {
plugins: ["react-constant-elements"]
});
```

View File

@@ -0,0 +1,11 @@
{
"name": "babel-plugin-react-constant-elements",
"version": "1.0.3",
"description": "Treat React JSX elements as value types and hoist them to the highest scope",
"repository": "babel-plugins/babel-plugin-react-constant-elements",
"license": "MIT",
"main": "lib/index.js",
"keywords": [
"babel-plugin"
]
}

View File

@@ -0,0 +1,46 @@
export default function ({ Plugin }) {
var immutabilityVisitor = {
enter(node, parent, scope, state) {
var stop = () => {
state.isImmutable = false;
this.stop();
};
if (this.isJSXClosingElement()) {
this.skip();
return;
}
if (this.isJSXIdentifier({ name: "ref" }) && this.parentPath.isJSXAttribute({ name: node })) {
return stop();
}
if (this.isJSXIdentifier() || this.isIdentifier() || this.isJSXMemberExpression()) {
return;
}
if (!this.isImmutable()) stop();
}
};
return new Plugin("react-constant-elements", {
metadata: {
group: "builtin-basic"
},
visitor: {
JSXElement(node) {
if (node._hoisted) return;
var state = { isImmutable: true };
this.traverse(immutabilityVisitor, state);
if (state.isImmutable) {
this.hoist();
} else {
node._hoisted = true;
}
}
}
});
}

View File

@@ -0,0 +1,3 @@
node_modules
*.log
src

View File

@@ -0,0 +1,35 @@
# babel-plugin-react-display-name
Add displayName to React.createClass calls
## Installation
```sh
$ npm install babel-plugin-react-display-name
```
## Usage
### Via `.babelrc` (Recommended)
**.babelrc**
```json
{
"plugins": ["react-display-name"]
}
```
### Via CLI
```sh
$ babel --plugins react-display-name script.js
```
### Via Node API
```javascript
require("babel-core").transform("code", {
plugins: ["react-display-name"]
});
```

View File

@@ -0,0 +1,11 @@
{
"name": "babel-plugin-react-display-name",
"version": "2.0.0",
"description": "Add displayName to React.createClass calls",
"repository": "babel-plugins/babel-plugin-react-display-name",
"license": "MIT",
"main": "lib/index.js",
"keywords": [
"babel-plugin"
]
}

View File

@@ -0,0 +1,84 @@
import path from "path";
export default function ({ Plugin, types: t }) {
function addDisplayName(id, call) {
var props = call.arguments[0].properties;
var safe = true;
for (var i = 0; i < props.length; i++) {
var prop = props[i];
var key = t.toComputedKey(prop);
if (t.isLiteral(key, { value: "displayName" })) {
safe = false;
break;
}
}
if (safe) {
props.unshift(t.property("init", t.identifier("displayName"), t.literal(id)));
}
}
var isCreateClassCallExpression = t.buildMatchMemberExpression("React.createClass");
function isCreateClass(node) {
if (!node || !t.isCallExpression(node)) return false;
// not React.createClass call member object
if (!isCreateClassCallExpression(node.callee)) return false;
// no call arguments
var args = node.arguments;
if (args.length !== 1) return false;
// first node arg is not an object
var first = args[0];
if (!t.isObjectExpression(first)) return false;
return true;
}
return new Plugin("react-display-name", {
metadata: {
group: "builtin-pre"
},
visitor: {
ExportDefaultDeclaration(node, parent, scope, file) {
if (isCreateClass(node.declaration)) {
var displayName = file.opts.basename;
// ./{module name}/index.js
if (displayName === "index") {
displayName = path.basename(path.dirname(file.opts.filename));
}
addDisplayName(displayName, node.declaration);
}
},
"AssignmentExpression|Property|VariableDeclarator"(node) {
var left, right;
if (t.isAssignmentExpression(node)) {
left = node.left;
right = node.right;
} else if (t.isProperty(node)) {
left = node.key;
right = node.value;
} else if (t.isVariableDeclarator(node)) {
left = node.id;
right = node.init;
}
if (t.isMemberExpression(left)) {
left = left.property;
}
if (t.isIdentifier(left) && isCreateClass(right)) {
addDisplayName(left.name, right);
}
}
}
});
}

View File

@@ -0,0 +1,3 @@
node_modules
*.log
src

View File

@@ -0,0 +1,35 @@
# babel-plugin-remove-console
Remove console.* calls
## Installation
```sh
$ npm install babel-plugin-remove-console
```
## Usage
### Via `.babelrc` (Recommended)
**.babelrc**
```json
{
"plugins": ["remove-console"]
}
```
### Via CLI
```sh
$ babel --plugins remove-console script.js
```
### Via Node API
```javascript
require("babel-core").transform("code", {
plugins: ["remove-console"]
});
```

View File

@@ -0,0 +1,11 @@
{
"name": "babel-plugin-remove-console",
"version": "1.0.1",
"description": "Remove console.* calls",
"repository": "babel-plugins/babel-plugin-remove-console",
"license": "MIT",
"main": "lib/index.js",
"keywords": [
"babel-plugin"
]
}

View File

@@ -0,0 +1,15 @@
export default function ({ Plugin, types: t }) {
return new Plugin("remove-console", {
metadata: {
group: "builtin-pre"
},
visitor: {
CallExpression() {
if (this.get("callee").matchesPattern("console", true)) {
this.dangerouslyRemove();
}
}
}
});
}

View File

@@ -0,0 +1,3 @@
node_modules
*.log
src

View File

@@ -0,0 +1,35 @@
# babel-plugin-remove-debugger
Remove debugger statements
## Installation
```sh
$ npm install babel-plugin-remove-debugger
```
## Usage
### Via `.babelrc` (Recommended)
**.babelrc**
```json
{
"plugins": ["remove-debugger"]
}
```
### Via CLI
```sh
$ babel --plugins remove-debugger script.js
```
### Via Node API
```javascript
require("babel-core").transform("code", {
plugins: ["remove-debugger"]
});
```

View File

@@ -0,0 +1,11 @@
{
"name": "babel-plugin-remove-debugger",
"version": "1.0.1",
"description": "Remove debugger statements",
"repository": "babel-plugins/babel-plugin-remove-debugger",
"license": "MIT",
"main": "lib/index.js",
"keywords": [
"babel-plugin"
]
}

View File

@@ -0,0 +1,13 @@
export default function ({ Plugin, types: t }) {
return new Plugin("remove-debugger", {
metadata: {
group: "builtin-pre"
},
visitor: {
DebuggerStatement() {
this.dangerouslyRemove();
}
}
});
}

View File

@@ -0,0 +1,3 @@
node_modules
*.log
src

View File

@@ -0,0 +1,35 @@
# babel-plugin-runtime
Externalise references to helpers and builtins, automatically polyfilling your code without polluting globals
## Installation
```sh
$ npm install babel-plugin-runtime
```
## Usage
### Via `.babelrc` (Recommended)
**.babelrc**
```json
{
"plugins": ["runtime"]
}
```
### Via CLI
```sh
$ babel --plugins runtime script.js
```
### Via Node API
```javascript
require("babel-core").transform("code", {
plugins: ["runtime"]
});
```

View File

@@ -0,0 +1,11 @@
{
"name": "babel-plugin-runtime",
"version": "1.0.7",
"description": "Externalise references to helpers and builtins, automatically polyfilling your code without polluting globals",
"repository": "babel-plugins/babel-plugin-runtime",
"license": "MIT",
"main": "lib/index.js",
"keywords": [
"babel-plugin"
]
}

View File

@@ -0,0 +1,168 @@
{
"builtins": {
"Symbol": "symbol",
"Promise": "promise",
"Map": "map",
"WeakMap": "weak-map",
"Set": "set",
"WeakSet": "weak-set"
},
"methods": {
"Array": {
"concat": "array/concat",
"copyWithin": "array/copy-within",
"entries": "array/entries",
"every": "array/every",
"fill": "array/fill",
"filter": "array/filter",
"findIndex": "array/find-index",
"find": "array/find",
"forEach": "array/for-each",
"from": "array/from",
"includes": "array/includes",
"indexOf": "array/index-of",
"join": "array/join",
"keys": "array/keys",
"lastIndexOf": "array/last-index-of",
"map": "array/map",
"of": "array/of",
"pop": "array/pop",
"push": "array/push",
"reduceRight": "array/reduce-right",
"reduce": "array/reduce",
"reverse": "array/reverse",
"shift": "array/shift",
"slice": "array/slice",
"some": "array/some",
"sort": "array/sort",
"splice": "array/splice",
"turn": "array/turn",
"unshift": "array/unshift",
"values": "array/values"
},
"Object": {
"assign": "object/assign",
"classof": "object/classof",
"create": "object/create",
"define": "object/define",
"defineProperties": "object/define-properties",
"defineProperty": "object/define-property",
"entries": "object/entries",
"freeze": "object/freeze",
"getOwnPropertyDescriptor": "object/get-own-property-descriptor",
"getOwnPropertyDescriptors": "object/get-own-property-descriptors",
"getOwnPropertyNames": "object/get-own-property-names",
"getOwnPropertySymbols": "object/get-own-property-symbols",
"getPrototypePf": "object/get-prototype-of",
"index": "object/index",
"isExtensible": "object/is-extensible",
"isFrozen": "object/is-frozen",
"isObject": "object/is-object",
"isSealed": "object/is-sealed",
"is": "object/is",
"keys": "object/keys",
"make": "object/make",
"preventExtensions": "object/prevent-extensions",
"seal": "object/seal",
"setPrototypeOf": "object/set-prototype-of",
"values": "object/values"
},
"RegExp": {
"escape": "regexp/escape"
},
"Function": {
"only": "function/only",
"part": "function/part"
},
"Math": {
"acosh": "math/acosh",
"asinh": "math/asinh",
"atanh": "math/atanh",
"cbrt": "math/cbrt",
"clz32": "math/clz32",
"cosh": "math/cosh",
"expm1": "math/expm1",
"fround": "math/fround",
"hypot": "math/hypot",
"pot": "math/pot",
"imul": "math/imul",
"log10": "math/log10",
"log1p": "math/log1p",
"log2": "math/log2",
"sign": "math/sign",
"sinh": "math/sinh",
"tanh": "math/tanh",
"trunc": "math/trunc"
},
"Date": {
"addLocale": "date/add-locale",
"formatUTC": "date/format-utc",
"format": "date/format"
},
"Symbol": {
"for": "symbol/for",
"hasInstance": "symbol/has-instance",
"is-concat-spreadable": "symbol/is-concat-spreadable",
"iterator": "symbol/iterator",
"keyFor": "symbol/key-for",
"match": "symbol/match",
"replace": "symbol/replace",
"search": "symbol/search",
"species": "symbol/species",
"split": "symbol/split",
"toPrimitive": "symbol/to-primitive",
"toStringTag": "symbol/to-string-tag",
"unscopables": "symbol/unscopables"
},
"String": {
"at": "string/at",
"codePointAt": "string/code-point-at",
"endsWith": "string/ends-with",
"escapeHTML": "string/escape-html",
"fromCodePoint": "string/from-code-point",
"includes": "string/includes",
"raw": "string/raw",
"repeat": "string/repeat",
"startsWith": "string/starts-with",
"unescapeHTML": "string/unescape-html"
},
"Number": {
"EPSILON": "number/epsilon",
"isFinite": "number/is-finite",
"isInteger": "number/is-integer",
"isNaN": "number/is-nan",
"isSafeInteger": "number/is-safe-integer",
"MAX_SAFE_INTEGER": "number/max-safe-integer",
"MIN_SAFE_INTEGER": "number/min-safe-integer",
"parseFloat": "number/parse-float",
"parseInt": "number/parse-int",
"random": "number/random"
},
"Reflect": {
"apply": "reflect/apply",
"construct": "reflect/construct",
"defineProperty": "reflect/define-property",
"deleteProperty": "reflect/delete-property",
"enumerate": "reflect/enumerate",
"getOwnPropertyDescriptor": "reflect/get-own-property-descriptor",
"getPrototypeOf": "reflect/get-prototype-of",
"get": "reflect/get",
"has": "reflect/has",
"isExtensible": "reflect/is-extensible",
"ownKeys": "reflect/own-keys",
"preventExtensions": "reflect/prevent-extensions",
"setPrototypeOf": "reflect/set-prototype-of",
"set": "reflect/set"
}
}
}

View File

@@ -0,0 +1,114 @@
import definitions from "./definitions";
export default function ({ Plugin, types: t }) {
const RUNTIME_MODULE_NAME = "babel-runtime";
function has(obj, key) {
return Object.prototype.hasOwnProperty.call(obj, key);
}
return new Plugin("runtime", {
metadata: {
group: "builtin-post-modules"
},
pre(file) {
file.set("helperGenerator", function (name) {
return file.addImport(`${RUNTIME_MODULE_NAME}/helpers/${name}`, name, "absoluteDefault");
});
file.setDynamic("regeneratorIdentifier", function () {
return file.addImport(`${RUNTIME_MODULE_NAME}/regenerator`, "regeneratorRuntime", "absoluteDefault");
});
},
visitor: {
ReferencedIdentifier(node, parent, scope, file) {
if (node.name === "regeneratorRuntime") {
return file.get("regeneratorIdentifier");
}
if (t.isMemberExpression(parent)) return;
if (!has(definitions.builtins, node.name)) return;
if (scope.getBindingIdentifier(node.name)) return;
// Symbol() -> _core.Symbol(); new Promise -> new _core.Promise
var modulePath = definitions.builtins[node.name];
return file.addImport(`${RUNTIME_MODULE_NAME}/core-js/${modulePath}`, node.name, "absoluteDefault");
},
CallExpression(node, parent, scope, file) {
// arr[Symbol.iterator]() -> _core.$for.getIterator(arr)
if (node.arguments.length) return;
var callee = node.callee;
if (!t.isMemberExpression(callee)) return;
if (!callee.computed) return;
if (!this.get("callee.property").matchesPattern("Symbol.iterator")) return;
return t.callExpression(file.addImport(`${RUNTIME_MODULE_NAME}/core-js/get-iterator`, "getIterator", "absoluteDefault"), [callee.object]);
},
BinaryExpression(node, parent, scope, file) {
// Symbol.iterator in arr -> core.$for.isIterable(arr)
if (node.operator !== "in") return;
if (!this.get("left").matchesPattern("Symbol.iterator")) return;
return t.callExpression(
file.addImport(`${RUNTIME_MODULE_NAME}/core-js/is-iterable`, "isIterable", "absoluteDefault"),
[node.right]
);
},
MemberExpression: {
enter(node, parent, scope, file) {
// Array.from -> _core.Array.from
if (!this.isReferenced()) return;
var obj = node.object;
var prop = node.property;
if (!t.isReferenced(obj, node)) return;
if (node.computed) return;
if (!has(definitions.methods, obj.name)) return;
var methods = definitions.methods[obj.name];
if (!has(methods, prop.name)) return;
// doesn't reference the global
if (scope.getBindingIdentifier(obj.name)) return;
// special case Object.defineProperty to not use core-js when using string keys
if (obj.name === "Object" && prop.name === "defineProperty" && this.parentPath.isCallExpression()) {
var call = this.parentPath.node;
if (call.arguments.length === 3 && t.isLiteral(call.arguments[1])) return;
}
var modulePath = methods[prop.name];
return file.addImport(`${RUNTIME_MODULE_NAME}/core-js/${modulePath}`, `${obj.name}$${prop.name}`, "absoluteDefault");
},
exit(node, parent, scope, file) {
if (!this.isReferenced()) return;
var prop = node.property;
var obj = node.object;
if (!has(definitions.builtins, obj.name)) return;
if (scope.getBindingIdentifier(obj.name)) return;
var modulePath = definitions.builtins[obj.name];
return t.memberExpression(
file.addImport(`${RUNTIME_MODULE_NAME}/core-js/${modulePath}`, `${obj.name}`, "absoluteDefault"),
prop
);
}
}
}
});
}

View File

@@ -0,0 +1,3 @@
node_modules
*.log
src

View File

@@ -0,0 +1,35 @@
# babel-plugin-undeclared-variables-check
Throw a compile-time error on references to undeclared variables
## Installation
```sh
$ npm install babel-plugin-undeclared-variables-check
```
## Usage
### Via `.babelrc` (Recommended)
**.babelrc**
```json
{
"plugins": ["undeclared-variables-check"]
}
```
### Via CLI
```sh
$ babel --plugins undeclared-variables-check script.js
```
### Via Node API
```javascript
require("babel-core").transform("code", {
plugins: ["undeclared-variables-check"]
});
```

View File

@@ -0,0 +1,14 @@
{
"name": "babel-plugin-undeclared-variables-check",
"version": "1.0.2",
"description": "Throw a compile-time error on references to undeclared variables",
"repository": "babel-plugins/babel-plugin-undeclared-variables-check",
"license": "MIT",
"main": "lib/index.js",
"keywords": [
"babel-plugin"
],
"dependencies": {
"leven": "^1.0.2"
}
}

View File

@@ -0,0 +1,48 @@
import levenshtein from "leven";
export default function ({ Plugin, types: t, messages }) {
return new Plugin("undeclared-variables-check", {
metadata: {
group: "builtin-pre"
},
visitor: {
ReferencedIdentifier(node, parent, scope) {
var binding = scope.getBinding(node.name);
if (binding && binding.kind === "type" && !this.parentPath.isFlow()) {
throw this.errorWithNode(messages.get("undeclaredVariableType", node.name), ReferenceError);
}
if (scope.hasBinding(node.name)) return;
// get the closest declaration to offer as a suggestion
// the variable name may have just been mistyped
var bindings = scope.getAllBindings();
var closest;
var shortest = -1;
for (var name in bindings) {
var distance = levenshtein(node.name, name);
if (distance <= 0 || distance > 3) continue;
if (distance <= shortest) continue;
closest = name;
shortest = distance;
}
var msg;
if (closest) {
msg = messages.get("undeclaredVariableSuggestion", node.name, closest);
} else {
msg = messages.get("undeclaredVariable", node.name);
}
//
throw this.errorWithNode(msg, ReferenceError);
}
}
});
}

View File

@@ -0,0 +1,3 @@
node_modules
*.log
src

View File

@@ -0,0 +1,53 @@
# babel-plugin-undefined-to-void
Some JavaScript implementations allow `undefined` to be overwritten, this
may lead to peculiar bugs that are extremely hard to track down.
This plugin transforms `undefined` into `void 0` which returns `undefined`
regardless of if it's been reassigned.
## Example
**In**
```javascript
foo === undefined;
```
**Out**
```javascript
foo === void 0;
```
## Installation
```sh
$ npm install babel-plugin-undefined-to-void
```
## Usage
### Via `.babelrc` (Recommended)
**.babelrc**
```json
{
"plugins": ["undefined-to-void"]
}
```
### Via CLI
```sh
$ babel --plugins undefined-to-void script.js
```
### Via Node API
```javascript
require("babel-core").transform("code", {
plugins: ["undefined-to-void"]
});
```

View File

@@ -0,0 +1,11 @@
{
"name": "babel-plugin-undefined-to-void",
"version": "1.1.6",
"description": "Replace references to `undefined` with `void 0`",
"repository": "babel-plugins/babel-plugin-undefined-to-void",
"license": "MIT",
"main": "lib/index.js",
"keywords": [
"babel-plugin"
]
}

View File

@@ -0,0 +1,15 @@
export default function ({ Plugin, types: t }) {
return new Plugin("undefined-to-void", {
metadata: {
group: "builtin-basic"
},
visitor: {
ReferencedIdentifier(node, parent) {
if (node.name === "undefined") {
return t.unaryExpression("void", t.literal(0), true);
}
}
}
});
}