Skip to content

Commit 8c14866

Browse files
authored
revert: bring back Babel CJS transform (#3798)
## Summary Reverts two commits that broke CJS package handling in dev mode: - Reverts #3793 (CJS detection regex fix) - Reverts #3767 (removal of Babel CJS→ESM transform) The simplified CJS shim introduced in #3767 has two fundamental issues: 1. **Detection**: the heuristic (`code.includes("export ")`) is fooled by comments containing "export" 2. **Named exports**: the shim only provides `export default module.exports`, so `import { trace } from "@opentelemetry/api"` returns `undefined` (#3797) The Babel-based transform handled both correctly. Bringing it back until we can replace it with a proper solution using `deno_ast`'s CJS parser.
1 parent 2cf68af commit 8c14866

17 files changed

Lines changed: 2050 additions & 233 deletions

File tree

deno.lock

Lines changed: 0 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
exports.value = "ok";

packages/plugin-vite/demo/fixtures/commonjs_mod.js

Lines changed: 0 additions & 1 deletion
This file was deleted.
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
"use strict";
2+
// deno-lint-ignore no-var
3+
var __importDefault = (this && this.__importDefault) || function (mod) {
4+
return (mod && mod.__esModule) ? mod : { "default": mod };
5+
};
6+
Object.defineProperty(exports, "__esModule", { value: true });
7+
const assert_1 = __importDefault(require("assert"));
8+
(0, assert_1.default)(true);

packages/plugin-vite/demo/fixtures/maxmind.js

Lines changed: 0 additions & 2 deletions
This file was deleted.

packages/plugin-vite/demo/routes/tests/cjs_npm.tsx

Lines changed: 0 additions & 6 deletions
This file was deleted.

packages/plugin-vite/demo/routes/tests/commonjs.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { value } from "../../fixtures/commonjs_mod.js";
1+
import { value } from "../../fixtures/commonjs_mod.cjs";
22

33
export default function Page() {
44
return <h1>{value}</h1>;

packages/plugin-vite/demo/routes/tests/maxmind.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import * as maxmind from "../../fixtures/maxmind.js";
1+
import * as maxmind from "../../fixtures/maxmind.cjs";
22

33
export default function Page() {
44
// deno-lint-ignore no-console

packages/plugin-vite/src/mod.ts

Lines changed: 26 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -82,43 +82,15 @@ export function fresh(config?: FreshViteConfig): Plugin[] {
8282
});
8383

8484
let isDev = false;
85-
let freshMode = "development";
8685

8786
const plugins: Plugin[] = [
8887
{
8988
name: "fresh",
9089
sharedDuringBuild: true,
91-
async config(config, env) {
90+
config(config, env) {
9291
isDev = env.command === "serve";
93-
freshMode = isDev ? "development" : "production";
94-
95-
// Load env files early so define entries are available
96-
const root = config.root ? path.resolve(config.root) : Deno.cwd();
97-
const envDir = config.envDir ? path.resolve(root, config.envDir) : root;
98-
await loadEnvFile(path.join(envDir, ".env"));
99-
await loadEnvFile(path.join(envDir, ".env.local"));
100-
await loadEnvFile(path.join(envDir, `.env.${freshMode}`));
101-
await loadEnvFile(path.join(envDir, `.env.${freshMode}.local`));
102-
103-
// Build define map for FRESH_PUBLIC_* env vars
104-
// Replaces the Babel inlineEnvVarsPlugin with Vite's native define
105-
const envDefine: Record<string, string> = {};
106-
for (const [key, value] of Object.entries(Deno.env.toObject())) {
107-
if (key.startsWith("FRESH_PUBLIC_")) {
108-
envDefine[`process.env.${key}`] = JSON.stringify(value);
109-
envDefine[`import.meta.env.${key}`] = JSON.stringify(value);
110-
}
111-
}
11292

11393
return {
114-
define: envDefine,
115-
ssr: {
116-
// Bundle all deps in SSR so that resolve.alias
117-
// (react -> preact/compat) is applied consistently.
118-
// CJS packages are handled by the deno plugin's load
119-
// hook which wraps them in an ESM-compatible shim.
120-
noExternal: true,
121-
},
12294
server: {
12395
watch: {
12496
// Ignore temp files, editor swap files, and Vite timestamp
@@ -147,15 +119,14 @@ export function fresh(config?: FreshViteConfig): Plugin[] {
147119
"react-dom": "preact/compat",
148120
react: "preact/compat",
149121
},
122+
// Disallow externals, because it leads to duplicate
123+
// modules with `preact` vs `npm:preact@*` in the server
124+
// environment.
125+
noExternal: true,
150126
},
151-
152127
optimizeDeps: {
153-
// Disable dep optimizer because deno.ts handles all
154-
// module resolution. The optimizer causes duplicate
155-
// module instances when remote (JSR) islands resolve
156-
// deps to /@fs/ paths while the optimizer bundles to
157-
// /.vite/deps/. CJS packages in client-side islands
158-
// are handled by deno.ts's load hook.
128+
// Optimize deps somehow leads to duplicate modules or them
129+
// being placed in the wrong chunks...
159130
noDiscovery: true,
160131
},
161132

@@ -221,6 +192,14 @@ export function fresh(config?: FreshViteConfig): Plugin[] {
221192
return;
222193
}
223194

195+
// Ignore commonjs optional exports
196+
if (
197+
warning.code === "MISSING_EXPORT" &&
198+
warning.message.includes("__require")
199+
) {
200+
return;
201+
}
202+
224203
// Ignore this warnings
225204
if (warning.code === "THIS_IS_UNDEFINED") {
226205
return;
@@ -242,7 +221,7 @@ export function fresh(config?: FreshViteConfig): Plugin[] {
242221
},
243222
};
244223
},
245-
configResolved(vConfig) {
224+
async configResolved(vConfig) {
246225
// Run update check in background
247226
updateCheck(UPDATE_INTERVAL).catch(() => {});
248227

@@ -257,45 +236,19 @@ export function fresh(config?: FreshViteConfig): Plugin[] {
257236
const name = fConfig.namer.getUniqueName(specName);
258237
fConfig.islandSpecifiers.set(spec, name);
259238
});
260-
},
261-
},
262-
// Lightweight replacement for Deno.env.get() calls with FRESH_PUBLIC_*
263-
// and NODE_ENV values. Replaces the Babel inlineEnvVarsPlugin for this
264-
// pattern which can't be handled by Vite's define (it's a call expression).
265-
{
266-
name: "fresh:deno-env",
267-
sharedDuringBuild: true,
268-
applyToEnvironment() {
269-
return true;
270-
},
271-
transform: {
272-
filter: {
273-
id: /\.([tj]sx?|[mc]?[tj]s)(\?.*)?$/,
274-
},
275-
handler(code) {
276-
if (!code.includes("Deno.env.get(")) return;
277239

278-
const allEnv = Deno.env.toObject();
279-
let modified = false;
280-
const result = code.replace(
281-
/Deno\.env\.get\(\s*["']([^"']+)["']\s*\)/g,
282-
(match: string, name: string) => {
283-
if (name === "NODE_ENV") {
284-
modified = true;
285-
return JSON.stringify(freshMode);
286-
}
287-
if (name.startsWith("FRESH_PUBLIC_") && name in allEnv) {
288-
modified = true;
289-
return JSON.stringify(allEnv[name]);
290-
}
291-
return match;
292-
},
293-
);
240+
const envDir = pathWithRoot(
241+
vConfig.envDir || vConfig.root,
242+
vConfig.root,
243+
);
294244

295-
if (modified) return { code: result };
296-
},
245+
await loadEnvFile(path.join(envDir, ".env"));
246+
await loadEnvFile(path.join(envDir, ".env.local"));
247+
const mode = isDev ? "development" : "production";
248+
await loadEnvFile(path.join(envDir, `.env.${mode}`));
249+
await loadEnvFile(path.join(envDir, `.env.${mode}.local`));
297250
},
298-
} satisfies Plugin,
251+
},
299252
serverEntryPlugin(fConfig),
300253
patches(),
301254
...serverSnapshot(fConfig),

0 commit comments

Comments
 (0)