bug: unable to use `jsxImportSource` for Stencil JSX types with newer versions of TypeScript.
Prerequisites
- [x] I have read the Contributing Guidelines.
- [x] I agree to follow the Code of Conduct.
- [x] I have searched for existing issues that already report this problem, without success.
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.
where
/jsx-runtimeis 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!
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...
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.patchto see what I modified innode_modules/@stencil/core/ - search for
TODOsin both the project source, and insidenode_modules/@stencil/core - search for
console.assertin both the project source, and insidenode_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).