From 119ddf11f3df55223d39bbe6867e760eaee788a8 Mon Sep 17 00:00:00 2001 From: Jacob Smith <3012099+JakobJingleheimer@users.noreply.github.com> Date: Thu, 25 Aug 2022 16:47:24 +0200 Subject: [PATCH 1/3] Add loader to support mixed-format packages --- mixed-format/fixture/cjs.js | 1 + mixed-format/fixture/esm.js | 1 + mixed-format/fixture/package.json | 3 +++ mixed-format/loader.mjs | 23 +++++++++++++++++++++++ mixed-format/test.mjs | 8 ++++++++ 5 files changed, 36 insertions(+) create mode 100644 mixed-format/fixture/cjs.js create mode 100644 mixed-format/fixture/esm.js create mode 100644 mixed-format/fixture/package.json create mode 100644 mixed-format/loader.mjs create mode 100644 mixed-format/test.mjs diff --git a/mixed-format/fixture/cjs.js b/mixed-format/fixture/cjs.js new file mode 100644 index 0000000..deb8531 --- /dev/null +++ b/mixed-format/fixture/cjs.js @@ -0,0 +1 @@ +exports.qux = 'zed'; diff --git a/mixed-format/fixture/esm.js b/mixed-format/fixture/esm.js new file mode 100644 index 0000000..c155820 --- /dev/null +++ b/mixed-format/fixture/esm.js @@ -0,0 +1 @@ +export const foo = 'bar'; diff --git a/mixed-format/fixture/package.json b/mixed-format/fixture/package.json new file mode 100644 index 0000000..a0df0c8 --- /dev/null +++ b/mixed-format/fixture/package.json @@ -0,0 +1,3 @@ +{ + "type": "commonjs" +} diff --git a/mixed-format/loader.mjs b/mixed-format/loader.mjs new file mode 100644 index 0000000..aa38eaa --- /dev/null +++ b/mixed-format/loader.mjs @@ -0,0 +1,23 @@ +export async function load(url, context, nextLoad) { + if (!url.endsWith('.js')) return nextLoad(url); + + const nextResult = await nextLoad(url, { ...context, format: 'module' }) + .then((result) => { + if (`${result.source}`.match(/exports[\. =]/)) throw new Error('Module is commonjs'); + + return result; + }) + .catch(async (err) => { + if ( + (err?.message.includes('require') && err.includes('import')) + || err?.message.includes('commonjs') + ) return { + format: 'commonjs', + source: (await nextLoad(url, {...context, format: 'commonjs' })).source, + }; + + throw err; + }); + + return nextResult; +} diff --git a/mixed-format/test.mjs b/mixed-format/test.mjs new file mode 100644 index 0000000..616dc86 --- /dev/null +++ b/mixed-format/test.mjs @@ -0,0 +1,8 @@ +import assert from 'node:assert'; + +import { foo } from './fixture/esm.js'; +import { qux } from './fixture/cjs.js'; + + +assert.strictEqual(foo, 'bar'); +assert.strictEqual(qux, 'zed'); From ec656c6afca583cdac69f6d0951b8073d339137f Mon Sep 17 00:00:00 2001 From: Jacob Smith <3012099+JakobJingleheimer@users.noreply.github.com> Date: Thu, 25 Aug 2022 17:57:12 +0200 Subject: [PATCH 2/3] add nested cjs via require --- mixed-format/fixture/cjs.js | 2 +- mixed-format/fixture/cjs2.js | 1 + mixed-format/loader.mjs | 22 ++++++++++++++++------ 3 files changed, 18 insertions(+), 7 deletions(-) create mode 100644 mixed-format/fixture/cjs2.js diff --git a/mixed-format/fixture/cjs.js b/mixed-format/fixture/cjs.js index deb8531..b7d3583 100644 --- a/mixed-format/fixture/cjs.js +++ b/mixed-format/fixture/cjs.js @@ -1 +1 @@ -exports.qux = 'zed'; +exports.qux = require('./cjs2.js'); diff --git a/mixed-format/fixture/cjs2.js b/mixed-format/fixture/cjs2.js new file mode 100644 index 0000000..732f419 --- /dev/null +++ b/mixed-format/fixture/cjs2.js @@ -0,0 +1 @@ +module.exports = 'zed'; diff --git a/mixed-format/loader.mjs b/mixed-format/loader.mjs index aa38eaa..cac97f8 100644 --- a/mixed-format/loader.mjs +++ b/mixed-format/loader.mjs @@ -3,21 +3,31 @@ export async function load(url, context, nextLoad) { const nextResult = await nextLoad(url, { ...context, format: 'module' }) .then((result) => { - if (`${result.source}`.match(/exports[\. =]/)) throw new Error('Module is commonjs'); + if (containsCJS(result.source)) { throw new Error('CommonJS'); } return result; }) .catch(async (err) => { if ( (err?.message.includes('require') && err.includes('import')) - || err?.message.includes('commonjs') - ) return { - format: 'commonjs', - source: (await nextLoad(url, {...context, format: 'commonjs' })).source, - }; + || err?.message.includes('CommonJS') + ) { + return { format: 'commonjs' }; + } throw err; }); return nextResult; } + +function containsCJS(source) { + const src = '' + source; + + if (src.match(/exports[\.( ?=)]/)) return true; + + if ( + src.match(/require\(/) + && !src.match(/createRequire\(/) + ) return true; +} From 86ef7ce083914980817c33b1ca81dd7db9d6e958 Mon Sep 17 00:00:00 2001 From: Jacob Smith <3012099+JakobJingleheimer@users.noreply.github.com> Date: Wed, 31 Aug 2022 12:18:18 +0200 Subject: [PATCH 3/3] Update mixed-format/loader.mjs Co-authored-by: Geoffrey Booth <456802+GeoffreyBooth@users.noreply.github.com> --- mixed-format/loader.mjs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/mixed-format/loader.mjs b/mixed-format/loader.mjs index cac97f8..afb903a 100644 --- a/mixed-format/loader.mjs +++ b/mixed-format/loader.mjs @@ -24,7 +24,8 @@ export async function load(url, context, nextLoad) { function containsCJS(source) { const src = '' + source; - if (src.match(/exports[\.( ?=)]/)) return true; + // A realistic version of this loader would use a parser like Acorn to check for actual `module.exports` syntax + if (src.match(/exports[\.( ?=)]/)) { return true }; if ( src.match(/require\(/)