Skip to content

Commit

Permalink
fix(cjs): patch module.path for accurate cache ID
Browse files Browse the repository at this point in the history
fixes #651
  • Loading branch information
privatenumber authored Sep 12, 2024
1 parent 44ed37f commit 0329bfc
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 2 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ jobs:
strategy:
matrix:
os: [ubuntu-latest, windows-latest]
timeout-minutes: 5
timeout-minutes: 10

steps:
- name: Checkout
Expand Down
1 change: 1 addition & 0 deletions src/@types/module.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ declare module 'module' {
export const _cache: NodeJS.Require['cache'];

export type Parent = {
id: string;

/**
* Can be null if the parent id is 'internal/preload' (e.g. via --require)
Expand Down
12 changes: 12 additions & 0 deletions src/cjs/api/module-extensions.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import fs from 'node:fs';
import path from 'node:path';
import Module from 'node:module';
import type { TransformOptions } from 'esbuild';
import { transformSync } from '../../utils/transform/index.js';
Expand Down Expand Up @@ -96,6 +97,17 @@ export const createExtensions = (
return defaultLoader(module, filePath);
}

/**
* In new Module(), m.path = path.dirname(module.id) but module.id coming from
* ESM resolver may be a data: path
*
* In these cases, we fix m.path to be the actual directory of the file
*/
// https://github.com/nodejs/node/blob/v22.8.0/lib/internal/modules/cjs/loader.js#L298
if (module.id.startsWith('data:text/javascript,')) {
module.path = path.dirname(cleanFilePath);
}

// For tracking dependencies in watch mode
if (parent?.send) {
parent.send({
Expand Down
41 changes: 40 additions & 1 deletion tests/specs/smoke.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ const wasmPath = path.resolve('tests/fixtures/test.wasm');
const wasmPathUrl = pathToFileURL(wasmPath).toString();

export default testSuite(async ({ describe }, { tsx, supports, version }: NodeApis) => {
describe('Smoke', ({ describe }) => {
describe('Smoke', ({ describe, test }) => {
for (const packageType of packageTypes) {
const isCommonJs = packageType === 'commonjs';

Expand Down Expand Up @@ -481,5 +481,44 @@ export default testSuite(async ({ describe }, { tsx, supports, version }: NodeAp
}
});
}

// https://github.com/privatenumber/tsx/issues/651
test('resolves same relative path from CJS loaded by ESM', async ({ onTestFail }) => {
await using fixture = await createFixture({
'package.json': createPackageJson({ type: 'commonjs' }),
a: {
'index.ts': `
import { value } from './value.js';
if (value !== 1) {
throw new Error('Unexpected value');
}
`,
'value.js': 'export const value = 1;',
},
b: {
'index.ts': `
import { value } from './value.js';
if (value !== 2) {
throw new Error('Unexpected value');
}
`,
'value.js': 'export const value = 2;',
},
'index.mjs': `
import './a/index.js';
import './b/index.js';
`,
});

const p = await tsx(['index.mjs'], {
cwd: fixture.path,
});
onTestFail(() => {
console.log(p);
});
expect(p.failed).toBe(false);
});
});
});

0 comments on commit 0329bfc

Please sign in to comment.