Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion packages/plugin-vite/src/mod.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ export function fresh(config?: FreshViteConfig): Plugin[] {
"react-dom": "preact/compat",
react: "preact/compat",
},
noExternal: true,
},
optimizeDeps: {
include: [
Expand Down
86 changes: 86 additions & 0 deletions packages/plugin-vite/src/plugins/commonjs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,28 @@ export function cjsPlugin(

if (body.length === 0 && state.get(HAS_ES_MODULE)) {
path.pushContainer("body", t.exportNamedDeclaration(null));
} else {
const seen = new Set<string>();

const children = path.get("body");
for (let i = children.length - 1; i >= 0; i--) {
const child = children[i];
if (child.isExportNamedDeclaration()) {
if (
t.isVariableDeclaration(child.node.declaration) &&
child.node.declaration.declarations.length > 0 &&
t.isIdentifier(child.node.declaration.declarations[0].id)
) {
const name = child.node.declaration.declarations[0].id.name;

if (seen.has(name)) {
child.remove();
} else {
seen.add(name);
}
}
}
}
}
},
},
Expand Down Expand Up @@ -112,6 +134,70 @@ export function cjsPlugin(
}
}
}
} else if (expr.isCallExpression()) {
if (
t.isMemberExpression(expr.node.callee) &&
t.isIdentifier(expr.node.callee.object) &&
expr.node.callee.object.name === "Object" &&
t.isIdentifier(expr.node.callee.property) &&
expr.node.callee.property.name === "defineProperty" &&
expr.node.arguments.length === 3 &&
t.isIdentifier(expr.node.arguments[0]) &&
expr.node.arguments[0].name === "exports" &&
t.isStringLiteral(expr.node.arguments[1]) &&
expr.node.arguments[1].value !== "__esModule" &&
t.isObjectExpression(expr.node.arguments[2])
) {
const named = expr.node.arguments[1].value;
const obj = expr.node.arguments[2];

let right: types.Expression = t.nullLiteral();

for (let i = 0; i < obj.properties.length; i++) {
const prop = obj.properties[i];

if (t.isObjectProperty(prop)) {
if (t.isIdentifier(prop.key)) {
if (prop.key.name === "get") {
if (
t.isFunctionExpression(prop.value) ||
t.isArrowFunctionExpression(prop.value)
) {
right = t.callExpression(
t.parenthesizedExpression(
t.cloneNode(prop.value, true),
),
[],
);
}
}
}
} else if (t.isObjectMethod(prop)) {
if (t.isIdentifier(prop.key)) {
if (prop.key.name === "get") {
right = t.callExpression(
t.parenthesizedExpression(
t.functionExpression(
null,
[],
t.cloneNode(prop.body, true),
),
),
[],
);
}
}
}
}

path.replaceWith(
t.exportNamedDeclaration(
t.variableDeclaration("let", [
t.variableDeclarator(t.identifier(named), right),
]),
),
);
}
}
},
},
Expand Down
52 changes: 52 additions & 0 deletions packages/plugin-vite/src/plugins/commonjs_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,58 @@ var a = _mod.default ?? _mod,
});
});

Deno.test("commonjs - duplicate exports", () => {
runTest({
input: `Object.defineProperty(exports, "__esModule", { value: true });
exports.trace = void 0;
exports.trace = 'foo'`,
expected: `export let trace = 'foo';`,
});
});

Deno.test("commonjs - cleared exports", () => {
runTest({
input: `Object.defineProperty(exports, "__esModule", { value: true });
exports.foo = exports.bar = void 0;
exports.foo = 'foo'`,
expected: `export let foo = 'foo';`,
});
});

Deno.test("commonjs - define exports", () => {
runTest({
input: `var utils_1 = require("./bar");
Object.defineProperty(exports, "foo", { enumerable: true, get: function () { return utils_1.foo; } });`,
expected: `import * as _mod from "./bar";
var utils_1 = _mod.default ?? _mod;
export let foo = (function () {
return utils_1.foo;
})();`,
});
});

Deno.test("commonjs - define exports #2", () => {
runTest({
input: `var utils_1 = require("./bar");
Object.defineProperty(exports, "foo", { enumerable: true, get() { return utils_1.foo; } });`,
expected: `import * as _mod from "./bar";
var utils_1 = _mod.default ?? _mod;
export let foo = (function () {
return utils_1.foo;
})();`,
});
});

Deno.test("commonjs - define exports #3", () => {
runTest({
input: `Object.defineProperty(exports, "__esModule", { value: true });
exports._globalThis = void 0;
exports._globalThis = typeof globalThis === 'object' ? globalThis : global;`,
expected:
`export let _globalThis = typeof globalThis === 'object' ? globalThis : global;`,
});
});

// I've never seen this, seems rare. Skipping for now.
Deno.test.ignore("commonjs - require", () => {
runTest({
Expand Down
6 changes: 6 additions & 0 deletions packages/plugin-vite/src/plugins/deno.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,12 @@ export function deno(): Plugin {
return true;
},
async resolveId(id, importer, options) {
// Workaround until upstream PR is merged and released,
// see: https://github.com/vitejs/vite/pull/20558
if (id.startsWith("deno-npm:")) {
id = id.slice("deno-".length);
}

importer = isDenoSpecifier(importer)
? parseDenoSpecifier(importer).specifier
: importer;
Expand Down
8 changes: 1 addition & 7 deletions packages/plugin-vite/src/plugins/patches.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import type { Plugin } from "vite";
import * as babel from "@babel/core";
import { cjsPlugin } from "./commonjs.ts";
import { npmWorkaround } from "./npm_workaround.ts";

export function patches(): Plugin {
Expand All @@ -9,16 +8,11 @@ export function patches(): Plugin {
applyToEnvironment() {
return true;
},
resolveId(id) {
if (id.startsWith("deno-npm:")) {
return id.slice("deno-".length);
}
},
transform(code, id) {
const res = babel.transformSync(code, {
filename: id,
babelrc: false,
plugins: [npmWorkaround, cjsPlugin],
plugins: [npmWorkaround],
});

if (res?.code) {
Expand Down
Loading