Skip to content

Support Custom JSX Pragma #9582

Closed
Closed

Description

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.

Activity

  1. WanderWang commented on Jul 9, 2016

    @WanderWang

    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.

  2. PaulBGD commented on Jul 9, 2016

    @PaulBGD

    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.

  3. developit commented on Jul 9, 2016

    @developit
    Author

    WanderWang (@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.

  4. basarat commented on Jul 9, 2016

    @basarat
    Contributor

    workaround:

    import * as h from "someplace";
    const hyper = {createElement: h}
  5. developit commented on Jul 10, 2016

    @developit
    Author

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

  6. bradleyayers commented on Sep 23, 2016

    @bradleyayers

    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.

  7. added this to the milestone on Sep 28, 2016
  8. RyanCavanaugh commented on Sep 28, 2016

    @RyanCavanaugh
    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
  9. 3 remaining items

  10. bradleyayers commented on Sep 29, 2016

    @bradleyayers

    I'll raise a PR.

  11. bradleyayers commented on Sep 29, 2016

    @bradleyayers

    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.

  12. mhegazy commented on Sep 29, 2016

    @mhegazy
    Contributor

    sounds reasonable.

  13. bradleyayers commented on Sep 29, 2016

    @bradleyayers

    I've raised the PR — #11267.

  14. modified the milestones: , on Nov 10, 2016
  15. tusharmath commented on Nov 12, 2016

    @tusharmath

    For future readers —

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

    The above configuration will get you going.

  16. mhegazy commented on Nov 12, 2016

    @mhegazy
    Contributor

    Edit: updated the jsxFactory property name in comment above.

  17. tusharmath commented on Nov 13, 2016

    @tusharmath

    Mohamed Hegazy (@mhegazy) I get this error — Unknown compiler option 'jsxFactory'

    tsc --version
    Version 2.1.1
    
  18. mhegazy commented on Nov 13, 2016

    @mhegazy
    Contributor

    Use typescript@next.

  19. nojvek commented on Nov 14, 2016

    @nojvek
    Contributor

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

  20. streamich commented on Oct 7, 2017

    @streamich
    <div>Hello</div>

    should compile to:

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

    and them React could do:

    (({h}) => h('div', {}, 'Hello'))({
      h: React.createElement,
    });
  21. locked and limited conversation to collaborators on Jun 19, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    FixedA PR has been merged for this issueGood First IssueWell scoped, documented and has the green lightHelp WantedYou can do thisSuggestionAn idea for TypeScript

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions