Support bundlers (esbuild, webpack) without requiring internal module swaps for WASM loading
Problem
When bundling source-map with esbuild (platform: node), the WASM loading breaks in production because:
read-wasm.js uses path.join(__dirname, "mappings.wasm") — but after bundling, __dirname points to the output directory, not node_modules/source-map/lib/
initialize() is a no-op in the Node version (read-wasm.js), so there's no way to provide the WASM from the consumer side without swapping to read-wasm-browser.js via a bundler resolve plugin
- The
"browser" field in package.json maps read-wasm.js → read-wasm-browser.js, but esbuild with platform: node (correctly) ignores browser fields
This forces users to either:
- Copy
mappings.wasm to their output directory with the exact filename (fragile, undocumented contract)
- Use a resolve plugin to swap
read-wasm.js → read-wasm-browser.js and manually call initialize() (depends on internal file paths)
Proposal
Make initialize() work regardless of platform — if the user provides WASM via initialize(), use it; otherwise fall back to the fs.readFile(__dirname) approach. This is essentially making the Node read-wasm.js behave like:
let initialized = null;
module.exports = function readWasm() {
if (initialized) return Promise.resolve(initialized);
// existing fs.readFile fallback
return new Promise((resolve, reject) => {
const wasmPath = path.join(__dirname, "mappings.wasm");
fs.readFile(wasmPath, null, (error, data) => {
if (error) reject(error);
else resolve(data.buffer);
});
});
};
module.exports.initialize = function (input) {
initialized = input;
};
This way bundler users can call SourceMapConsumer.initialize({"lib/mappings.wasm": wasmBuffer}) on Node without needing to swap modules.
Alternatives considered
- Exporting
mappings.wasm via package.json "exports" so bundlers can resolve it cleanly
- Shipping a pre-built JS fallback (like
source-map-js does — no WASM at all)
Environment
- source-map 0.7.6
- esbuild 0.28.x, platform: node, format: esm
- Node.js 24.x
- Deploying to Docker (only
dist/ is copied — no node_modules)
Support bundlers (esbuild, webpack) without requiring internal module swaps for WASM loading
Problem
When bundling
source-mapwith esbuild (platform: node), the WASM loading breaks in production because:read-wasm.jsusespath.join(__dirname, "mappings.wasm")— but after bundling,__dirnamepoints to the output directory, notnode_modules/source-map/lib/initialize()is a no-op in the Node version (read-wasm.js), so there's no way to provide the WASM from the consumer side without swapping toread-wasm-browser.jsvia a bundler resolve plugin"browser"field inpackage.jsonmapsread-wasm.js→read-wasm-browser.js, but esbuild withplatform: node(correctly) ignores browser fieldsThis forces users to either:
mappings.wasmto their output directory with the exact filename (fragile, undocumented contract)read-wasm.js→read-wasm-browser.jsand manually callinitialize()(depends on internal file paths)Proposal
Make
initialize()work regardless of platform — if the user provides WASM viainitialize(), use it; otherwise fall back to thefs.readFile(__dirname)approach. This is essentially making the Noderead-wasm.jsbehave like:This way bundler users can call
SourceMapConsumer.initialize({"lib/mappings.wasm": wasmBuffer})on Node without needing to swap modules.Alternatives considered
mappings.wasmvia package.json"exports"so bundlers can resolve it cleanlysource-map-jsdoes — no WASM at all)Environment
dist/is copied — nonode_modules)