Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use remapping to remap minified sourcemap into source code #37238

Merged
merged 11 commits into from
Jan 6, 2022

Conversation

jridgewell
Copy link
Contributor

For some reason, Terser is using the already changed property names instead of the original names (which exist inside the babel sourcemap). Instead of letting Terser do the remapping, we'll use our remapping library to remap our minified output maps into real source code.

Copy link
Member

@samouri samouri left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given we believe this to be a terser bug, lets file an issue

build-system/tasks/helpers.js Outdated Show resolved Hide resolved
build-system/tasks/helpers.js Show resolved Hide resolved
@samouri
Copy link
Member

samouri commented Jan 5, 2022

Testing this out locally, and I don't think this solves the issue. After doing more digging, I think I know the culprit of incorrect identifiers.

  1. esbuild does not generate the names field: Support for sourcemap names evanw/esbuild#1296.
  2. terser then generates an incorrect names field .
  3. Our unminify code within the error-reporter-bot uses source-map.originalPositionFor which inspects the names field.

Potential fixes:

  1. Make error bot more resilient by inspecting the original source and taking substrings instead of names.
  2. Generate a correct names array in our build pipeline. To be clear, I still don't know why (2) is happening or why this PR doesn't fix it.

@samouri
Copy link
Member

samouri commented Jan 5, 2022

Discussed potential solution with @jridgewell.

Conclusion was to get each sourcemap separately. Then apply remapping to them all. Babel will produces 100s of sourcemaps, esbuild 1, and terser 1. Remapping can handle collating all of them.

We can remove this complication once esbuild supports outputting sourcemaps with names.

@amp-owners-bot
Copy link

amp-owners-bot bot commented Jan 6, 2022

Hey @erwinmombay! These files were changed:

build-system/babel-plugins/babel-plugin-transform-rename-privates/index.js

Hey @rsimha! These files were changed:

build-system/common/esbuild-babel.js
build-system/common/transform-cache.js

Copy link
Contributor Author

@jridgewell jridgewell left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ready for review.

return;
}
key.replaceWith(t.identifier(`${name}AMP_PRIVATE_`));
key.replaceWith(t.inherits(t.identifier(`${name}AMP_PRIVATE_`), node));
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When we replaced the node, it forgets what the original name is. We have to use t.inherits to pass the data from the original Identifier to the new Identifier.

transformPromise.then((contents) => fs.outputFile(filepath, contents));

const filepath = path.join(this.cacheDir, this.key_(hash));
transformPromise.then((contents) => fs.outputJson(filepath, contents));
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This changes TransformCache to use JSON so that we can persist both the transformed code and the sourcemap in the cache directory.

build-system/tasks/helpers.js Show resolved Hide resolved
Some build targets have directory parts in the `destFilename` as well as the `destDir`. We need the full dest directory path for remapping to work.
Copy link
Member

@samouri samouri left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice work! I tested the fix, and sourcemaps lgtm. I checked both the names field as well as manually looked at the mapping in a visualizer.

if (name.endsWith('_AMP_PRIVATE_')) {
return;
}

if (!name.endsWith('_')) {
if (!name.endsWith('_') || name === '__proto__') {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FMI: how did you find the proto bug? Also how isn't this breaking prod? I'm assuming we only set proto to null ever?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I saw it in the names list as __proto___AMP_PRIVATE_

/**
* Used to cache babel transforms done by esbuild.
* @const {TransformCache}
* @type {TransformCache<!CacheMessageDef>}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We no longer need the !, since TS assumes nonnullable (this isn't checked via closure)

Suggested change
* @type {TransformCache<!CacheMessageDef>}
* @type {TransformCache<CacheMessageDef>}

Copy link
Member

@samouri samouri Jan 6, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

one more thing! pretty sure you can add @readonly for variables meant to be const (docs)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Due to rebase issue, I'm going to fix this in a followup PR.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@readonly didn't actually work for me when I tested it out. Maybe only for class props

@jridgewell jridgewell merged commit 5f9e38d into ampproject:main Jan 6, 2022
@jridgewell jridgewell deleted the terser-sourcemap branch January 6, 2022 20:24
westonruter added a commit that referenced this pull request Jan 10, 2022
…nce-attr-to-hero-img

* 'main' of github.com:ampproject/amphtml: (525 commits)
  mathml storybook: supply missing component definition. (#37326)
  storybook: Iframe --> BentoIframe (#37327)
  🖍  [Story system layer] New ad badge (#37311)
  🐛 [amp story] Replay/next page button bug fix (#37316)
  🚀  [Story performance] Remove affiliate links (#37280)
  Compiler: Add amp-carousel-0.1 to the builder map (#37308)
  ⏪  [Story system layer] Audio icon disappears when story has background audio (#37314)
  🚀  [Story performance] Remove story access (#37281)
  Fix remapping esbuild output on Windows (#37312)
  🐛 adds in correct weight for amp-story-product-tag text (#37188)
  typechecking carousel: remove shame files (#37213)
  Use remapping to remap minified sourcemap into source code (#37238)
  SwG Release 0.1.22.199 (#37310)
  🐛 Adds microsoft-edge protocol (#34168)
  Sync for validator cpp engine and cpp htmlparser (#37292)
  ✨ amp-story-shopping Updated currency with product price and correct Localized currency (#37249)
  ✨[Smartadserver ad extension] Implement support for Fast Fetch (#36991)
  Remove client-side-experiments-config.json from this repo (#37304)
  🚮  Remove closure compiler logic from build-system. (#37296)
  🌐 Added RTL ordering i18n for amp story shopping tag (#37252)
  ...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants