Preact: Using named imports results in "Uncaught ReferenceError: h is not defined"

Created on 17 Nov 2018  路  9Comments  路  Source: preactjs/preact

I'm currently trying to setup a project with Preact, Typescript and Babel7/webpack. When I import preact members explicitly, as stated in the documentation, I get an Uncaught ReferenceError at runtime. I can work around this issue by importing via namespace, but that doesn't feel right.

import { h, render } from "preact";

// This actually works as expected from the code above
// import * as preact from "preact";
// const { h, render } = preact;

// Uncaught ReferenceError: h is not defined
render(<h1>Hello, preact!</h1>, document.body);

Corresponding webpack.config.js:

const path = require("path");
const CleanWebpackPlugin = require("clean-webpack-plugin");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const OUTPUT_DIR = "dist";

module.exports = {
  entry: "./src/index.tsx",
  output: {
    filename: "main.js",
    path: path.resolve(__dirname, OUTPUT_DIR)
  },
  module: {
    rules: [
      {
        test: /\.tsx?$/,
        exclude: /node_modules/,
        use: {
          loader: "babel-loader",
          options: {
            presets: ["@babel/env", "@babel/typescript"],
            plugins: [["@babel/transform-react-jsx", { pragma: "h" }]]
          }
        }
      }
    ]
  },
  resolve: {
    extensions: [".ts", ".tsx", ".json"]
  },
  plugins: [
    new CleanWebpackPlugin([OUTPUT_DIR]),
    new HtmlWebpackPlugin({
      template: "./public/index.html"
    })
  ],
  devtool: "eval-source-map"
};

Most helpful comment

@codecab Thanks for the repo link, that made reproducing this issue much easier馃憤

It turns out that the error is thrown by @babel/typescript, which is applied before @babel/transform-react-jsx. Adding the pragma to @babel/typescript fixes this issue.

{
  presets: [
    "@babel/env",
    ["@babel/typescript", { jsxPragma: "h" }], // Add jsxPragma here
  ],
  plugins: [
    ["@babel/transform-react-jsx", { pragma: "h" }]
  ],
}

All 9 comments

@codecab That's strange. I'd love to have a go at this. Can you share the repo, because otherwise I'd have to spend time just to create the package.json from scratch.

@marvinhagemeister nice! Of course, here you go: https://github.com/codecab/play-preact-typescript

I think it is necessary to change @babel/transform-react-jsx to @babel/plugin-transform-react-jsx.

Using a shorthand name when referencing packages/plugins is supported in Babel 7. Also, the error states that h() is missing, which hints that JSX transformation is happening with the correct pragma. Tried using the full package name nonetheless, but the behavior didn't change.

@codecab Thanks for the repo link, that made reproducing this issue much easier馃憤

It turns out that the error is thrown by @babel/typescript, which is applied before @babel/transform-react-jsx. Adding the pragma to @babel/typescript fixes this issue.

{
  presets: [
    "@babel/env",
    ["@babel/typescript", { jsxPragma: "h" }], // Add jsxPragma here
  ],
  plugins: [
    ["@babel/transform-react-jsx", { pragma: "h" }]
  ],
}

My understanding is that plugin-transform-typescript remove the h import because it doesn't see it as used. The jsxPragma: "h" option prevents this. The logic can be seen here.
I guess plugin-transform-typescript doesn't see h as used because it only sees jsx.

Thank you @marvinhagemeister! I have been stuck on this for hours!
I too was missing { jsxPragma: "h" } off of my @babel/typescript preset.

Has anyone been able to resolve this using Parcel? Seems to still throw this error regardless of my babel config changes. Thanks!

Has anyone been able to resolve this using Parcel? Seems to still throw this error regardless of my babel config changes. Thanks!

@iamclaytonray I was having this issue, adding a tsconfig.json like the one here seemed to work, even in the absence of a .babelrc: https://github.com/parcel-bundler/examples/tree/master/typescript-preact

Was this page helpful?
0 / 5 - 0 ratings

Related issues

mizchi picture mizchi  路  3Comments

matthewmueller picture matthewmueller  路  3Comments

nopantsmonkey picture nopantsmonkey  路  3Comments

matuscongrady picture matuscongrady  路  3Comments

rajaraodv picture rajaraodv  路  3Comments