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

Make namespace @@toStringTag "Module" non-enumerable #4378

Merged
merged 13 commits into from Mar 2, 2022

Conversation

dnalborczyk
Copy link
Contributor

@dnalborczyk dnalborczyk commented Jan 31, 2022

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

List any relevant issue numbers:
Resolves #4336

Description

Updated: This will make sure that the Symbol.toStringTag property of namespaces is non-enumerable, which has an effect on the behaviour of Object.assign and the object spread operator. This includes

  • internally created dynamic namespaces objects
  • static entry points
  • dynamic entry points

Moreover, this deprecates the output.namespaceToStringTag option in favour of output.generatedCode.symbols, which again is now automatically enabled for es2015 output.
The deprecation warning is hidden for now but will be shown after the next major Rollup version.

@lukastaegert
Copy link
Member

lukastaegert commented Jan 31, 2022

You got me confused here after the discussion in #4336: Is your ultimate goal to get rid of the output.namespaceToStringTag option and enable it by default (probably just causes overhead for nearly everyone)? Or change the default (breaking change)?

@lukastaegert
Copy link
Member

lukastaegert commented Jan 31, 2022

Though it would make sense to improve on #4336 (comment) , but this is not what you are testing (if there is anything to do #4336 (comment))

@dnalborczyk
Copy link
Contributor Author

Though it would make sense to improve on #4336 (comment) , but this is not what you are testing (if there is anything to do #4336 (comment))

oh, dang, you're right. I'll fix the test. should have revisited the issue. 😄

const { configurable, enumerable, value, writable } = Object.getOwnPropertyDescriptor(
ns,
Symbol.toStringTag
);
Copy link
Member

Choose a reason for hiding this comment

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

Why not explicitly check the Object.assign behaviour? Then this would also document why it is important and people do not need to Google it again.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

good idea, I'll add that to the test.

@dnalborczyk dnalborczyk changed the title test: namespace export should have @@toStringTag value "Module" #4336 test: namespace export should have @@toStringTag "Module" be non-enumerable #4336 Feb 4, 2022
@dnalborczyk
Copy link
Contributor Author

also changed the issue title.

@dnalborczyk
Copy link
Contributor Author

dnalborczyk commented Feb 4, 2022

Is your ultimate goal to get rid of the output.namespaceToStringTag option and enable it by default (probably just causes overhead for nearly everyone)?

@lukastaegert

yes, personally I would, here's to the why:

  • it's spec compliant, and rollup as far as I know, is known to be spec compliant. currently, rollup alters the behavior of the code.
  • the namespace object is most of the time tree-shaken away by rollup anyways, unless accessed dynamically.
  • I sincerely believe rollup has too many options (feature creep), specially when used in tandem with the official @rollup/plugins.
  • the above would be good reasons to retire and subsequently remove namespaceToStringTag. there's probably very few people gonna study all options, let alone understand what those even mean.
  • that would also mean less functionality to maintain

at the bare minimum I would make it default: true, same as the freeze option. but to tell you the truth, I would just remove both altogether. I don't see a point in having those options. granted, it might safe a few bytes.

Copy link
Contributor

@guybedford guybedford left a comment

Choose a reason for hiding this comment

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

Great, case, again, any plans for a fix? Happy to point to implementation paths if you're interested.

@lukastaegert
Copy link
Member

I have added a fix and also additional tests so that this also applies to tags added to entry points. I also decided to use this PR to deprecate namespaceToStringTag in favour of a new option output.generatedCode.symbols. The idea is that the only reason to not always add this is because it makes the code non ES5 compliant. output.generatedCode has an es2015 preset, so with this PR now, using this preset will automatically add the tags.
Will update the PR description by tomorrow.

@lukastaegert lukastaegert changed the title test: namespace export should have @@toStringTag "Module" be non-enumerable #4336 Make namespace @@toStringTag "Module" non-enumerable Mar 1, 2022
@codecov
Copy link

codecov bot commented Mar 2, 2022

Codecov Report

Merging #4378 (e2c395b) into master (11bd9d9) will increase coverage by 0.00%.
The diff coverage is 100.00%.

Impacted file tree graph

@@           Coverage Diff           @@
##           master    #4378   +/-   ##
=======================================
  Coverage   98.75%   98.75%           
=======================================
  Files         204      204           
  Lines        7299     7306    +7     
  Branches     2078     2079    +1     
=======================================
+ Hits         7208     7215    +7     
  Misses         33       33           
  Partials       58       58           
Impacted Files Coverage Δ
src/finalisers/amd.ts 100.00% <ø> (ø)
src/finalisers/cjs.ts 100.00% <ø> (ø)
src/finalisers/iife.ts 100.00% <ø> (ø)
src/finalisers/umd.ts 100.00% <ø> (ø)
src/utils/options/options.ts 100.00% <ø> (ø)
src/ast/variables/NamespaceVariable.ts 100.00% <100.00%> (ø)
src/finalisers/shared/getExportBlock.ts 100.00% <100.00%> (ø)
src/utils/interopHelpers.ts 100.00% <100.00%> (ø)
src/utils/options/normalizeOutputOptions.ts 100.00% <100.00%> (ø)

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 11bd9d9...e2c395b. Read the comment docs.

@guybedford
Copy link
Contributor

Can we support "treeshaking" for this tag itself? Eg if the namespace object is not globally exposed, to skip adding the symbol? Or do we not have comprehensive global exposure analysis to rely on here?

@guybedford
Copy link
Contributor

Ah of course, looks great, and the overhead of the symbol is negligible (especially when compared to former interop wrappers!).

@lukastaegert lukastaegert merged commit b74cb92 into rollup:master Mar 2, 2022
AbhiPrasad pushed a commit to getsentry/sentry-javascript that referenced this pull request Oct 27, 2022
…'` to CJS files (#6043)

As of version 2.69.0, setting `output.generatedCode` to `'es2015'` (as we do) causes Rollup to [add `[Symbol.toStringTag]: 'Module'` to generated CJS files](rollup/rollup#4378 (comment)). Though this is valid ES6, it causes Jest to be unable to mock our generated packages.

Though [a PR](jestjs/jest#13513) has been opened to fix this, the change almost certainly won't be backported, so anyone using Jest 29.2.2 or under will run into [this problem](#5994) if they try to mock `@sentry/xxx` 7.16. (The relevant change was introduced in #5951, when we (semi-)accidentally upgraded Rollup from 2.67.1 to 2.78.0, and was first included in version 7.16.) 

This PR prevents the new Rollup behavior, since it has no known benefit. (The [Rollup docs](https://rollupjs.org/guide/en/#outputgeneratedcode) say that presence of the `'Module'` toStringTag "is used for feature detection in certain libraries and frameworks," but not having it hasn't seemed to hurt us so far.)
@dnalborczyk dnalborczyk deleted the test/4336-to-string-tag branch December 17, 2022 04:39
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.

bug: @@toStringTag property undefined, should be 'Module'
3 participants