parcel: Typescript + Preact doesn't work right now

🐛 bug report

🎛 Configuration (.babelrc, package.json, cli command)

index.html

<html>

<head>
</head>

<body>
  <h2>hi</h2>
  <script src="./index.tsx"></script>
</body>

</html>

index.tsx

import { h, render } from 'preact'

render(<h2>hi</h2>, document.body)

Resulting in:

Uncaught ReferenceError: h is not defined

💁 Possible Solution

I’m pretty sure it’s related to missing "jsxFactory": "h", in the Typescript asset class: https://github.com/parcel-bundler/parcel/blob/master/src/assets/TypeScriptAsset.js#L16

The compiled output looks like this:

var preact_1 = require("preact");

preact_1.render(h(
  "h2",
  null,
  "hi"
), document.body);

You’ll notice that it’s just h(...), even though it should be preact_1.h(...)

🌍 Your Environment

Software Version(s)
Parcel 1.7.0
Node v8.10.0
npm/Yarn npm@5.6.0
Operating System osx

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Reactions: 5
  • Comments: 17 (3 by maintainers)

Most upvoted comments

Any updates here?

I ran into this issue and resolved it by changing "jsx": "preserve" to "jsx": "react" in my tsconfig.json

@matthewmueller

I had the same issue after upgrading preact from 10.2 to 10.3. I already had the above tsconfig.json and was rather stuck - but adding babel based from this: https://github.com/developit/babel-preset-preact worked! I just used env preset rather than es2015.

Mine worked just from changing my tsconfig.json from:

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

To:

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

Also import preact from 'preact' (using factory preact.h) doesn’t work anymore in Preact 10. So I changed to import { h, render } from 'preact'.

@FDiskas can you open a new issue with a code sample and the error you’re getting?

Same problem again - latest and greatest

"parcel": "^2.0.0-nightly.500",
"preact": "^10.5.8",

No extra babel files or settings. tsconfig.json

{
  "compilerOptions": {
    "esModuleInterop": true,
    "jsx": "react",
    "jsxFactory": "h",
    "lib": [
      "dom",
      "esnext"
    ],
    "module": "esnext",
    "moduleResolution": "node",
    "strict": true,
    "target": "es5"
  }
}

I changed my tsconfig.json to match the syntax of this repo here while also following the advice to add the jsx-loader to by .babelrc and have managed to get parcel to handle TSX and Preact at once. This probably isn’t too helpful, so I’ll make a repo to share my basic code.

I’m having the opposite problem: Parcel’s output refers to h when it should be using React.createElement. That’s because my preact code is pretending to be React code, just with imports changed:

import * as React from 'preact';
import * as ReactDOM from 'preact';

Adding /** jsx React.createElement */ to the top of file has no effect, so I’m using a workaround:

var h = React.createElement;