-
Notifications
You must be signed in to change notification settings - Fork 12.6k
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
Check for require when binding commonjs #50130
Conversation
Previously, the binder didn't check for a declared function named 'require' when binding require in JS. It unconditionally treated 'require' as the commonjs function, even when a local function named 'require' existed and even in ES modules. Now, the binder checks for a local function named require and avoids binding in that case. Both before and after, actually importing the module causes the checker to issue an error saying that top-level functions named 'require' are illegal. But this error doesn't show up until you've imported from the module, so you won't notice it in the editor, where JS errors are most useful. Within-binder checks for declared functions are dependent on binding order, but function binding simulates hoisting by binding all function declarations first, so it should be pretty reliable.
Note: The "'require' is reserved by the compiler" error has to do with emit, so it shouldn't be issued on any .js file. That's a separate issue though. Edit: Filed #50132 for this |
src/compiler/binder.ts
Outdated
@@ -3260,6 +3260,7 @@ namespace ts { | |||
if (isInJSFile(node) && | |||
isVariableDeclarationInitializedToBareOrAccessedRequire(possibleVariableDecl) && | |||
!getJSDocTypeTag(node) && | |||
!(lookupSymbolForName(container, "require" as __String)) && |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we should move this in enum as we are doing in below
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are you talking about an enum like ModifierFlags? require
isn't a modifier like public
et al, and I think if the binder gets this right, then the checker won't have to look up require
again. Even if it does, it'll only happen once more. I don't think it's worth caching.
Will this end up breaking code that relied on the fact that we treat a function named "require" specially? I know that yarn plugins are passed a require function as an argument (so you can require things lazily / get the same dep as the executing yarn version), and having |
Similar question to Jake’s: does this check affect ambient declarations? Both @types/node and @types/webpack-env declare |
@andrewbranch No: @jakebailey Yes: based on the test noCrashOnParameterNamedRequire. While technically correct, the assumption that ES modules would be less likely to have a I looked at a couple of yarn plugins but they were written in TS, and I didn't see any Two more things:
|
My example is in a private repo so I can't link it here, but here is the example from the yarn docs: https://yarnpkg.com/advanced/plugin-tutorial/#writing-our-first-plugin |
Closing this after various discussions. I think a warning against writing a function named |
Previously, the binder didn't check for a declared function named 'require' when binding require in JS. It unconditionally treated 'require' as the commonjs function, even when a local function named 'require' existed and even in ES modules. Now, the binder checks for a local function named require and avoids binding in that case.
Both before and after, actually importing the module causes the checker to issue an error saying that top-level functions named 'require' are illegal. But this error doesn't show up until you've imported from the module, so you won't notice it in the editor, where JS errors are most useful.
Within-binder checks for declared functions are dependent on binding order, but function binding simulates hoisting by binding all function declarations first, so it should be pretty reliable.
Fixes #48726