Skip to content

Commit e5ca7d1

Browse files
committed
wip
1 parent 4c787f0 commit e5ca7d1

File tree

2 files changed

+57
-11
lines changed

2 files changed

+57
-11
lines changed

src/rollup/plugins/native-modules.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@ const PREFIX = '\0natives:';
88
* Handles native Node.js addons (.node files)
99
* - Detects imports of .node files
1010
* - Copies them to natives directory
11-
* - Rewrites imports to use createRequire for ESM compatibility
11+
* - Returns ESM code that works for both ESM and CJS:
12+
* - ESM: esmInjectCreateRequire plugin adds createRequire shim
13+
* - CJS: Rollup automatically transforms to module.exports = require(...)
1214
*/
1315
export const nativeModules = (
1416
distDirectory: string,
@@ -80,12 +82,10 @@ export const nativeModules = (
8082

8183
const relativePath = id.slice(PREFIX.length);
8284

83-
// Generate code that uses createRequire for ESM compatibility
84-
return `
85-
import { createRequire } from 'module';
86-
const require = createRequire(import.meta.url);
87-
export default require(${JSON.stringify(relativePath)});
88-
`;
85+
// Return ESM code that Rollup will transform based on output format:
86+
// - For ESM: esmInjectCreateRequire plugin adds createRequire shim
87+
// - For CJS: Rollup transforms to module.exports = require(...)
88+
return `export default require(${JSON.stringify(relativePath)});`;
8989
},
9090
};
9191
};

tests/specs/builds/native-modules.ts

Lines changed: 50 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,11 @@ import { createPackageJson } from '../../fixtures.js';
77

88
export default testSuite(({ describe }, nodePath: string) => {
99
describe('native modules', ({ test }) => {
10-
test('copies .node files to natives directory', async () => {
10+
test('ESM: copies .node files to natives directory', async () => {
1111
await using fixture = await createFixture({
1212
'package.json': createPackageJson({
13-
main: './dist/index.js',
13+
type: 'module',
14+
main: './dist/index.mjs',
1415
}),
1516
'src/index.js': `
1617
import native from './native.node';
@@ -42,9 +43,54 @@ export default testSuite(({ describe }, nodePath: string) => {
4243
const files = await fs.readdir(path.join(fixture.path, 'dist/natives'));
4344
expect(files.some(file => file.endsWith('.node'))).toBe(true);
4445

45-
// Check that import was rewritten
46-
const content = await fixture.readFile('dist/index.js', 'utf8');
46+
// Check that import was rewritten and uses createRequire for ESM
47+
const content = await fixture.readFile('dist/index.mjs', 'utf8');
4748
expect(content).toMatch('./natives');
49+
expect(content).toMatch('createRequire');
50+
});
51+
52+
test('CJS: copies .node files to natives directory', async () => {
53+
await using fixture = await createFixture({
54+
'package.json': createPackageJson({
55+
type: 'commonjs',
56+
main: './dist/index.cjs',
57+
}),
58+
'src/index.js': `
59+
import native from './native.node';
60+
console.log(native);
61+
`,
62+
});
63+
64+
// Create a dummy .node file after fixture is created
65+
await fs.writeFile(
66+
path.join(fixture.path, 'src/native.node'),
67+
Buffer.from('dummy native module'),
68+
);
69+
70+
const pkgrollProcess = await pkgroll([], {
71+
cwd: fixture.path,
72+
nodePath,
73+
});
74+
75+
expect(pkgrollProcess.exitCode).toBe(0);
76+
expect(pkgrollProcess.stderr).toBe('');
77+
78+
// Check that natives directory was created
79+
const nativesExists = await fs.access(path.join(fixture.path, 'dist/natives'))
80+
.then(() => true)
81+
.catch(() => false);
82+
expect(nativesExists).toBe(true);
83+
84+
// Check that .node file was copied
85+
const files = await fs.readdir(path.join(fixture.path, 'dist/natives'));
86+
expect(files.some(file => file.endsWith('.node'))).toBe(true);
87+
88+
// Check that import was transformed to require for CJS
89+
const content = await fixture.readFile('dist/index.cjs', 'utf8');
90+
expect(content).toMatch('./natives');
91+
expect(content).toMatch('require');
92+
// Should NOT have createRequire in CJS output
93+
expect(content).not.toMatch('createRequire');
4894
});
4995

5096
test('handles multiple src:dist pairs', async () => {

0 commit comments

Comments
 (0)