microsoft / microsoft/TypeScript
Support JSX transformations with custom jsxFactory
Nobody has claimed this yet.
- Dominant language
- Go
- Stars
- 111k
- Forks
- 14.3k
- Avg merge
- 2d 4h
- Merged PRs (30d)
- 132
Description
Search Terms
jsx, jsxFactory, transformer
Suggestion
Allow tapping into the JSX generation process to control React.createElement output format when using --jsxFactory.
Specific cases requested (e.g. #15217, #32619) would also benefit from a generalized solution.
Use Cases
Emit component children as thunks
Useful to reactive frameworks which attach dependency tracking via the JSX component hierarchy.
The internal createJsxFactoryExpression() call LHS is controlled using the --jsxFactory compiler option:
// jsx
<div>
<div>a</div>
<div>b</div>
</div>
// current emit (jsxFactory: "h")
h('div', null,
h('div', null, 'a'),
h('div', null, 'b')
)
This produces a nested React.createElement()/h() chain which evaluates eagerly.
With (still synchronous) thunks, frameworks can track each component dependency as they traverse the tree, for fine-grained change detection:
// thunks (needs transformer)
h('div', null, () => [
h('div', null, () => ['a']),
h('div', null, () => ['b'])
])
This requires recursively transforming the JSX emits to a signature of h() which accepts some args as a thunk.
I've written a hacky (#16607) transformer for this but had to extract most of the JSX-related internals from the TypeScript compiler, whereas making the change to createExpressionForJsxElement() is trivial:
const cs = argumentsList.slice(2);
const argThunk = ts.createArrowFunction(
[],
[],
[],
undefined,
undefined,
ts.createArrayLiteral(cs)
);
const thunkified = [...argumentsList.slice(0, 2), argThunk];
According to #34547, plans are already in motion to pass nested component args as arrays instead of varargs. Specifying the jsxFactory implies we are assuming control of the composition behavior; we should also control the function signature.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reading createJsxFactoryExpression() and createExpressionForJsxElement() in src/compiler/factory.ts, then review the related requirements in issues #15217, #32619, and #34547. Done means defining and implementing a generalized way to control JSX factory output, including nested component arguments, without relying on a private transformer.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript, typescript
- Domain
- compilers
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 25/100