start on babel module bundling and type inferrence
This commit is contained in:
parent
5080534974
commit
aaf4cbf06f
@ -28,6 +28,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"ast-types": "~0.7.0",
|
||||
"bluebird": "^2.9.25",
|
||||
"chalk": "^1.0.0",
|
||||
"convert-source-map": "^1.1.0",
|
||||
"core-js": "^0.9.0",
|
||||
@ -49,6 +50,7 @@
|
||||
"regenerator": "^0.8.20",
|
||||
"regexpu": "^1.1.2",
|
||||
"repeating": "^1.1.2",
|
||||
"resolve": "^1.1.6",
|
||||
"shebang-regex": "^1.0.0",
|
||||
"slash": "^1.0.0",
|
||||
"source-map": "^0.4.0",
|
||||
|
||||
@ -9,6 +9,7 @@ export { canCompile } from "../util";
|
||||
|
||||
export { default as options } from "../transformation/file/options";
|
||||
export { default as Transformer } from "../transformation/transformer";
|
||||
export { default as Pipeline } from "../transformation/transformer-pipeline";
|
||||
export { default as traverse } from "../traversal";
|
||||
export { default as buildExternalHelpers } from "../tools/build-external-helpers";
|
||||
export { version } from "../../../package";
|
||||
|
||||
15
src/babel/transformation/bundler/index.js
Normal file
15
src/babel/transformation/bundler/index.js
Normal file
@ -0,0 +1,15 @@
|
||||
export default class Bundler {
|
||||
constructor(opts) {
|
||||
this.resolvers = [];
|
||||
this.cache = {};
|
||||
this.opts = opts;
|
||||
}
|
||||
|
||||
addResolver(resolver) {
|
||||
this.resolvers.push(resolver);
|
||||
}
|
||||
|
||||
transform() {
|
||||
|
||||
}
|
||||
}
|
||||
25
src/babel/transformation/bundler/resolvers/node.js
Normal file
25
src/babel/transformation/bundler/resolvers/node.js
Normal file
@ -0,0 +1,25 @@
|
||||
import { Promise } from "bluebird";
|
||||
import resolve from "resolve";
|
||||
import path from "path";
|
||||
import fs from "fs";
|
||||
|
||||
export default function (request, parent) {
|
||||
return new Promise(function (resolve, reject) {
|
||||
resolve(request, { basedir: path.dirname(parent) }, function (err, res) {
|
||||
if (err) {
|
||||
resolve(null);
|
||||
} else {
|
||||
fs.readFile(res, "utf8", function (err) {
|
||||
if (err) {
|
||||
reject(err);
|
||||
} else {
|
||||
resolve({
|
||||
filename: filename,
|
||||
content: content
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
@ -1,5 +1,6 @@
|
||||
import convertSourceMap from "convert-source-map";
|
||||
import * as optionParsers from "./option-parsers";
|
||||
import moduleFormatters from "../modules";
|
||||
import PluginManager from "./plugin-manager";
|
||||
import shebangRegex from "shebang-regex";
|
||||
import TraversalPath from "../../traversal/path";
|
||||
@ -38,7 +39,7 @@ function checkPath(stack, path) {
|
||||
}
|
||||
|
||||
export default class File {
|
||||
constructor(opts = {}) {
|
||||
constructor(opts = {}, pipeline) {
|
||||
this.dynamicImportTypes = {};
|
||||
this.dynamicImportIds = {};
|
||||
this.dynamicImports = [];
|
||||
@ -49,9 +50,10 @@ export default class File {
|
||||
this.data = {};
|
||||
this.uids = {};
|
||||
|
||||
this.log = new Logger(this, opts.filename || "unknown");
|
||||
this.opts = this.normalizeOptions(opts);
|
||||
this.ast = {};
|
||||
this.pipeline = pipeline;
|
||||
this.log = new Logger(this, opts.filename || "unknown");
|
||||
this.opts = this.normalizeOptions(opts);
|
||||
this.ast = {};
|
||||
|
||||
this.buildTransformers();
|
||||
}
|
||||
@ -133,7 +135,7 @@ export default class File {
|
||||
}
|
||||
|
||||
var optionParser = optionParsers[option.type];
|
||||
if (optionParser) val = optionParser(key, val);
|
||||
if (optionParser) val = optionParser(key, val, this.pipeline);
|
||||
|
||||
if (option.alias) {
|
||||
opts[option.alias] = opts[option.alias] || val;
|
||||
@ -200,7 +202,7 @@ export default class File {
|
||||
var stack = [];
|
||||
|
||||
// build internal transformers
|
||||
each(transform.transformers, function (transformer, key) {
|
||||
each(this.pipeline.transformers, function (transformer, key) {
|
||||
var pass = transformers[key] = transformer.buildPass(file);
|
||||
|
||||
if (pass.canTransform()) {
|
||||
@ -235,7 +237,7 @@ export default class File {
|
||||
}
|
||||
|
||||
getModuleFormatter(type: string) {
|
||||
var ModuleFormatter = isFunction(type) ? type : transform.moduleFormatters[type];
|
||||
var ModuleFormatter = isFunction(type) ? type : moduleFormatters[type];
|
||||
|
||||
if (!ModuleFormatter) {
|
||||
var loc = util.resolveRelative(type);
|
||||
|
||||
@ -1,14 +1,13 @@
|
||||
import transform from "./../index";
|
||||
import * as util from "../../util";
|
||||
|
||||
export function transformerList(key, val) {
|
||||
export function transformerList(key, val, pipeline) {
|
||||
val = util.arrayify(val);
|
||||
|
||||
if (val.indexOf("all") >= 0 || val.indexOf(true) >= 0) {
|
||||
val = Object.keys(transform.transformers);
|
||||
val = Object.keys(pipeline.transformers);
|
||||
}
|
||||
|
||||
return transform._ensureTransformerNames(key, val);
|
||||
return pipeline._ensureTransformerNames(key, val);
|
||||
}
|
||||
|
||||
export function number(key, val) {
|
||||
|
||||
@ -1,68 +1,34 @@
|
||||
import normalizeAst from "../helpers/normalize-ast";
|
||||
import Transformer from "./transformer";
|
||||
import object from "../helpers/object";
|
||||
import File from "./file";
|
||||
import each from "lodash/collection/each";
|
||||
import Pipeline from "./transformer-pipeline";
|
||||
|
||||
export default function transform(code: string, opts?: Object) {
|
||||
var file = new File(opts);
|
||||
return file.parse(code);
|
||||
}
|
||||
var pipeline = new Pipeline;
|
||||
|
||||
transform.fromAst = function (ast, code, opts) {
|
||||
ast = normalizeAst(ast);
|
||||
//
|
||||
|
||||
var file = new File(opts);
|
||||
file.addCode(code);
|
||||
file.transform(ast);
|
||||
return file.generate();
|
||||
};
|
||||
import transformers from "./transformers";
|
||||
pipeline.addTransformers(transformers);
|
||||
|
||||
transform._ensureTransformerNames = function (type: string, rawKeys: Array<string>) {
|
||||
var keys = [];
|
||||
//
|
||||
|
||||
for (var i = 0; i < rawKeys.length; i++) {
|
||||
var key = rawKeys[i];
|
||||
import deprecated from "./transformers/deprecated";
|
||||
pipeline.addDeprecated(deprecated);
|
||||
|
||||
var deprecatedKey = transform.deprecatedTransformerMap[key];
|
||||
var aliasKey = transform.aliasTransformerMap[key];
|
||||
if (aliasKey) {
|
||||
keys.push(aliasKey);
|
||||
} else if (deprecatedKey) {
|
||||
// deprecated key, remap it to the new one
|
||||
console.error(`The transformer ${key} has been renamed to ${deprecatedKey}`);
|
||||
rawKeys.push(deprecatedKey);
|
||||
} else if (transform.transformers[key]) {
|
||||
// valid key
|
||||
keys.push(key);
|
||||
} else if (transform.namespaces[key]) {
|
||||
// namespace, append all transformers within this namespace
|
||||
keys = keys.concat(transform.namespaces[key]);
|
||||
} else {
|
||||
// invalid key
|
||||
throw new ReferenceError(`Unknown transformer ${key} specified in ${type}`);
|
||||
}
|
||||
}
|
||||
//
|
||||
|
||||
return keys;
|
||||
};
|
||||
import aliases from "./transformers/aliases";
|
||||
pipeline.addDeprecated(aliases);
|
||||
|
||||
transform.transformerNamespaces = object();
|
||||
transform.transformers = object();
|
||||
transform.namespaces = object();
|
||||
//
|
||||
|
||||
transform.deprecatedTransformerMap = require("./transformers/deprecated");
|
||||
transform.aliasTransformerMap = require("./transformers/aliases");
|
||||
transform.moduleFormatters = require("./modules");
|
||||
import * as filters from "./transformers/filters";
|
||||
pipeline.addFilter(filters.internal);
|
||||
pipeline.addFilter(filters.blacklist);
|
||||
pipeline.addFilter(filters.whitelist);
|
||||
pipeline.addFilter(filters.stage);
|
||||
pipeline.addFilter(filters.optional);
|
||||
|
||||
import rawTransformers from "./transformers";
|
||||
//
|
||||
|
||||
each(rawTransformers, function (transformer, key) {
|
||||
var namespace = key.split(".")[0];
|
||||
|
||||
transform.namespaces[namespace] = transform.namespaces[namespace] || [];
|
||||
transform.namespaces[namespace].push(key);
|
||||
transform.transformerNamespaces[key] = namespace;
|
||||
|
||||
transform.transformers[key] = new Transformer(key, transformer);
|
||||
});
|
||||
var transform = pipeline.transform.bind(pipeline);
|
||||
transform.fromAst = pipeline.transformFromAst.bind(pipeline);
|
||||
transform.pipeline = pipeline;
|
||||
export default transform;
|
||||
|
||||
@ -17,30 +17,7 @@ export default class TransformerPass {
|
||||
}
|
||||
|
||||
canTransform(): boolean {
|
||||
var transformer = this.transformer;
|
||||
|
||||
var opts = this.file.opts;
|
||||
var key = transformer.key;
|
||||
|
||||
// internal
|
||||
if (key[0] === "_") return true;
|
||||
|
||||
// blacklist
|
||||
var blacklist = opts.blacklist;
|
||||
if (blacklist.length && includes(blacklist, key)) return false;
|
||||
|
||||
// whitelist
|
||||
var whitelist = opts.whitelist;
|
||||
if (whitelist) return includes(whitelist, key);
|
||||
|
||||
// stage
|
||||
var stage = transformer.metadata.stage;
|
||||
if (stage != null && stage >= opts.stage) return true;
|
||||
|
||||
// optional
|
||||
if (transformer.metadata.optional && !includes(opts.optional, key)) return false;
|
||||
|
||||
return true;
|
||||
return this.file.pipeline.canTransform(this.transformer, this.file.opts);
|
||||
}
|
||||
|
||||
checkPath(path: TraversalPath): boolean {
|
||||
|
||||
105
src/babel/transformation/transformer-pipeline.js
Normal file
105
src/babel/transformation/transformer-pipeline.js
Normal file
@ -0,0 +1,105 @@
|
||||
import Transformer from "./transformer";
|
||||
import normalizeAst from "../helpers/normalize-ast";
|
||||
import Bundler from "./bundler";
|
||||
import assign from "lodash/object/assign";
|
||||
import object from "../helpers/object";
|
||||
import File from "./file";
|
||||
|
||||
export default class TransformerPipeline {
|
||||
constructor() {
|
||||
this.transformers = object();
|
||||
this.namespaces = object();
|
||||
this.deprecated = object();
|
||||
this.aliases = object();
|
||||
this.filters = [];
|
||||
}
|
||||
|
||||
addTransformers(transformers) {
|
||||
for (var key in transformers) {
|
||||
this.addTransformer(key, transformers[key]);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
addTransformer(key, transformer) {
|
||||
if (this.transformers[key]) throw new Error(); // todo: error
|
||||
|
||||
var namespace = key.split(".")[0];
|
||||
this.namespaces[namespace] = this.namespaces[namespace] || [];
|
||||
this.namespaces[namespace].push(key);
|
||||
this.namespaces[key] = namespace;
|
||||
|
||||
this.transformers[key] = new Transformer(key, transformer);
|
||||
}
|
||||
|
||||
addAliases(names) {
|
||||
assign(this.aliases, names);
|
||||
return this;
|
||||
}
|
||||
|
||||
addDeprecated(names) {
|
||||
assign(this.deprecated, names);
|
||||
return this;
|
||||
}
|
||||
|
||||
addFilter(filter: Function) {
|
||||
this.filters.push(filter);
|
||||
return this;
|
||||
}
|
||||
|
||||
canTransform(transformer, fileOpts) {
|
||||
for (var filter of (this.filters: Array)) {
|
||||
var result = filter(transformer, fileOpts);
|
||||
if (result != null) return result;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
transform(code: string, opts?: Object) {
|
||||
var file = new File(opts, this);
|
||||
return file.parse(code);
|
||||
}
|
||||
|
||||
transformFromAst(ast, code, opts) {
|
||||
ast = normalizeAst(ast);
|
||||
|
||||
var file = new File(opts, this);
|
||||
file.addCode(code);
|
||||
file.transform(ast);
|
||||
return file.generate();
|
||||
}
|
||||
|
||||
createBundler() {
|
||||
return new Bundler(this);
|
||||
}
|
||||
|
||||
_ensureTransformerNames(type: string, rawKeys: Array<string>) {
|
||||
var keys = [];
|
||||
|
||||
for (var i = 0; i < rawKeys.length; i++) {
|
||||
var key = rawKeys[i];
|
||||
|
||||
var deprecatedKey = this.deprecated[key];
|
||||
var aliasKey = this.aliases[key];
|
||||
if (aliasKey) {
|
||||
keys.push(aliasKey);
|
||||
} else if (deprecatedKey) {
|
||||
// deprecated key, remap it to the new one
|
||||
console.error(`The transformer ${key} has been renamed to ${deprecatedKey}`);
|
||||
rawKeys.push(deprecatedKey);
|
||||
} else if (this.transformers[key]) {
|
||||
// valid key
|
||||
keys.push(key);
|
||||
} else if (this.namespaces[key]) {
|
||||
// namespace, append all transformers within this namespace
|
||||
keys = keys.concat(this.namespaces[key]);
|
||||
} else {
|
||||
// invalid key
|
||||
throw new ReferenceError(`Unknown transformer ${key} specified in ${type}`);
|
||||
}
|
||||
}
|
||||
|
||||
return keys;
|
||||
}
|
||||
}
|
||||
@ -15,7 +15,7 @@ import each from "lodash/collection/each";
|
||||
*/
|
||||
|
||||
export default class Transformer {
|
||||
constructor(transformerKey: string, transformer: Object, opts: Object) {
|
||||
constructor(transformerKey: string, transformer: Object) {
|
||||
transformer = assign({}, transformer);
|
||||
|
||||
var take = function (key) {
|
||||
@ -40,7 +40,6 @@ export default class Transformer {
|
||||
//
|
||||
|
||||
this.handlers = this.normalize(transformer);
|
||||
this.opts = this.opts || {};
|
||||
this.key = transformerKey;
|
||||
|
||||
//
|
||||
|
||||
24
src/babel/transformation/transformers/filters.js
Normal file
24
src/babel/transformation/transformers/filters.js
Normal file
@ -0,0 +1,24 @@
|
||||
import includes from "lodash/collection/includes";
|
||||
|
||||
export function internal(transformer, opts) {
|
||||
if (transformer.key[0] === "_") return true;
|
||||
}
|
||||
|
||||
export function blacklist(transformer, opts) {
|
||||
var blacklist = opts.blacklist;
|
||||
if (blacklist.length && includes(blacklist, transformer.key)) return false;
|
||||
}
|
||||
|
||||
export function whitelist(transformer, opts) {
|
||||
var whitelist = opts.whitelist;
|
||||
if (whitelist) return includes(whitelist, transformer.key);
|
||||
}
|
||||
|
||||
export function stage(transformer, opts) {
|
||||
var stage = transformer.metadata.stage;
|
||||
if (stage != null && stage >= opts.stage) return true;
|
||||
}
|
||||
|
||||
export function optional(transformer, opts) {
|
||||
if (transformer.metadata.optional && !includes(opts.optional, transformer.key)) return false;
|
||||
}
|
||||
@ -19,7 +19,7 @@ suite("api", function () {
|
||||
});
|
||||
|
||||
test("addHelper unknown", function () {
|
||||
var file = new File;
|
||||
var file = new File({}, transform.pipeline);
|
||||
assert.throws(function () {
|
||||
file.addHelper("foob");
|
||||
}, /Unknown helper foob/);
|
||||
@ -40,11 +40,11 @@ suite("api", function () {
|
||||
});
|
||||
|
||||
test("extra options", function () {
|
||||
var file1 = new File({ extra: { foo: "bar" } });
|
||||
var file1 = new File({ extra: { foo: "bar" } }, transform.pipeline);
|
||||
assert.equal(file1.opts.extra.foo, "bar");
|
||||
|
||||
var file2 = new File;
|
||||
var file3 = new File;
|
||||
var file2 = new File({}, transform.pipeline);
|
||||
var file3 = new File({}, transform.pipeline);
|
||||
assert.ok(file2.opts.extra !== file3.opts.extra);
|
||||
});
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user