stencil icon indicating copy to clipboard operation
stencil copied to clipboard

bug: unable to use `jsxImportSource` for Stencil JSX types with newer versions of TypeScript.

Open trusktr opened this issue 11 months ago • 3 comments

Prerequisites

Stencil Version

4.26.0

Current Behavior

The @stencil/core package does not have a @stencil/core/jsx-runtime export path (or similar jsx-runtime path), making it not possible to use with TypeScript's jsxImportSource option.

Expected Behavior

Updated Stencil to work with newer TypeScript.

System Info

n/a

Steps to Reproduce

In any TypeScript project (doesn't matter if it is a React project, etc), try to put this at the top of a .tsx file to tell TypeScript to load JSX types for any JSX expressions from @stencil/core:

/* @jsxImportSource @stencil/core */

You'll get an error like

Cannot find module '@stencil/core/jsx-runtime' or its corresponding type declarations.

where /jsx-runtime is the conventional postfix that TypeScript appends to the path.

Code Reproduction URL

no URL yet

Additional Information

Without this feature, it is not possible to write Stencil components inside any other application that uses non-stencil JSX types.

The purpose of jsxImportSource is to allow for different files to use different JSX types. This makes it possible to, for example, compile certain files with one flavor of JSX (f.e. Solid.js JSX) and other files with Stencil JSX.

Solution

The fix is likely easy: just create an empty jsx-runtime.js file at the root of the package, along with a jsx-runtime.d.ts file at the root of the package that re-exports the JSX type.

trusktr avatar Mar 01 '25 09:03 trusktr

where /jsx-runtime is the conventional postfix that TypeScript appends to the path.

I think it shouldn't be difficult to add an additional export path to enable this. Contributions are welcome!

christian-bromann avatar Mar 01 '25 22:03 christian-bromann

I did a small exploration and I got types from jsx-runtime working locally.

Here's a patch to @stencil/core in my node_modules (which I've tracked locally using the nice patch-package package from npm that will apply patches to libraries on postinstall):

diff --git a/node_modules/@stencil/core/jsx-runtime.d.ts b/node_modules/@stencil/core/jsx-runtime.d.ts
new file mode 100644
index 0000000..aaa3332
--- /dev/null
+++ b/node_modules/@stencil/core/jsx-runtime.d.ts
@@ -0,0 +1 @@
+export type * from "./internal/index.js";
diff --git a/node_modules/@stencil/core/jsx-runtime.js b/node_modules/@stencil/core/jsx-runtime.js
new file mode 100644
index 0000000..afc2712
--- /dev/null
+++ b/node_modules/@stencil/core/jsx-runtime.js
@@ -0,0 +1,2 @@
+// No JSX runtime to export here, but jsx-runtime.d.ts exports JSX types.
+export {}

Or basically, I simply added these two files:

This is @stencil/core/jsx-runtime.js:

// No JSX runtime to export here, but jsx-runtime.d.ts exports JSX types.
export {}

This is @stencil/core/jsx-runtime.d.ts:

export type * from "./internal/index.js";

I am now able to use the @jsxImportSource comment successfully (or the equivalent option in tsconfig.json).

I only tested type definitions in my case, but I think that the jsx-runtime.js might need to also export h or something, in runtime is needed from there instead of "jsxFactory": "h" in tsconfig.json. Need more testing...

trusktr avatar Mar 02 '25 00:03 trusktr

I've made a repo where I've gotten a stencil app with jsxImportSource working, with a couple things left to iron out:

https://github.com/trusktr/stenciljs-core-issue-6181-jsxImportSource

Note this depends on an unpublished version of @lume/element, so it is not yet runnable on its own. I'll post back when it is.

In the meantime, to understand the needed changes and what is left to fix,

  • see the README.md
  • look at patches/@stencil+core+4.26.0.patch to see what I modified in node_modules/@stencil/core/
  • search for TODOs in both the project source, and inside node_modules/@stencil/core
  • search for console.assert in both the project source, and inside node_modules/@stencil/core

When toggling from jsxFactory to jsxImportSource, the console.assert statements will start to show red messages (but the repo doesn't run yet, I will update it soon).

trusktr avatar Mar 02 '25 05:03 trusktr