Skip to content

allow wasm to be bundled #527

@mbrevda

Description

@mbrevda

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:

  1. read-wasm.js uses path.join(__dirname, "mappings.wasm") — but after bundling, __dirname points to the output directory, not node_modules/source-map/lib/
  2. 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
  3. The "browser" field in package.json maps read-wasm.jsread-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.jsread-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)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions