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

TypeScript transformers don't bind imports added during a transformation #38077

Closed
itsdouges opened this issue Apr 20, 2020 · 2 comments
Closed
Assignees
Labels
Working as Intended The behavior described is the intended behavior; this is not a bug

Comments

@itsdouges
Copy link

itsdouges commented Apr 20, 2020

TypeScript Version: 3.7.x-dev.201xxxxx

Search Terms:

Code

https://github.com/atlassian-labs/compiled-css-in-js

Expected behavior:

  • Usage of imports get renamed when targetting CJS modules
  • Imports do not get removed when they are used

Actual behavior:

Playground Link:

Related Issues:

I have no idea how the auto react import will work without this being fixed.

@RyanCavanaugh RyanCavanaugh added the Needs Investigation This issue needs a team member to investigate its status. label Apr 22, 2020
@RyanCavanaugh RyanCavanaugh added this to the TypeScript 4.0 milestone Apr 22, 2020
@rbuckton
Copy link
Member

There are some features of the compiler you can employ to produce the same generated name for the react import. The name react_1 is a special GeneratedIdentifier node and isn't value isn't known until after transforms are run and emit occurs. You can create a GeneratedIdentifier for a specific node using getGeneratedNameForNode, which will always generate the same name for the same node. The CommonJS transformer uses that behavior for the module name for a default import:

// import d from "mod";
// import { x, y } from "mod";
// import d, { x, y } from "mod";
// import d, * as n from "mod";
variables.push(
factory.createVariableDeclaration(
factory.getGeneratedNameForNode(node),
/*exclamationToken*/ undefined,
/*type*/ undefined,
getHelperExpressionForImport(node, createRequireCall(node))
)
);

You can use the same behavior to get the generated name for the react import node in your own code, given the current transformation's input SourceFile:

  1. Get the original parse-tree SourceFile using getParseTreeNode(file). This will give you the SourceFile as originally parsed before any transformations have been applied.
  2. Search statements of the original SourceFile to find an ImportDeclaration for "react".
  3. Use getGeneratedNameForNode(node) on the ImportDeclaration.

This will give you a GeneratedIdentifier corresponding to the ImportDeclaration that will produce the same identifier value that the CommonJS transform uses.

@rbuckton
Copy link
Member

To clarify, this isn't a bug in the compiler, but rather is due to the nature of how the transforms work. Binding and type-checking occur before any transformations are evaluated and transformed nodes are never re-bound.

@rbuckton rbuckton added Working as Intended The behavior described is the intended behavior; this is not a bug and removed Needs Investigation This issue needs a team member to investigate its status. labels Jun 30, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Working as Intended The behavior described is the intended behavior; this is not a bug
Projects
None yet
Development

No branches or pull requests

3 participants