From 2f70bf302d24e79cd85f5850a12f7ef17f7cec35 Mon Sep 17 00:00:00 2001 From: Hiroki Osame Date: Wed, 6 Dec 2023 15:39:06 +0900 Subject: [PATCH] module: load source maps in `commonjs` translator --- lib/internal/modules/esm/translators.js | 2 ++ test/es-module/test-esm-loader-hooks.mjs | 33 ++++++++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/lib/internal/modules/esm/translators.js b/lib/internal/modules/esm/translators.js index 9976b819f266c6..bdbcd40740942d 100644 --- a/lib/internal/modules/esm/translators.js +++ b/lib/internal/modules/esm/translators.js @@ -289,6 +289,8 @@ function createCJSModuleWrap(url, source, isMain, loadCJS = loadCJSModule) { // In case the source was not provided by the `load` step, we need fetch it now. source = stringify(source ?? getSource(new URL(url)).source); + maybeCacheSourceMap(url, source); + const { exportNames, module } = cjsPreparseModuleExports(filename, source); cjsCache.set(url, module); const namesWithDefault = exportNames.has('default') ? diff --git a/test/es-module/test-esm-loader-hooks.mjs b/test/es-module/test-esm-loader-hooks.mjs index c7b8632bae3df8..6f035bccb87f5c 100644 --- a/test/es-module/test-esm-loader-hooks.mjs +++ b/test/es-module/test-esm-loader-hooks.mjs @@ -747,6 +747,39 @@ describe('Loader hooks', { concurrency: true }, () => { assert.strictEqual(signal, null); }); + it('should support source maps in commonjs translator', async () => { + const readFile = async () => {}; + const hook = ` + import { readFile } from 'node:fs/promises'; + export ${ + async function load(url, context, nextLoad) { + const resolved = await nextLoad(url, context); + if (context.format === 'commonjs') { + resolved.source = await readFile(new URL(url)); + } + return resolved; + } +}`; + + const { code, signal, stdout, stderr } = await spawnPromisified(execPath, [ + '--no-warnings', + '--enable-source-maps', + '--import', + `data:text/javascript,${encodeURIComponent(` + import{ register } from "node:module"; + register(${ + JSON.stringify('data:text/javascript,' + encodeURIComponent(hook)) +}); + `)}`, + fixtures.path('source-map/throw-on-require.js'), + ]); + + assert.strictEqual(stdout, ''); + assert.match(stderr, /throw-on-require\.ts:9:9/); + assert.strictEqual(code, 1); + assert.strictEqual(signal, null); + }); + it('should handle mixed of opt-in modules and non-opt-in ones', async () => { const { code, signal, stdout, stderr } = await spawnPromisified(execPath, [ '--no-warnings',