Skip to content

Commit d231d0b

Browse files
committed
fix(scripts): use file URL for ESM sourcemap preload
1 parent 95c4071 commit d231d0b

2 files changed

Lines changed: 31 additions & 2 deletions

File tree

tools/scripts/src/commands/start.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { spawn, type SpawnOptions, type ChildProcess, execFile as _execFile } fr
22
import { mkdir, rename, stat, open } from 'node:fs/promises';
33
import path from 'node:path';
44
import { scheduler } from 'node:timers/promises';
5+
import { pathToFileURL } from 'node:url';
56
import { debuglog, promisify } from 'node:util';
67

78
import { getFrameworkPath, importResolve } from '@eggjs/utils';
@@ -249,7 +250,7 @@ export default class Start<T extends typeof Start> extends BaseCommand<T> {
249250
});
250251
const sourceMapSupport = path.join(path.dirname(sourceMapSupportPkgPath), 'register.js');
251252
if (this.isESM) {
252-
execArgv.push('--import', sourceMapSupport);
253+
execArgv.push('--import', pathToFileURL(sourceMapSupport).href);
253254
} else {
254255
execArgv.push('--require', sourceMapSupport);
255256
}

tools/scripts/test/start-unit.test.ts

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ class TestStart extends (Start as any) {
2020
return '/fake/framework';
2121
}
2222
async getServerBin() {
23-
return '/fake/scripts/start-cluster.cjs';
23+
return `/fake/scripts/start-cluster.${this.isESM ? 'mjs' : 'cjs'}`;
2424
}
2525
}
2626

@@ -69,6 +69,34 @@ describe('test/start-unit.test.ts', () => {
6969
expect(options.env.NODE_ENV).toBe('production');
7070
});
7171

72+
it('preloads source-map-support with a file URL for ESM apps', async () => {
73+
const esmBaseDir = path.join(homeDir, 'esm-typescript-app');
74+
await fs.mkdir(esmBaseDir);
75+
await fs.writeFile(
76+
path.join(esmBaseDir, 'package.json'),
77+
JSON.stringify({ name: 'esm-typescript-app', type: 'module', egg: { typescript: true } }),
78+
);
79+
spawnMock.mockImplementation(() => ({
80+
once: vi.fn().mockReturnThis(),
81+
on: vi.fn().mockReturnThis(),
82+
unref: vi.fn(),
83+
disconnect: vi.fn(),
84+
kill: vi.fn(),
85+
pid: 1112,
86+
}));
87+
88+
await TestStart.run(['--workers=1', esmBaseDir]);
89+
90+
expect(spawnMock).toHaveBeenCalledTimes(1);
91+
const [, args] = spawnMock.mock.calls[0] as [string, string[]];
92+
expect(args).toContain('/fake/scripts/start-cluster.mjs');
93+
const importIndex = args.indexOf('--import');
94+
expect(importIndex).toBeGreaterThan(-1);
95+
// A Windows drive path such as D:\app\register.js is parsed as the
96+
// unsupported `d:` URL scheme by Node's ESM loader unless it is a file URL.
97+
expect(args[importIndex + 1]).toMatch(/^file:/);
98+
});
99+
72100
it('daemon mode backgrounds once the child reports egg-ready over IPC', async () => {
73101
const unref = vi.fn();
74102
const disconnect = vi.fn();

0 commit comments

Comments
 (0)