add some test cases for cjs tree-shaking

This commit is contained in:
Tobias Koppers 2019-12-04 16:19:39 +01:00
parent 6ef9ea8f27
commit 26f30cebce
56 changed files with 535 additions and 0 deletions

View File

@ -0,0 +1,5 @@
module.exports.func = function f() {
"use strict";
return this;
};
module.exports.abc = "abc";

View File

@ -0,0 +1,7 @@
exports.abc = "abc";
function f(m) {
m.exports = { abc: "abc", def: "def" };
}
f(module);

View File

@ -0,0 +1,6 @@
exports.abc = "abc";
var newObj = {};
exports = newObj;
exports.def = "def";

View File

@ -0,0 +1,6 @@
Object.defineProperty(exports, "abc", { value: "abc" });
var newObj = {};
exports = newObj;
Object.defineProperty(exports, "def", { value: "def" });

View File

@ -0,0 +1,10 @@
exports.abc = "abc";
Object.defineProperties(module, {
exports: {
value: {
abc: "abc",
def: "def"
}
}
});

View File

@ -0,0 +1,8 @@
exports.abc = "abc";
Object.defineProperty(module, "exports", {
value: {
abc: "abc",
def: "def"
}
});

View File

@ -0,0 +1,56 @@
it("should bailout when reading whole exports object from this", () => {
var test = require("./reading-this").test;
expect(test().abc).toBe("abc");
});
it("should bailout when reading whole exports object from exports", () => {
var test = require("./reading-exports").test;
expect(test().abc).toBe("abc");
});
it("should bailout when reading whole exports object from module.exports", () => {
var test = require("./reading-module-exports").test;
expect(test().abc).toBe("abc");
});
it("should reassigning exports (assign values)", () => {
expect(require("./assign-exports-assign").abc).toBe("abc");
expect(require("./assign-exports-assign").def).toBe(undefined);
});
it("should reassigning exports (define values)", () => {
expect(require("./assign-exports-define").abc).toBe("abc");
expect(require("./assign-exports-define").def).toBe(undefined);
});
it("should not mangle or remove nested properties", () => {
expect(require("./nested-property").abc).toBe("abc");
});
it("should be able to access the exports via call context", () => {
expect(require("./accessing-call-context?1").func().abc).toBe("abc");
var cc = require("./accessing-call-context?2");
expect(cc.func().abc).toBe("abc");
var func = require("./accessing-call-context?3").func;
expect(func()).toBe(undefined);
});
it("should be able to define an exports property on module (property)", () => {
expect(require("./define-module-property?2").abc).toBe("abc");
expect(require("./define-module-property?1").def).toBe("def");
});
it("should be able to define an exports property on module (properties)", () => {
expect(require("./define-module-properties?2").abc).toBe("abc");
expect(require("./define-module-properties?1").def).toBe("def");
});
it("should be able to do stuff with the module object", () => {
expect(require("./accessing-module?2").abc).toBe("abc");
expect(require("./accessing-module?1").def).toBe("def");
});
it("should be able to use AMD to define exports", () => {
expect(require("./using-amd?2").abc).toBe("abc");
expect(require("./using-amd?1").def).toBe("def");
});

View File

@ -0,0 +1,8 @@
var abc = {};
module.exports = abc;
module.exports.abc = "abc";
module.exports.def = "def";
expect(abc).toEqual({ abc: "abc", def: "def" });

View File

@ -0,0 +1,5 @@
exports.abc = "abc";
exports.test = function() {
return exports;
};

View File

@ -0,0 +1,5 @@
exports.abc = "abc";
exports.test = function() {
return module.exports;
};

View File

@ -0,0 +1,5 @@
exports.abc = "abc";
exports.test = () => {
return this;
};

View File

@ -0,0 +1,5 @@
exports.abc = "not-abc";
define({
abc: "abc",
def: "def"
});

View File

@ -0,0 +1,10 @@
it("should allow to require esm", () => {
expect(require("./module?1").abc).toBe("abc");
expect(typeof require("./module?2").func).toBe("function");
// check if a function called with a namespace object as context
// still yield the same optimization, compared to only accessing
// the export
expect(Object.keys(require("./module?3").func())).toEqual(
Object.keys(require.cache[require.resolve("./module?2")].exports)
);
});

View File

@ -0,0 +1,6 @@
export const abc = "abc";
export const def = "def";
export const func = function() {
"use strict";
return this;
};

View File

@ -0,0 +1,9 @@
import m1 from "./module?1";
import m2 from "./module?2";
import { abc } from "./module?3";
it("should allow to import cjs with esm", () => {
expect(m1.abc).toBe("abc");
expect(m2).toEqual({ abc: "abc", def: "def" });
expect(abc).toBe("abc");
});

View File

@ -0,0 +1,2 @@
exports.abc = "abc";
exports.def = "def";

View File

@ -0,0 +1,2 @@
exports.abc = "abc";
exports.def = "def";

View File

@ -0,0 +1,2 @@
module.exports.abc = "abc";
module.exports.def = "def";

View File

@ -0,0 +1,2 @@
this.abc = "abc";
this.def = "def";

View File

@ -0,0 +1,3 @@
module.exports = () => "abc";
module.exports.def = "def";

View File

@ -0,0 +1,5 @@
module.exports = function() {
return "abc";
};
module.exports.def = "def";

View File

@ -0,0 +1,5 @@
module.exports = {
abc: "abc"
};
module.exports.def = "def";

View File

@ -0,0 +1,2 @@
Object.defineProperty(exports, "abc", { enumerable: true, value: "abc" });
Object.defineProperty(exports, "def", { enumerable: true, value: "def" });

View File

@ -0,0 +1,8 @@
Object.defineProperty(module.exports, "abc", {
enumerable: true,
value: "abc"
});
Object.defineProperty(module.exports, "def", {
enumerable: true,
value: "def"
});

View File

@ -0,0 +1,2 @@
Object.defineProperty(this, "abc", { enumerable: true, value: "abc" });
Object.defineProperty(this, "def", { enumerable: true, value: "def" });

View File

@ -0,0 +1,83 @@
it("should allow to export via exports", () => {
expect(require("./assign-exports-property?1").abc).toBe("abc");
expect(require("./assign-exports-property?2")).toEqual({
abc: "abc",
def: "def"
});
});
it("should allow to export via module.exports", () => {
expect(require("./assign-module-exports-property?1").abc).toBe("abc");
expect(require("./assign-module-exports-property?2")).toEqual({
abc: "abc",
def: "def"
});
});
it("should allow to export via this", () => {
expect(require("./assign-this-property?1").abc).toBe("abc");
expect(require("./assign-this-property?2")).toEqual({
abc: "abc",
def: "def"
});
});
it("should allow to export via define property on exports", () => {
expect(require("./define-exports-property?1").abc).toBe("abc");
expect(require("./define-exports-property?2")).toEqual({
abc: "abc",
def: "def"
});
});
it("should allow to export via define property on module.exports", () => {
expect(require("./define-module-exports-property?1").abc).toBe("abc");
expect(require("./define-module-exports-property?2")).toEqual({
abc: "abc",
def: "def"
});
});
it("should allow to export via define property on this", () => {
expect(require("./define-this-property?1").abc).toBe("abc");
expect(require("./define-this-property?2")).toEqual({
abc: "abc",
def: "def"
});
});
it("should allow to read own exports via exports", () => {
var test = require("./reading-self-from-exports").test;
expect(test()).toBe("abc");
});
it("should allow to read own exports via module.exports", () => {
var test = require("./reading-self-from-module-exports").test;
expect(test()).toBe("abc");
});
it("should allow to read own exports via this", () => {
var test = require("./reading-self-from-this").test;
expect(test()).toBe("abc");
});
it("should allow to attach exports to object", () => {
expect(require("./attach-to-object?1").abc).toBe("abc");
expect(require("./attach-to-object?2").def).toBe("def");
expect(require("./attach-to-object?3").abc).toBe("abc");
expect(require("./attach-to-object?3").def).toBe("def");
});
it("should allow to attach exports to function", () => {
expect(require("./attach-to-function?1")()).toBe("abc");
expect(require("./attach-to-function?2").def).toBe("def");
expect(require("./attach-to-function?3")()).toBe("abc");
expect(require("./attach-to-function?3").def).toBe("def");
});
it("should allow to attach exports to arrow function", () => {
expect(require("./attach-to-arrow-function?1")()).toBe("abc");
expect(require("./attach-to-arrow-function?2").def).toBe("def");
expect(require("./attach-to-arrow-function?3")()).toBe("abc");
expect(require("./attach-to-arrow-function?3").def).toBe("def");
});

View File

@ -0,0 +1,5 @@
exports.abc = "abc";
exports.test = function() {
return exports.abc;
};

View File

@ -0,0 +1,5 @@
exports.abc = "abc";
exports.test = function() {
return module.exports.abc;
};

View File

@ -0,0 +1,5 @@
exports.abc = "abc";
exports.test = () => {
return this.abc;
};

View File

@ -0,0 +1,15 @@
it("should be able to import a module via require and property", () => {
expect(require("./module").abc).toBe("abc");
});
it("should be able to import a module via require and destruct", () => {
var { abc } = require("./module");
expect(abc).toBe("abc");
});
it("should be able to import a module via require and exports object", () => {
var module1 = require("./module?1");
expect(module1.abc).toBe("abc");
var module2 = require("./module?2");
expect(module2).toEqual({ abc: "abc", def: "def" });
});

View File

@ -0,0 +1,2 @@
exports.abc = "abc";
exports.def = "def";

View File

@ -0,0 +1,33 @@
import module1 from "./module?1";
import module2, { a } from "./module?2";
it("should allow mutating imported modules (changing existing exports)", () => {
expect(module1.abc).toBe("abc");
expect(module1.def).toBe("def");
module1.abc = "new-abc";
expect(module1.abc).toBe("new-abc");
expect(module1.def).toBe("def");
});
it("should allow mutating imported modules (adding new properties)", () => {
expect(module2.abc).toBe("abc");
expect(module2.def).toBe("def");
expect(module2.ghi).toBe(undefined);
expect(module2.Oi).toBe(undefined);
expect(module2.a).toBe(undefined);
expect(a).toBe(undefined);
expect(module2[""]).toBe(undefined);
module2.ghi = "ghi";
module2.Oi = "Oi";
module2.a = "a";
module2[""] = {};
module2[""].abc = "abc";
expect(module2.abc).toBe("abc");
expect(module2.def).toBe("def");
expect(module2.ghi).toBe("ghi");
expect(module2.Oi).toBe("Oi");
expect(module2.a).toBe("a");
expect(a).toBe("a");
expect(module2[""]).toEqual({ abc: "abc" });
expect(module2[""].abc).toBe("abc");
});

View File

@ -0,0 +1,2 @@
exports.abc = "abc";
exports.def = "def";

View File

@ -0,0 +1,25 @@
it("should allow to create namespace exports via __esModule on exports", async () => {
expect(await import("./namespace-via-exports")).toBe(
require("./namespace-via-exports")
);
});
it("should allow to create namespace exports via __esModule on literal", async () => {
expect(await import("./namespace-via-literal")).toBe(
require("./namespace-via-literal")
);
});
it("should allow to create namespace exports via __esModule with Object.defineProperty", async () => {
expect(await import("./namespace-via-define-property")).toBe(
require("./namespace-via-define-property")
);
});
it("should allow to create namespace exports via __esModule with Object.defineProperty minimized true", async () => {
expect(await import("./namespace-via-define-property-minimized")).toBe(
require("./namespace-via-define-property-minimized")
);
});
it("should allow to create namespace exports via __esModule with Object.defineProperties", async () => {
expect(await import("./namespace-via-define-properties")).toBe(
require("./namespace-via-define-properties")
);
});

View File

@ -0,0 +1,5 @@
Object.defineProperties(exports, {
__esModule: { value: true },
abc: { enumerable: true, value: "abc" },
default: { enumerable: true, value: "default" }
});

View File

@ -0,0 +1,3 @@
Object.defineProperty(exports, "__esModule", { value: !0 });
exports.abc = "abc";
exports.default = "default";

View File

@ -0,0 +1,3 @@
Object.defineProperty(exports, "__esModule", { value: true });
exports.abc = "abc";
exports.default = "default";

View File

@ -0,0 +1,3 @@
exports.__esModule = true;
exports.abc = "abc";
exports.default = "default";

View File

@ -0,0 +1,5 @@
module.exports = {
__esModule: true,
abc: "abc",
default: "default"
};

View File

@ -0,0 +1,4 @@
module.exports = {
abc: "abc",
def: "def"
};

View File

@ -0,0 +1,9 @@
it("should be able to export an object literal", () => {
expect(require("./direct-object?1").abc).toBe("abc");
expect(require("./direct-object?2")).toEqual({ abc: "abc", def: "def" });
});
it("should be able to export an object literal indirect", () => {
expect(require("./indirect-object?1").abc).toBe("abc");
expect(require("./indirect-object?2")).toEqual({ abc: "abc", def: "def" });
});

View File

@ -0,0 +1,6 @@
var value = {
abc: "abc",
def: "def"
};
module.exports = value;

View File

@ -0,0 +1,41 @@
it("should allow to reexport a exports object (this, exports)", () => {
expect(require("./reexport-whole-exports?1").m1.abc).toBe("abc");
expect(require("./reexport-whole-exports?2").m2.abc).toBe("abc");
expect(require("./reexport-whole-exports?3").m3.abc).toBe("abc");
expect(require("./reexport-whole-exports?4").m4.abc).toBe("abc");
});
it("should allow to reexport a exports object (module.exports, object literal)", () => {
expect(require("./reexport-whole-module-exports?1").m1.abc).toBe("abc");
expect(require("./reexport-whole-module-exports?2").m2.abc).toBe("abc");
expect(require("./reexport-whole-module-exports?3").m3.abc).toBe("abc");
expect(require("./reexport-whole-module-exports?4").m4.abc).toBe("abc");
});
it("should allow to reexport a imported property (this, exports)", () => {
expect(require("./reexport-property-exports?1").p1).toBe("abc");
expect(require("./reexport-property-exports?2").p2).toBe("abc");
expect(require("./reexport-property-exports?3").p3).toBe("abc");
expect(require("./reexport-property-exports?4").p4).toBe("abc");
});
it("should allow to reexport a imported property (module.exports, object literal)", () => {
expect(require("./reexport-property-module-exports?1").p1).toBe("abc");
expect(require("./reexport-property-module-exports?2").p2).toBe("abc");
expect(require("./reexport-property-module-exports?3").p3).toBe("abc");
expect(require("./reexport-property-module-exports?4").p4).toBe("abc");
});
it("should allow to reexport a reexported exports object (this, exports)", () => {
expect(require("./reexport-reexport-exports?1").x1.abc).toBe("abc");
expect(require("./reexport-reexport-exports?2").x2.abc).toBe("abc");
expect(require("./reexport-reexport-exports?3").x3.abc).toBe("abc");
expect(require("./reexport-reexport-exports?4").x4.abc).toBe("abc");
});
it("should allow to reexport a reexported exports object (module.exports, object literal)", () => {
expect(require("./reexport-reexport-module-exports?1").x1.abc).toBe("abc");
expect(require("./reexport-reexport-module-exports?2").x2.abc).toBe("abc");
expect(require("./reexport-reexport-module-exports?3").x3.abc).toBe("abc");
expect(require("./reexport-reexport-module-exports?4").x4.abc).toBe("abc");
});

View File

@ -0,0 +1,2 @@
exports.abc = "abc";
exports.def = "def";

View File

@ -0,0 +1,6 @@
exports.p1 = require("./module?pe1").abc;
var m2 = require("./module?pe2");
exports.p2 = m2.abc;
this.p3 = require("./module?pe3").abc;
var m4 = require("./module?pe4");
this.p4 = m4.abc;

View File

@ -0,0 +1,8 @@
var m2 = require("./module?pme2");
module.exports = {
p1: require("./module?pme1").abc,
p2: m2.abc
};
module.exports.p3 = require("./module?pme3").abc;
var m4 = require("./module?pme4");
module.exports.p4 = m4.abc;

View File

@ -0,0 +1,6 @@
exports.x1 = require("./reexport-whole-exports?x1").m1;
var m2 = require("./reexport-whole-exports?x2");
exports.x2 = m2.m2;
this.x3 = require("./reexport-whole-exports?x3").m3;
var m4 = require("./reexport-whole-exports?x4");
this.x4 = m4.m4;

View File

@ -0,0 +1,8 @@
var m2 = require("./reexport-whole-module-exports?x2");
module.exports = {
x1: require("./reexport-whole-module-exports?x1").m1,
x2: m2.m2
};
module.exports.x3 = require("./reexport-whole-module-exports?x3").m3;
var m4 = require("./reexport-whole-module-exports?x4");
module.exports.x4 = m4.m4;

View File

@ -0,0 +1,6 @@
exports.m1 = require("./module?we1");
var m2 = require("./module?we2");
exports.m2 = m2;
this.m3 = require("./module?we3");
var m4 = require("./module?we4");
this.m4 = m4;

View File

@ -0,0 +1,8 @@
var m2 = require("./module?wme2");
module.exports = {
m1: require("./module?wme1"),
m2
};
module.exports.m3 = require("./module?wme3");
var m4 = require("./module?wme4");
module.exports.m4 = m4;

View File

@ -0,0 +1,5 @@
var xxx = _interopRequireDefault(require("./module?2"));
function _interopRequireDefault(obj) {
return obj && obj.__esModule ? obj : { default: obj };
}
module.exports = xxx.default.abc;

View File

@ -0,0 +1,14 @@
it("should support typescript export *", () => {
expect(require("./typescript-reexport").abc).toBe("abc");
});
it("should support babel default interop", () => {
var xxx2 = _interopRequireDefault(require("./module?2"));
var xxx3 = _interopRequireDefault(require("./module?3"));
expect(xxx2.default.abc).toBe("abc");
expect(xxx3.default).toEqual({ abc: "abc", def: "def" });
});
function _interopRequireDefault(obj) {
return obj && obj.__esModule ? obj : { default: obj };
}

View File

@ -0,0 +1,2 @@
exports.abc = "abc";
exports.def = "def";

View File

@ -0,0 +1,4 @@
function __export(m) {
for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
}
__export(require("./module?1"));

View File

@ -0,0 +1,16 @@
import m from "./module";
it("should allow any name as exports in CommonJs", () => {
expect(m.abc).toBe("abc");
expect(m[""]).toBe("");
expect(m["default"]).toBe("default");
expect(m["0"]).toBe("0");
expect(m[1]).toBe(1);
expect(m.length).toBe("length");
expect(m["0_0"]).toBe("0_0");
expect(m.if).toBe("if");
expect(m["\0"]).toBe("\0");
expect(m["\n"]).toBe("\n");
expect(m["*/"]).toBe("*/");
expect(m["a.b.c"]).toBe("a.b.c");
});

View File

@ -0,0 +1,12 @@
exports.abc = "abc";
exports[""] = "";
exports["default"] = "default";
exports["0"] = "0";
exports[1] = 1;
exports.length = "length";
exports["0_0"] = "0_0";
exports.if = "if";
exports["\0"] = "\0";
exports["\n"] = "\n";
exports["*/"] = "*/";
exports["a.b.c"] = "a.b.c";