GeezerVisonThe World Wide Web, restored to 800 pixels of glory. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Home|About|Gaming cabinet|Archives|How it works|Starter sites | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
GeezerVison is showing github.com — Add refactoring to convert CommonJS module to ES6 module · Pull Request #19916 · microsoft/TypeScript ConversationFixes #19719
Sorry, something went wrong. Uh oh!
There was an error while loading. Please reload this page. All reactions
ghost
requested a review
from Andrew Casey (amcasey)
ghost
force-pushed
the
convertToEsModule
branch
2 times, most recently
from
4118c0c to
517715a
Compare
ghost
force-pushed
the
convertToEsModule
branch
from
517715a to
a4b588d
Compare
Member
All reactions
Sorry, something went wrong. Uh oh!
There was an error while loading. Please reload this page.
Author
All reactions
Sorry, something went wrong. Uh oh!
There was an error while loading. Please reload this page.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Notes on all files but
Sorry, something went wrong. Uh oh!
There was an error while loading. Please reload this page. All reactions
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Copy-paste error?
Sorry, something went wrong. Uh oh!
There was an error while loading. Please reload this page. All reactions
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Presumably, there's no conflict between this
Sorry, something went wrong. Uh oh!
There was an error while loading. Please reload this page. All reactions
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Right, the
Sorry, something went wrong. Uh oh!
There was an error while loading. Please reload this page. All reactions
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Are imports supposed to go at the top?
Sorry, something went wrong. Uh oh!
There was an error while loading. Please reload this page. All reactions
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Some people lint for that style but it's not a language rule. In this case I think it makes sense to put the only use of
Sorry, something went wrong. Uh oh!
There was an error while loading. Please reload this page. All reactions
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This comment could be clearer about which
Sorry, something went wrong. Uh oh!
There was an error while loading. Please reload this page. All reactions
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Naively, I would have expected this to return an
Sorry, something went wrong. Uh oh!
There was an error while loading. Please reload this page. All reactions
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You can pass a function that only takes
Sorry, something went wrong. Uh oh!
There was an error while loading. Please reload this page. All reactions
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍
Sorry, something went wrong. Uh oh!
There was an error while loading. Please reload this page. All reactions
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should this be an explicit check for
Sorry, something went wrong. Uh oh!
There was an error while loading. Please reload this page. All reactions
Andrew Casey (amcasey)
approved these changes
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Seems reasonable, but I don't understand it deeply.
Sorry, something went wrong. Uh oh!
There was an error while loading. Please reload this page. All reactions
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Typo "conver to"
Sorry, something went wrong. Uh oh!
There was an error while loading. Please reload this page. All reactions
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Sorry, something went wrong. Uh oh!
There was an error while loading. Please reload this page. All reactions
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Out of curiosity, why alias boolean like this?
Sorry, something went wrong. Uh oh!
There was an error while loading. Please reload this page. All reactions
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So I don't have to keep documenting what the return value means --
Sorry, something went wrong. Uh oh!
There was an error while loading. Please reload this page. All reactions
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think the refactoring context might contain a newline character.
Sorry, something went wrong. Uh oh!
There was an error while loading. Please reload this page. All reactions
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure I understand what work remains to be done here.
Sorry, something went wrong. Uh oh!
There was an error while loading. Please reload this page. All reactions
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| case SyntaxKind.CallExpression: { | ||
| const call = parent as CallExpression; | ||
| if (isRequireCall(call, /*checkArgumentIsStringLiteral*/ false)) { | ||
| changes.replaceNode(importingFile, parent, createPropertyAccess(getSynthesizedDeepClone(call), "default")); |
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
I would have guessed there was a constant for "default" somewhere.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Doesn't look like it, "default" occurs 67 times in our code. You could make a separate PR for that.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
| case SyntaxKind.ClassExpression: | ||
| // `exports.C = class {}` --> `export class C {}` | ||
| return classExpressionToDeclaration(name, modifiers, exported as ClassExpression); | ||
| default: |
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Does this cover a reasonably short list of kinds? It would be nice if we could have the compiler notify us when a new case requires coverage.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Unfortunately Expression is a huge list of kinds. But only function/class expressions can be converted to declarations, all others should be left as expressions.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
| const { text, originalKeywordKind } = node.name; | ||
| if (!res.has(text) && (originalKeywordKind !== undefined && isNonContextualKeyword(originalKeywordKind) | ||
| || checker.resolveName(node.name.text, node, SymbolFlags.Value, /*includeGlobals*/ false))) { | ||
| res.set(text, makeUniqueName(`_${text}`, identifiers)); |
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Isn't it redundant to prepend an underscore?
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
text is a keyword name; it doesn't appear in the identifiers list, but still needs the underscore to avoid being a keyword. And then if there happens to be an identifier _class we need to change to __class.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
| nameNotFoundMessage: DiagnosticMessage, | ||
| nameArg: __String | Identifier, | ||
| isUse: boolean, | ||
| includeGlobals: boolean, |
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
seems wierd to have to opt-in resolving a global. i would expect this be the opposite, that you opt out-in to skip globals
Sorry, something went wrong.
There was an error while loading. Please reload this page.
| export default 0; | ||
|
|
||
| export * from "./b"; | ||
| export { default } from "./b";`, |
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
this seems wrong to me.. or at least having both exports seem wrong.. i think you either want one or the other.. and to a big extend it depends on what the shape of "./b" is. if "./b" does not have a default export, this statement is an error under ES6 semantics.
I would say we should do one or the other, i.e. always do export * from "./b" unless ",/b" has only one export that happens to be default (or export = for that matter).
Sorry, something went wrong.
There was an error while loading. Please reload this page.
| actionDescription: "Convert to ES6 module", | ||
| newContent: `import x from "x"; | ||
| const y = 0; | ||
| import { z } from "z";`, |
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
not sure i understand why this is { z } an not import _z from "z"; const {z} = _z;
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
If we had this:
const zNamespace = require("z"); zNamespace.z();
We would translate to this:
import { z } from "z"; z();
right?
Using a destructure in commonjs (const { z } = require("z");) behaves equivalently to the first example so I think we should upgrade it to es6 too.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
well it depends on what "z" is. if it is ES6 module, then it is fine. if it a cjs file, then it shoudl be import zNamspace from "z"; zNamespace.z().
2 questions:
"z" next, should we assume it is a default? or that it is a namespace?I think the important part here is for us to be consistent between import and export. either everything is a default, or everything is a namespace. let's grab Daniel Rosenwasser (@DanielRosenwasser) tomorrow and talk it out.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Talked with Daniel Rosenwasser (@DanielRosenwasser) and I think it's fine to use a named import regardless of the thing we're importing from. Daniel Rosenwasser (@DanielRosenwasser) mentioned that we could also choose to provide a second codefix that would always use default imports. But I think we should wait and see if anyone actually wants that, because I think most people will want named imports.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
| const [] = aB; | ||
| import A from "0a"; | ||
| const [] = A; | ||
| import _A from "1a"; |
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
ideally we would have all the import statements at the top and not interleaved with the statements
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Similar comment in #19916 (comment)
I don't think that would be easy to do as we are replacing all of the ... = require(...) statements in place -- we're not guaranteed that these will all be in a row at the top of the file anyway.
This case should be pretty rare though since it's unusual to destructure a module into an array.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
| refactorName: "Convert to ES6 module", | ||
| actionName: "Convert to ES6 module", | ||
| actionDescription: "Convert to ES6 module", | ||
| newContent: 'import { x, y as z } from "x";', |
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
same as my earlier comment, i thought this would be a default import.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
| refactorName: "Convert to ES6 module", | ||
| actionName: "Convert to ES6 module", | ||
| actionDescription: "Convert to ES6 module", | ||
| newContent: `import { y } from "x"; |
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
and this.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
fb282fb to
051c9c8
Compare
| } | ||
|
|
||
| function createLiteralFromNode(sourceNode: StringLiteral | NumericLiteral | Identifier): StringLiteral { | ||
| function createLiteralFromNode(sourceNode: StringLiteralLike | NumericLiteral | Identifier): StringLiteral { |
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
This isn't internal, but it uses StringLiteralLike. You can technically make an internal overload for it, or use NoSubstitutionTemplateLiteral
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
This isn't exported so it won't show up in the public API. API baseline tests would have told us if we tried to use an internal type in a public api.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
4989ae5 to
4df53c1
Compare
|
Daniel Rosenwasser (@DanielRosenwasser) Mohamed Hegazy (@mhegazy) Good to go? |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
Andy (Andrewkraft) (@Andy-MS) can you please refresh and merge. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
540706e to
53c9bf2
Compare
53c9bf2 to
d67ef00
Compare
There was an error while loading. Please reload this page.
Successfully merging this pull request may close these issues.
There was an error while loading. Please reload this page.