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"
};
@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
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/typescriptfixes this issue.