Skip to content

Conversation

@sandersn
Copy link
Member

@sandersn sandersn commented Feb 4, 2021

Previously, the module identifier in commonjs modules got a synthetic type with a single property exports. The exports property reused the file's symbol, which, for a module file, gives the correct exported properties.

However, the name of this symbol was still the filename of the file, not exports. This PR creates a synthetic symbol for exports by copying in a similar way to esModuleInterop's default symbol in resolveESModuleSymbol (although the intent there is to strip off signatures from the symbol).

It's not possible to use cloneSymbol because that function merges the symbols, altering the original to point to the new symbol.

Fixes #41764

Previously, the `module` identifier in commonjs modules got a synthetic
type with a single property `exports`. The exports property reused the
file's symbol, which, for a module file, gives the correct exported
properties.

However, the name of this symbol was still the filename of the file, not
`exports`. This PR creates a synthetic symbol for `exports` by copying
in a similar way to esModuleInterop's `default` symbol in
`resolveESModuleSymbol` (although the intent there is to strip off
signatures from the symbol).
@sandersn sandersn requested a review from weswigham February 4, 2021 23:42
@typescript-bot typescript-bot added the For Milestone Bug PRs that fix a bug with a specific milestone label Feb 4, 2021
@sandersn sandersn changed the title Commonjs module:create synthetic exports symbol Create synthetic exports symbol for commonjs module Feb 4, 2021
const fileSymbol = getSymbolOfNode(getSourceFileOfNode(symbol.valueDeclaration));
const result = createSymbol(fileSymbol.flags, "exports" as __String);
result.declarations = fileSymbol.declarations ? fileSymbol.declarations.slice() : [];
result.parent = fileSymbol.parent;
Copy link
Member

Choose a reason for hiding this comment

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

The parent should be reset to the module symbol in module.exports, no?

Comment on lines +8776 to +8777
if (fileSymbol.members) result.members = new Map(fileSymbol.members);
if (fileSymbol.exports) result.exports = new Map(fileSymbol.exports);
Copy link
Member

Choose a reason for hiding this comment

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

How much of a memory hit for big checkJs projects (that use module.exports) is this?

Copy link
Member Author

Choose a reason for hiding this comment

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

The only baseline we have for this is "does chrome-devtools-frontend run out of memory?". I'll run the user tests.

A priori, it shouldn't be gigantic; a file with 1000 exports will add 1000 map entries. The first page of google only returns an SO answer from a V8 developer, which points out that each entry has key,value and next pointers. So...is that 6000 bytes per large file? It's not too expensive, but on the other hand this is a mostly cosmetic feature. The exception is the bug that the PR fixes.

@sandersn
Copy link
Member Author

sandersn commented Feb 5, 2021

@typescript-bot user test this

@typescript-bot
Copy link
Collaborator

typescript-bot commented Feb 5, 2021

Heya @sandersn, I've started to run the parallelized community code test suite on this PR at 5289808. You can monitor the build here.

@typescript-bot
Copy link
Collaborator

The user suite test run you requested has finished and failed. I've opened a PR with the baseline diff from master.

@sandersn
Copy link
Member Author

sandersn commented Feb 5, 2021

User test baselines finished OK, so I think this is safe enough.
(It also found a couple instances of the pattern from the original bug.)

@sandersn sandersn merged commit aba932a into master Feb 5, 2021
@sandersn sandersn deleted the create-synthetic-exports-symbol-for-commonjs-module branch February 5, 2021 18:56
@microsoft microsoft locked as resolved and limited conversation to collaborators Oct 21, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

Author: Team For Milestone Bug PRs that fix a bug with a specific milestone

Projects

None yet

Development

Successfully merging this pull request may close these issues.

In JS, checking require.main === module causes the type of module to get messed up

5 participants