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(node-resolve): forward meta-information from other plugins #1062

Merged
merged 1 commit into from Dec 31, 2021

Conversation

lukastaegert
Copy link
Member

Rollup Plugin Name: node-resolve

This PR contains:

  • bugfix
  • feature
  • refactor
  • documentation
  • other

Are tests included?

  • yes (bugfixes and features will not be merged without tests)
  • no

Breaking Changes?

  • yes (breaking changes will not be merged unless absolutely necessary)
  • no

If yes, then include "BREAKING CHANGES:" in the first commit message body, followed by a description of what is breaking.

List any relevant issue numbers:
Resolves #1060

Description

While node-resolve was already calling other resolvers to allow them to mark modules as external, meta-information was ignored so far. This fix will make sure that all meta information added by other plugins is preserved (except moduleSideEffects that is).

Copy link
Member

@tjenkinson tjenkinson left a comment

Choose a reason for hiding this comment

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

Is the reason this fix is needed because the resolve id hooks are only ever called once?

So without the this.resolve the other resolve id hooks would be called from somewhere else, where the returned metadata was respected there?

]);
});

test.only('passes on custom options', async (t) => {
Copy link
Member

Choose a reason for hiding this comment

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

🙈

@lukastaegert
Copy link
Member Author

So without the this.resolve the other resolve id hooks would be called from somewhere else

Actually, they would not be called at all for plugins that are sorted after the node-resolve plugin, because, as you stated, resolution only happens once. We needed to add this.resolve here because it allowed people to mark ids as external that had been resolved by node-resolve. Another solution would have been to place the other plugin always before node-resolve, but these ordering-solutions are tricky. Yet another solution is for the plugin to use the options hook to add a secondary plugin that is placed first.
But as we decided to go for this solution, respecting the meta data added by other plugins besides the external flag seemed like a small step.
The only things that are NOT respected are the id and moduleSideEffects. moduleSideEffects is necessary, because node-resolve determines this value and we have no way to figure out if other plugins respected that value or not. The reason we also ignore id changes was linked for me: If I change the id, moduleSideEffects may be completely wrong as it was based on the position of the original module in the file system.

Copy link
Member

@tjenkinson tjenkinson left a comment

Choose a reason for hiding this comment

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

thanks for the explanation. I think you might have missed overriding the id based on what you said?

I'm not sure what the best answer is to my other comment. Not defaulting to passing all props through feels safer and more controlled, but maybe it's fine. You have a much better understanding of the API than I do :)

LGTM!

return false;
}
// Pass on meta information added by other plugins
return { ...resolvedResolved, moduleSideEffects: resolved.moduleSideEffects };
Copy link
Member

Choose a reason for hiding this comment

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

given what you said before

The only things that are NOT respected are the id and moduleSideEffects

shouldn't you be forcing resolved.id as the id here too?

Copy link
Member Author

Choose a reason for hiding this comment

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

No, that is what I was trying to say:

  • node-resolves figures out that /foo/foo.js has no side-effects based on some package.json file
  • another plugin changes the id to /bar.js, which is completely different.
    Then our value for moduleSideEffects is probably wrong or irrelevant.

That is why I thought to prohibit changing the id.

On the other hand, one could also check if the id has changed and only override the moduleSideEffects value if it is still the same id.

Copy link
Member

Choose a reason for hiding this comment

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

I mean

Suggested change
return { ...resolvedResolved, moduleSideEffects: resolved.moduleSideEffects };
return { ...resolvedResolved, id: resolved.id, moduleSideEffects: resolved.moduleSideEffects };

?

right now a change to bar.js would make it though and it shouldn’t?

Copy link
Member Author

Choose a reason for hiding this comment

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

Ah, then you are indeed right, should read my own code ^^
I will change it to just pick the meta property, that is probably best for now.

Copy link
Member Author

Choose a reason for hiding this comment

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

Done, please have another look

if (resolvedResolved.external) {
return false;
}
// Pass on meta information added by other plugins
Copy link
Member

Choose a reason for hiding this comment

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

I wonder if we should really just target property holding the metadata instead of allowing everything through by default except moduleSideEffects? Don't think we'd be doing any object merging then

Copy link
Member Author

Choose a reason for hiding this comment

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

Admittedly, the last remaining property is syntheticNamedExports. Which we may want to keep IF we also keep the id. So maybe a better solution is: Keep everything from the second resolve, but override moduleSideEffects if the id did not change?

@shellscape
Copy link
Collaborator

@lukastaegert @tjenkinson please give me a heads up on when you both are satisfied with the state of conversation, so I know when to merge this one.

Copy link
Member

@tjenkinson tjenkinson left a comment

Choose a reason for hiding this comment

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

Lgtm :shipit:

@shellscape shellscape merged commit 23226cd into master Dec 31, 2021
@shellscape shellscape deleted the node-resolve/forward-meta branch December 31, 2021 02:47
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.

node-resolve wipes out other plugins' meta data
3 participants