From 5fc10ca4d6fdcfae9ebbebd9964be8ed5588a502 Mon Sep 17 00:00:00 2001 From: Hiroki Osame Date: Wed, 13 Dec 2023 14:53:19 +0900 Subject: [PATCH] module: load source maps in `commonjs` translator PR-URL: https://github.com/nodejs/node/pull/51033 Reviewed-By: Antoine du Hamel Reviewed-By: Geoffrey Booth Reviewed-By: Chengzhong Wu Reviewed-By: James M Snell --- 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 949dbab7f6ad6b..47906cff86a225 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 d5fee004392b44..8e616c0d517823 100644 --- a/test/es-module/test-esm-loader-hooks.mjs +++ b/test/es-module/test-esm-loader-hooks.mjs @@ -737,6 +737,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',