Skip to content

Conversation

sandersn
Copy link
Member

Note that this uses lookupSymbolForNameWorker, which is really abest-effort check since it only knows about symbols that it has already encountered.

As a side-effect, even when module is bound as part of a module.exports reference, it only declares it once instead of one declaration per reference.

Fixes user baseline regression in webpack as found in #25866.

Note that this uses `lookupSymbolForNameWorker`, which is really a
best-effort check since it only knows about symbols that it has already
encountered.

As a side-effect, even when `module` is bound as part of a
`module.exports` reference, it only declares it once instead of one
declaration per reference.
@weswigham
Copy link
Member

@sandersn can you also add a test with

function exec() {
    const module = new C(12);
    return () => {
        return module.exports; // should be fine because `module` is defined locally
    }
}

I don't think lookupSymbolForNameWorker is sufficient here.

It is an error inside script files, but the binder sometimes creates a
ModuleExports symbol because we doesn't know whether we have a commonjs
module until after binding is done.
@sandersn
Copy link
Member Author

Nice test -- that exposed a crash that happens because we erroneously create a symbol with ModuleExports on it in a script file. Since script files, unlike module files, don't have a symbol, the checker is unable to create the synthetic type for module: { exports: import("~/src/my/filename") }.

The binder doesn't know ahead of time whether it is in a commonjs module or not -- that property is calculated lazily inside the binder, so I just added a check in the checker.

>12 : 12

return () => {
>() => { return module.exports; } : () => any
Copy link
Member

Choose a reason for hiding this comment

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

This return type is wrong. AFAIK, module.exports here should be a number[].

sandersn added 2 commits July 24, 2018 14:35
Note that this, too, is a best-effort check since evidence of
commonjs-ness may be found after a *reference* to module.exports. (A
reference to module.exports alone is not enough evidence that a file is
commonjs. It has to have an assignment to it.)
@sandersn
Copy link
Member Author

OK, I made the binder more conservative about creating a symbol for module.exports. See the commit notes for details.

@sandersn sandersn merged commit 4d84bde into master Jul 30, 2018
@sandersn sandersn deleted the js/only-bind-module-exports-if-no-local-definition-exists branch July 30, 2018 19:28
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