Skip to content

Commit b3fe2b0

Browse files
Add loader supporting mixed-format packages (#8)
1 parent 67d0dc2 commit b3fe2b0

File tree

6 files changed

+48
-0
lines changed

6 files changed

+48
-0
lines changed

mixed-format/fixture/cjs.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
exports.qux = require('./cjs2.js');

mixed-format/fixture/cjs2.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
module.exports = 'zed';

mixed-format/fixture/esm.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export const foo = 'bar';

mixed-format/fixture/package.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"type": "commonjs"
3+
}

mixed-format/loader.mjs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
export async function load(url, context, nextLoad) {
2+
if (!url.endsWith('.js')) return nextLoad(url);
3+
4+
const nextResult = await nextLoad(url, { ...context, format: 'module' })
5+
.then((result) => {
6+
if (containsCJS(result.source)) { throw new Error('CommonJS'); }
7+
8+
return result;
9+
})
10+
.catch(async (err) => {
11+
if (
12+
(err?.message.includes('require') && err.includes('import'))
13+
|| err?.message.includes('CommonJS')
14+
) {
15+
return { format: 'commonjs' };
16+
}
17+
18+
throw err;
19+
});
20+
21+
return nextResult;
22+
}
23+
24+
function containsCJS(source) {
25+
const src = '' + source;
26+
27+
// A realistic version of this loader would use a parser like Acorn to check for actual `module.exports` syntax
28+
if (src.match(/exports[\.( ?=)]/)) { return true };
29+
30+
if (
31+
src.match(/require\(/)
32+
&& !src.match(/createRequire\(/)
33+
) return true;
34+
}

mixed-format/test.mjs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import assert from 'node:assert';
2+
3+
import { foo } from './fixture/esm.js';
4+
import { qux } from './fixture/cjs.js';
5+
6+
7+
assert.strictEqual(foo, 'bar');
8+
assert.strictEqual(qux, 'zed');

0 commit comments

Comments
 (0)