Fix helpers dependencies loading

This commit is contained in:
Nicolò Ribaudo 2017-10-04 23:39:04 +02:00
parent e0a6e1e864
commit d2af56bcae
3 changed files with 61 additions and 25 deletions

View File

@ -1,6 +1,6 @@
// @flow // @flow
import getHelper from "@babel/helpers"; import * as helpers from "@babel/helpers";
import { NodePath, Hub, Scope } from "@babel/traverse"; import { NodePath, Hub, Scope } from "@babel/traverse";
import { codeFrameColumns } from "@babel/code-frame"; import { codeFrameColumns } from "@babel/code-frame";
import traverse from "@babel/traverse"; import traverse from "@babel/traverse";
@ -132,11 +132,16 @@ export default class File {
name, name,
)); ));
const { nodes, globals } = getHelper( const dependencies = {};
for (const dep of helpers.getDependencies(name)) {
dependencies[dep] = this.addHelper(dep);
}
const { nodes, globals } = helpers.get(
name, name,
name => this.addHelper(name), dep => dependencies[dep],
uid, uid,
() => Object.keys(this.scope.getAllBindings()), Object.keys(this.scope.getAllBindings()),
); );
globals.forEach(name => { globals.forEach(name => {

View File

@ -134,8 +134,8 @@ function getHelperMetadata(file) {
/** /**
* Given a helper AST and information about how it will be used, update the AST to match the usage. * Given a helper AST and information about how it will be used, update the AST to match the usage.
*/ */
function permuteHelperAST(file, metadata, id, getLocalBindings, getDependency) { function permuteHelperAST(file, metadata, id, localBindings, getDependency) {
if (getLocalBindings && !id) { if (localBindings && !id) {
throw new Error("Unexpected local bindings for module-based helpers."); throw new Error("Unexpected local bindings for module-based helpers.");
} }
@ -154,11 +154,11 @@ function permuteHelperAST(file, metadata, id, getLocalBindings, getDependency) {
const dependenciesRefs = {}; const dependenciesRefs = {};
dependencies.forEach((name, id) => { dependencies.forEach((name, id) => {
dependenciesRefs[id.name] = dependenciesRefs[id.name] =
typeof getDependency === "function" ? getDependency(name) : id; (typeof getDependency === "function" && getDependency(name)) || id;
}); });
const toRename = {}; const toRename = {};
const bindings = new Set((getLocalBindings && getLocalBindings()) || []); const bindings = new Set(localBindings || []);
localBindingNames.forEach(name => { localBindingNames.forEach(name => {
let newName = name; let newName = name;
while (bindings.has(newName)) newName = "_" + newName; while (bindings.has(newName)) newName = "_" + newName;
@ -237,17 +237,17 @@ function loadHelper(name) {
const metadata = getHelperMetadata(fn()); const metadata = getHelperMetadata(fn());
// Preload dependencies helperData[name] = {
metadata.dependencies.forEach(loadHelper); build(getDependency, id, localBindings) {
helperData[name] = function(getDependency, id, getLocalBindings) {
const file = fn(); const file = fn();
permuteHelperAST(file, metadata, id, getLocalBindings, getDependency); permuteHelperAST(file, metadata, id, localBindings, getDependency);
return { return {
nodes: file.program.body, nodes: file.program.body,
globals: metadata.globals, globals: metadata.globals,
}; };
},
dependencies: metadata.dependencies,
}; };
} }
@ -256,12 +256,15 @@ function loadHelper(name) {
export function get( export function get(
name, name,
getDependency?: string => t.Expression, getDependency?: string => ?t.Expression,
id?, id?,
getLocalBindings?: () => string[], localBindings?: string[],
) { ) {
const helper = loadHelper(name); return loadHelper(name).build(getDependency, id, localBindings);
return helper(getDependency, id, getLocalBindings); }
export function getDependencies(name: string): $ReadOnlyArray<string> {
return Array.from(loadHelper(name).dependencies.values());
} }
export const list = Object.keys(helpers) export const list = Object.keys(helpers)

View File

@ -99,6 +99,15 @@ function buildRuntimeRewritePlugin(relativePath, helperName, dependencies) {
}; };
} }
function buildRequireCall(id, dep) {
return t.variableDeclaration("var", [
t.variableDeclarator(
id,
t.callExpression(t.identifier("require"), [t.stringLiteral(dep)])
)
]);
}
function buildHelper(helperName, modules, useBuiltIns) { function buildHelper(helperName, modules, useBuiltIns) {
const id = const id =
modules === "commonjs" modules === "commonjs"
@ -106,8 +115,27 @@ function buildHelper(helperName, modules, useBuiltIns) {
: null; : null;
const sourceType = modules === "commonjs" ? "script" : "module"; const sourceType = modules === "commonjs" ? "script" : "module";
const helper = helpers.get(helperName, null, id); const tree = t.program([], [], sourceType);
const tree = t.program(helper.nodes, [], sourceType); const dependencies = {};
let bindings = null;
if (modules === "commonjs") {
bindings = [];
for (const dep of helpers.getDependencies(helperName)) {
const id = dependencies[dep] = t.identifier(t.toIdentifier(dep));
tree.body.push(buildRequireCall(id, dep));
bindings.push(id.name);
}
}
const helper = helpers.get(
helperName,
dep => dependencies[dep],
id,
bindings
);
tree.body.push.apply(tree.body, helper.nodes);
const transformOpts = makeTransformOpts(modules, useBuiltIns); const transformOpts = makeTransformOpts(modules, useBuiltIns);
const relative = useBuiltIns ? "../.." : ".."; const relative = useBuiltIns ? "../.." : "..";