Skip to content

Source maps for ES modules have wrong offsets after conversion to AMD #1214

@nenadvicentic

Description

@nenadvicentic

Issue

Since Aurelia CLI defaults to AMD modules, it converts ES modules to AMD format during bundling process. However, it never updates source map for converted file. This creates random offsets in the source map and issues when debugging in the browser (cannot put breakpoint to a line we want, local variables not being read correctly, etc...)

The code that creates the issue is here:

try {
contents = esTransform(modulePath, this.contents);
} catch (e) {
logger.error('Could not convert to AMD module, skipping ' + modulePath);
logger.error('Error was: ' + e);
contents = this.contents;
}

Original source map of the file is not taken in cosideration

Expected behavior

Pass current source map of the file to the transform, since underlying Babel's transform function accepts inputSourceMap parameter:

const transformSync = require('@babel/core').transformSync;

/**
 * Use babel to translate native es module into AMD module
 * @param {string} fileName 
 * @param {string} fileContents 
 * @param {object | boolean} inputSourceMap 
 * @returns {{ code: string, map: string, ast: any }}
 */
module.exports = function es(fileName, fileContents, inputSourceMap) {
  return transformSync(fileContents, {
    babelrc: false,
    plugins: [['@babel/plugin-transform-modules-amd', {loose: true}]],
    inputSourceMap: inputSourceMap
  });
};

transformSync is going to return updated both transformed code and updated source map.

Code in the bundled-source.js would become:

// file is not in amd/cjs format, try native es module
try {
  /** @type {{} | boolean} */
  let inputSourceMap = false;
  if (this.file.sourceMap) {
    inputSourceMap = typeof this.file.sourceMap === 'string' ? JSON.parse(this.file.sourceMap) : this.file.sourceMap;
  }
  const result = esTransform(modulePath, this.contents, inputSourceMap);

  contents = result.code;
  if (result.map) {
    this.file.sourceMap = result.map; // save updated source map
  }
} catch (e) {
  logger.error('Could not convert to AMD module, skipping ' + modulePath);
  logger.error('Error was: ' + e);
  contents = this.contents;
}

Note

In order to apply this change to the source maps in an existing web project aurelia.json would have to be temporary modified, to stop using cache:

{
  "build: {
    "options: {
      "cache": false
    }
  }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions