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 namespaced object export when default is the only one available #4058

Merged
merged 11 commits into from
Nov 15, 2024

Conversation

ankur22
Copy link
Contributor

@ankur22 ankur22 commented Nov 14, 2024

What?

This fixes an issue where a module only expose a default object, but we also want to allow the the module to be imported as a namespaced object.

Why?

This is how node works, and this is how we have chosen to work even after the changes to work with ESM from commonJS. It prevents breaking changes with older scripts that were not intended.

Checklist

  • I have performed a self-review of my code.
  • I have added tests for my changes.
  • I have run linter locally (make lint) and all checks pass.
  • I have run tests locally (make tests) and all tests pass.
  • I have commented on my code, particularly in hard-to-understand areas.

Related PR(s)/Issue(s)

Related: #4050

This allows us to work with a more go way of working with conditional
branching.
If no named exports are available, we want to try and convert the
default export to named exports. This allows users to work with
namespaced objects even through the module hasn't been setup to work in
that way. This is how node works too.
@ankur22 ankur22 requested a review from a team as a code owner November 14, 2024 10:03
@ankur22 ankur22 requested review from inancgumus, joanlopez and mstoykov and removed request for a team November 14, 2024 10:03
Copy link
Contributor

@mstoykov mstoykov left a comment

Choose a reason for hiding this comment

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

LGTM in general - i have a couple of comments mostly on old issues

js/modules/gomodule.go Outdated Show resolved Hide resolved
js/module_loading_test.go Outdated Show resolved Hide resolved
js/modules/gomodule.go Outdated Show resolved Hide resolved
js/modules/gomodule.go Outdated Show resolved Hide resolved
gm.exportedNames = make([]string, len(named))
for name := range named {
gm.exportedNames = append(gm.exportedNames, name)
switch {
Copy link
Contributor

Choose a reason for hiding this comment

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

I expect you used switch as there were more than one cases earlier?

Copy link
Contributor Author

@ankur22 ankur22 Nov 14, 2024

Choose a reason for hiding this comment

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

I refactored it since i think it's easier to follow when there are more than one conditions in the same function, instead of a if/else/else if etc. I also believe it's more go like to work with switch instead of if/else/else if.

Copy link
Contributor

Choose a reason for hiding this comment

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

I do consider it go like in the cases where:

  1. it can't be rewritten as a signel if/else pair - this can
  2. or when using a case can be used to check a single variable against multiple values and that is the only thing happening:
s := "apple";
switch s{
case "cucumber", "pepper", "leek":
  return "vegetable";
default:
  return "not vegetable"
}

As in both of this case it makes it easier to read. I would argue that using a switch in other cases makes me think there is something strange going on.

I will let other people also look at this and see what they think on it - so this is not a request for a change at this point, but a nit.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah, happy to hear more feedback, before merging/reverting the switch change.

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've reverted it back to if/else in 37a78c6

This is to stay consistent with other areas of the codebase
(e.g. toESModuleExports). There could be a valid case where we want
named to be an empty slice and default be non-nil, and not use this
feature to convert from default to namespace exports.
It needs to be of length 0 to allow for append from 0.
This is a better and safer way to work with an interface{} type when we
need to retrieve the property values from the object. Since the
underlying type of Default could be anything, including a sobek.Value,
it's better to retrieve it as a sobek.Object instead of a casting.
This will allow us to create other tests under the StarImport domain.
mstoykov
mstoykov previously approved these changes Nov 14, 2024
inancgumus
inancgumus previously approved these changes Nov 14, 2024
Copy link
Member

@inancgumus inancgumus left a comment

Choose a reason for hiding this comment

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

LGTM 👍 Nice fix.

@ankur22 ankur22 dismissed stale reviews from inancgumus and mstoykov via 37a78c6 November 15, 2024 09:57
@ankur22 ankur22 merged commit ddc3b0b into master Nov 15, 2024
23 checks passed
@ankur22 ankur22 deleted the fix/default-to-namespace-object branch November 15, 2024 14:02
@mstoykov mstoykov added this to the v0.56.0 milestone Nov 29, 2024
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.

3 participants