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

Fix sourcemaps failing on refresh #1755

Merged
merged 2 commits into from Jul 22, 2018
Merged

Fix sourcemaps failing on refresh #1755

merged 2 commits into from Jul 22, 2018

Conversation

DeMoorJasper
Copy link
Member

@DeMoorJasper DeMoorJasper commented Jul 18, 2018

Sourcemaps inside assets were being overwritten due to not cloning the actual mappings array before merging and manipulating them inside the packager. Which caused the sourcemaps to get their position + bundle offset, resulting in incorrect mappings

Closes #997

@DeMoorJasper DeMoorJasper changed the title Fix sourcemaps failing on HMR Fix sourcemaps failing on reload Jul 18, 2018
@DeMoorJasper DeMoorJasper changed the title Fix sourcemaps failing on reload Fix sourcemaps failing on refresh Jul 18, 2018
src/SourceMap.js Outdated
@@ -38,6 +39,8 @@ class SourceMap {
}

async addMap(map, lineOffset = 0, columnOffset = 0) {
map = clone(map);
Copy link
Member

Choose a reason for hiding this comment

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

what kind of perf impact does this have? is there a specific situation where we need to clone, or just all the time?

Copy link
Member Author

Choose a reason for hiding this comment

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

We could probably move it to before line 62, as the actual reuse of mappings happens on the lines after that as far as I know. I haven't tested moving it, but it should work in theory

Copy link
Member Author

Choose a reason for hiding this comment

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

I'm not able to compare performance as I don't really have a project which is big enough to notice a difference

@devongovett
Copy link
Member

where do we mutate the mappings?

@devongovett
Copy link
Member

Tested perf on a larger app, and it was noticeable - about 5 seconds slower build time. Changed it to manually clone each mapping, and this reduced the time to about the same again.

@devongovett devongovett merged commit 569b60a into master Jul 22, 2018
@devongovett devongovett deleted the fix/sourcemap-dev branch July 22, 2018 00:39
@DeMoorJasper
Copy link
Member Author

Awesome, thanks for testing it out :)

};

this.mappings.push(mapping);
this.mappings.push({

Choose a reason for hiding this comment

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

Not familiar with this API, but does this mapping have a .name? I see it used in addConsumerMapping, but not this one.

Copy link
Member Author

Choose a reason for hiding this comment

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

Ow it should, thanks for noticing

line: mapping.generated.line + lineOffset,
column: mapping.generated.column + columnOffset
}
});
}

addConsumerMapping(mapping, lineOffset = 0, columnOffset = 0) {
Copy link

Choose a reason for hiding this comment

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

FYI, the handling below here seems questionable. Mappings with no original location are still important because they terminate the end of a conceptual range over the generated file by saying that a generated location points at nothing. By discarding mappings with no original location, you're essentially force-extending every generated mapping to instead extend to the end of the line/next original-location mapping.

Copy link
Member Author

Choose a reason for hiding this comment

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

Not sure why this would be an issue, if code is generated it shouldn't have a mapping right?

Choose a reason for hiding this comment

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

Not quite. Sourcemaps are conceptually ranges over the generated code, but the actual mappings passed from the consumer are single points of data, from one generated line/col to an original line/col (optionally).

It's the fact that the original part is option that is critical here, and that is getting lost with the check in

     if (
       !mapping.source ||
       !mapping.originalLine ||
       (!mapping.originalColumn && mapping.originalColumn !== 0)
     ) {
       return;
     }

Imagine a generated piece of code like this:

console.log

If I want to map just the console to something in the original JS file, setting no original location on the .log part, I'd generate two mappings. One would say

{
  generated: {
    line: 0,
    column: 0,
  },
  original: {
    line: 0,
    column: 0,
  },
  source: "input.js",
  name: "console",
}

to say that the start of the word "console" (line 0, column 0) maps to the original file, also at line 0 column 0.

So far so good, but nothing sets an end position, so that mapping on its own would also apply to the .log part.

That's where non-source mappings come in. You'd also include a mapping as

{
  generated: {
    line: 0,
    column: 7,
  },
  original: null
  source: null,
  name: null,
}

to say that, starting at line 0, column 7, the code maps to nothing in the original file.

By discarding that information, you've essentially made the original line 0 column 0 mapping apply to the whole of console.log.

Copy link
Member Author

Choose a reason for hiding this comment

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

Ow I never saw that as an issue but I'll definitely look into it.
Now that you've explained it, I can see it could and will cause issues.

Thank you

Choose a reason for hiding this comment

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

No problem, I'm happy to answer any other sourcemap questions if you have them. Babel has had it's fair share of questionable mapping logic over the ears too.

@ghost
Copy link

ghost commented Sep 19, 2018

when is this supposed to be fixed? i need this and it still breaks in "parcel-bundler": "1.10.0-beta.1

@DeMoorJasper
Copy link
Member Author

DeMoorJasper commented Sep 19, 2018

@Makmm it should’ve been fixed.

Feel free to open an issue

Sent with GitHawk

devongovett pushed a commit that referenced this pull request Oct 15, 2018
devongovett pushed a commit that referenced this pull request Oct 15, 2018
@quantuminformation
Copy link

Still having this issue with new typescript project and fresh install of parcel

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants