Skip to content

Commit

Permalink
Merge pull request #229 from benjamn/rename-module-by-wrapping-progra…
Browse files Browse the repository at this point in the history
…m-with-IIFE

Rename module identifier by wrapping program.body with IIFE.
  • Loading branch information
benjamn committed Jun 18, 2019
2 parents 83545ed + bb30506 commit a0e7913
Show file tree
Hide file tree
Showing 13 changed files with 119 additions and 53 deletions.
2 changes: 1 addition & 1 deletion lib/assignment-visitor.js
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ function wrap(visitor, path) {
type: "MemberExpression",
object: {
type: "Identifier",
name: "module"
name: visitor.moduleAlias,
},
property: {
type: "Identifier",
Expand Down
2 changes: 1 addition & 1 deletion lib/compiler.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ exports.compile = function (code, options) {
}

const rootPath = new FastPath(result.ast || parse(code));
options.moduleAlias = makeUniqueId(getOption(options, "moduleAlias"), code);
options.moduleAlias = getOption(options, "moduleAlias");
importExportVisitor.visit(rootPath, code, options);

const magicString = importExportVisitor.magicString;
Expand Down
6 changes: 0 additions & 6 deletions lib/import-export-visitor.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,6 @@ class ImportExportVisitor extends Visitor {
}
}

if (bodyInfo.parent.type === "Program" &&
this.moduleAlias !== "module") {
codeToInsert += this.generateLetDeclarations ? "const " : "var ";
codeToInsert += this.moduleAlias + "=module;";
}

const addExportsMap = (map, constant) => {
const namedExports = toModuleExport(this, map, constant);
if (namedExports) {
Expand Down
1 change: 1 addition & 0 deletions lib/transform.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ module.exports = function (ast, options) {
if (importExportVisitor.madeChanges) {
assignmentVisitor.visit(rootPath, {
exportedLocalNames: importExportVisitor.exportedLocalNames,
moduleAlias: importExportOptions.moduleAlias,
modifyAST: true
});

Expand Down
3 changes: 3 additions & 0 deletions lib/visitor.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ class Visitor {
this._piUpperBound = 0;
}

// The reset method does nothing unless it is overridden.
reset() {}

_afterReset() {
// Reset the bounds we are currently considering within
// this.possibleIndexes, so that we can adjust the bounds in
Expand Down
12 changes: 12 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
"devDependencies": {
"@babel/core": "7.4.4",
"@babel/parser": "7.4.4",
"@babel/plugin-transform-runtime": "^7.4.4",
"@babel/preset-env": "7.4.4",
"lodash": "4.17.11",
"mocha": "6.1.4",
Expand Down
87 changes: 57 additions & 30 deletions plugins/babel.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
var assert = require("assert");
var namespace;
var ibsPropertyName = "isBlockScoped";
var types;
var cache;
"use strict";

const assert = require("assert");
let namespace;
let ibsPropertyName = "isBlockScoped";
let types;
let cache;

function tryScopedLibDirect() {
namespace = require("@babel/types/lib/validators/isBlockScoped");
Expand Down Expand Up @@ -44,11 +46,11 @@ function tryUnscoped() {
return false;
}

var wrapped = namespace[ibsPropertyName];
const wrapped = namespace[ibsPropertyName];
assert.strictEqual(typeof wrapped, "function")

// Allow types.isBlockScoped to return true for import-related nodes.
var wrapper = namespace[ibsPropertyName] = function (node) {
const wrapper = namespace[ibsPropertyName] = function (node) {
return node &&
types.isImportDeclaration(node) ||
wrapped.apply(this, arguments);
Expand All @@ -66,32 +68,57 @@ function tryUnscoped() {
});

module.exports = function (context) {
var compiler = require("../lib/compiler.js");
var parse = require("../lib/parsers/babel.js").parse;
const compiler = require("../lib/compiler.js");
const transformOptions = {
parse: require("../lib/parsers/babel.js").parse
};

function transform(node) {
const result = compiler.transform(node, transformOptions);
if (! result.identical) {
// If the Reify compiler made any changes, invalidate all existing
// Scope objects, so that any variable binding changes made by
// compiler.transform will be reflected accurately.
cache.clearScope();
}
return result;
}

return {
visitor: {
Program: function (path) {
var transformOptions = {
parse: parse
};

var code = path.hub.file.code;
if (typeof code === "string") {
transformOptions.moduleAlias =
compiler.makeUniqueId("module", code);
}

var result = compiler.transform(
path.node,
Object.assign(transformOptions, this.opts)
);

// If the Reify compiler made any changes, invalidate all existing
// Scope objects, so that any variable binding changes made by
// compiler.transform will be reflected accurately.
if (! result.identical) {
cache.clearScope();
Program: {
enter(path) {
const code = path.hub.file.code;
if (typeof code === "string") {
transformOptions.moduleAlias =
compiler.makeUniqueId("module", code);
}
Object.assign(transformOptions, this.opts);
transform(path.node);
},

exit(path) {
const ast = transform(path.node).ast;
assert.strictEqual(ast.type, "Program");

ast.body = [
types.callExpression(
types.memberExpression(
types.parenthesizedExpression(
types.functionExpression(
null,
[types.identifier(transformOptions.moduleAlias)],
types.blockStatement(ast.body)
)
),
types.identifier("call")
),
[
types.thisExpression(),
types.identifier("module"),
]
)
];
}
}
}
Expand Down
46 changes: 40 additions & 6 deletions test/babel-plugin-tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import { files } from "./all-files.js";
import { parse } from "../lib/parsers/babel.js";
import reifyPlugin from "../plugins/babel.js";
import envPreset from "@babel/preset-env";
import runtimeTransform from "@babel/plugin-transform-runtime";
import Visitor from "../lib/visitor.js";

const filesToTest = Object.create(null);
const methodNameRegExp =
Expand Down Expand Up @@ -34,28 +36,60 @@ Object.keys(files).forEach((absPath) => {
filesToTest[relPath] = code;
});

function fail(path) {
throw new Error("unexpected node of type " + path.getNode().type);
}

class ImportExportChecker extends Visitor {
visitImportDeclaration(path) { fail(path) }
visitExportAllDeclaration(path) { fail(path) }
visitExportDefaultDeclaration(path) { fail(path) }
visitExportNamedDeclaration(path) { fail(path) }
}

describe("reify/plugins/babel", () => {
function check(code, options) {
const ast = parse(code);
delete ast.tokens;
const result = transformFromAst(ast, code, options);
assert.ok(methodNameRegExp.test(result.code), result.code);
new ImportExportChecker().visit(parse(result.code));
return result;
}

Object.keys(filesToTest).forEach((relPath) => {
const code = filesToTest[relPath];
const presets = [envPreset];
const plugins = [[reifyPlugin, {
generateLetDeclarations: true
}]];

const presets = [
[envPreset, {
targets: {
ie: 11
}
}]
];

const pluginsReifyFirst = [
[reifyPlugin, {
generateLetDeclarations: true
}],
runtimeTransform,
];

const pluginsReifyLast = [
[reifyPlugin, {
generateLetDeclarations: true
}],
runtimeTransform,
];

it(`compiles ${relPath}`, () => {
check(code, { plugins });
check(code, { plugins: pluginsReifyFirst });
check(code, { plugins: pluginsReifyLast });
});

it(`compiles ${relPath} with es2015`, () => {
check(code, { plugins, presets });
check(code, { plugins: pluginsReifyFirst, presets });
check(code, { plugins: pluginsReifyLast, presets });
});
});
});
6 changes: 0 additions & 6 deletions test/compiler-tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,6 @@ describe("compiler", () => {
assert.ok(/unexpected/i.test(error.message));
});

it("should choose a unique module identifier", () => {
const module = null, module2 = null;
import { a } from "./misc/abc";
assert.strictEqual(a, "a");
});

it("should be enabled for packages that depend on reify", () => {
import a from "enabled";
assert.strictEqual(a, assert);
Expand Down
2 changes: 1 addition & 1 deletion test/output/export-multi-namespace/expected.js
Original file line number Diff line number Diff line change
@@ -1 +1 @@
"use strict";var module1=module;module1.link("module",{"*":["a","b"]},0);
"use strict";module.link("module",{"*":["a","b"]},0);
2 changes: 1 addition & 1 deletion test/output/name/expected.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
"use strict";var module1=module;module1.export({foo:()=>foo});module1.export({id:()=>id,name:()=>name},true);const path = require("path");
"use strict";module.export({foo:()=>foo});module.export({id:()=>id,name:()=>name},true);const path = require("path");

const id = module.id,
name = path.basename(__filename);
Expand Down
2 changes: 1 addition & 1 deletion test/output/only-nested/expected.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
"use strict";var module1=module;function f() {var a,c;module1.link("./module",{a(v){a=v},b(v){c=v}},0);
"use strict";function f() {var a,c;module.link("./module",{a(v){a=v},b(v){c=v}},0);

}

0 comments on commit a0e7913

Please sign in to comment.