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

Support Custom JSX Pragma #9582

Closed
developit opened this issue Jul 9, 2016 · 22 comments
Closed

Support Custom JSX Pragma #9582

developit opened this issue Jul 9, 2016 · 22 comments
Labels
Fixed A PR has been merged for this issue Good First Issue Well scoped, documented and has the green light Help Wanted You can do this Suggestion An idea for TypeScript

Comments

@developit
Copy link

Hi. I've searched through the various issues (as well as other places this has been discussed) and I don't see a current open issue to address the lack of custom JSX pragma support.

As discussed elsewhere, other transpilers allow specifying any function name to insert when producing hyperscript from JSX. It's worth noting that hyperscript predates React, and is a format shared by a large number of libraries entirely separate from the React project. Currently, TypeScript only allows configuration of an Object on which to invoke .createElement(), however the original implementations and many descendants thereof simply use h(). You can read my attempt to document some of the context and background here.

The configuration would presumably look something like this:

{
    "compilerOptions": {
        "jsx": "react",
        "jsxPragma": "h"
    }
}

... and the output would look like:

// input:
<div id="foo">hello</div>

// output:
h('div', { id:'foo' }, 'hello');

Has this been bypassed for feasibility reasons? If not, I think it would be a valuable addition.

@WanderWang
Copy link

I have a different view

consider this proposal
Proposal: Replace emitter with syntax tree transformations and a simplified node emitter.

Your requirement can be implements via " custom syntax tree transformations " . So I don't think it's necessary for us to increase tsconfig 's complexity.

@PaulBGD
Copy link

PaulBGD commented Jul 9, 2016

And I think that's a great idea, however the tsconfig already has an option for JSX (that only supports React.) I don't see why we'd support just the first half of the function call.

@developit
Copy link
Author

@WanderWang this is very much a userland feature. Most users of TypeScript would not be compelled to extend TypeScript itself simply to account for a common use-case.

My suggestion could replace the existing "jsxNamespace" config property, since jsxPragma enables a superset of use-cases, while still allowing the default to remain "React.createElement".

Currently, TypeScript forces users to build shims for non-React JSX use-cases, which is significantly more cumbersome than needing to know about another (or a different) configuration property.

@basarat
Copy link
Contributor

basarat commented Jul 9, 2016

workaround:

import * as h from "someplace";
const hyper = {createElement: h}

@developit
Copy link
Author

@basarat yes, this is what people currently do. However, this is a second-class experience and difficult to explain in documentation.

@ghost
Copy link

ghost commented Jul 29, 2016

@basarat that is exactly that - a workaround. It seems that there should be a better way of doing this.

@ghost
Copy link

ghost commented Aug 4, 2016

No discussion, no nothing. Sad.

@bradleyayers
Copy link

My use-case is to support JSX within skate.js. skatejs has a hyperscript compliant API import { h } from 'skatejs';, so all that's missing is JSX pragma support or something equivalent.

@RyanCavanaugh RyanCavanaugh added the In Discussion Not yet reached consensus label Sep 23, 2016
@RyanCavanaugh RyanCavanaugh added Help Wanted You can do this and removed In Discussion Not yet reached consensus labels Sep 28, 2016
@RyanCavanaugh RyanCavanaugh added this to the Community milestone Sep 28, 2016
@RyanCavanaugh RyanCavanaugh added the Good First Issue Well scoped, documented and has the green light label Sep 28, 2016
@RyanCavanaugh
Copy link
Member

Accepting PRs for a flag jsxFactory which accepts a string, like "h" or "React.createElement"

  • No explicit validation of this parameter occurs; users are assumed to have provided a correct string
  • If this flag is specified, JSX elements in react emit mode no longer require the React identifier to be present
  • It is an error to specify both this and the "React namespace" setting

@developit
Copy link
Author

Sweet, someone submit a PR

@RyanCavanaugh
Copy link
Member

Be the PR you want to see in the world 😉

@developit
Copy link
Author

I would, but I've never used TypeScript and already have tons to maintain 😛

@bradleyayers
Copy link

I'll raise a PR.

@bradleyayers
Copy link

bradleyayers commented Sep 29, 2016

If this flag is specified, JSX elements in react emit mode no longer require the React identifier to be present.

In the case of // @jsxFactory: a, we should require the a identifier to be present right? Following on that // @jsxFactory: a.b would still require just a to be present.

I think we should require React to be present if jsxFactory: React.createElement is used.

I also need to look into how React.__spread should be dealt with. I hadn't realised that reactNamespace was also used to describe which object .__spread hangs off. nevermind .__spread is no longer used.

@mhegazy
Copy link
Contributor

mhegazy commented Sep 29, 2016

sounds reasonable.

@bradleyayers
Copy link

I've raised the PR — #11267.

@sheetalkamat sheetalkamat added the Fixed A PR has been merged for this issue label Nov 10, 2016
@mhegazy mhegazy modified the milestones: TypeScript 2.1.3, Community Nov 10, 2016
@tusharmath
Copy link

tusharmath commented Nov 12, 2016

For future readers —

{
    "compilerOptions": {
        "jsx": "react",
        "jsxFactory": "h"
    }
}

The above configuration will get you going.

@mhegazy
Copy link
Contributor

mhegazy commented Nov 12, 2016

Edit: updated the jsxFactory property name in comment above.

@tusharmath
Copy link

@mhegazy I get this error — Unknown compiler option 'jsxFactory'

tsc --version
Version 2.1.1

@mhegazy
Copy link
Contributor

mhegazy commented Nov 13, 2016

Use typescript@next.

@nojvek
Copy link
Contributor

nojvek commented Nov 14, 2016

This is awesome. Kudos for baking this as a compiler param.

@streamich
Copy link

streamich commented Oct 7, 2017

<div>Hello</div>

should compile to:

({h}) => h('div', {}, 'Hello');

and them React could do:

(({h}) => h('div', {}, 'Hello'))({
  h: React.createElement,
});

@microsoft microsoft locked and limited conversation to collaborators Jun 19, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Fixed A PR has been merged for this issue Good First Issue Well scoped, documented and has the green light Help Wanted You can do this Suggestion An idea for TypeScript
Projects
None yet
Development

No branches or pull requests