typia
typia copied to clipboard
Can't make it work with Vite/Svelte
Hello. I'd love to test this, but I just can't make it work with Vite. Tried for days, and nothing. It always throws:
module.ts:653 Uncaught Error: Error on typia.is(): no transform has been configured. Read and follow https://typia.io/docs/setup please
I followed the setup guide, tried the npx typia setup
method, the manual installation, and no deal.
I've created my test repo using these steps:
pnpm create vite@latest vite-svelte # then: Svelte > Typescript
cd vite-svelte
pnpm i -D typia
pnpm i -D rollup-plugin-typescript2 typescript tslib
npx typia setup # then: pnpm > tsconfig.json
pnpm run dev
I checked, and the transformer plugin is in place:
"plugins": [
{
"transform": "typia/lib/transform"
}
],
Until here, project loads normally. Then when I edit App.svelte
to include:
import typia, { tags } from "typia";
const matched: boolean = typia.is<IMember>({
email: "[email protected]",
age: 30,
});
console.log(matched); // true
interface IMember {
email: string & tags.Format<"email">;
age: number &
tags.Type<"uint32"> &
tags.ExclusiveMinimum<19> &
tags.Maximum<100>;
}
and as I save, immediately, the error above is thrown.
I've uploaded my repository into here:
https://github.com/howesteve/typia-test/
Any clues? Is there any bare-bones repository of this actually running with vite?
Thanks.
Did you follow this guide? https://typia.io/docs/setup/#vite
Yes I did. That's what I meant when I wrote this:
I followed the setup guide, tried the npx typia setup method, the manual installation, and no deal.
I am also seeing similar problems. I am using vite version: vite/4.4.8 win32-x64 node-v18.12.0
and yarn version 3.6.1
I think I may have found the source of the problem: https://github.com/samchon/typia/blob/3776b1100574f8f156954ce767de6dbeeefee9d1/src/programmers/TypiaProgrammer.ts#L159
Because your file ends with .svelte
and not .ts
, the TypiaProgrammer never includes your file during the gather()
phase of transformation.
@matthew-dean Could you give PR #816 a try? It's a very simple fix. I did a quick and dirty test on my own machine and it seemed to work, but I am using React and not Svelte...
@howesteve @tsengia Will you svelte generation with typia@next
package?
As I don't know svelte at all, cannot sure it to work.
npm install --save typia@next
Tried but not working on *.svelte
file. TypeScript compiler can't detect it.
@samchon Even with latest fix still can't get it to work with react.
I had to modify/hot patch rollup-plugin-typescript2
to support "allowImportingTsExtensions": true
due to it defaulting to "noEmit": true
, but even with that hot patch I'm still not 100% of the way there. Typia transforms 2 modules but then rollup errors out with:
[rpt2] src/main.tsx:1:10 - error TS2614: Module '"react/jsx-runtime"' has no exported member 'jsx'. Did you mean to use 'import jsx from "react/jsx-runtime"' instead?
import { jsx } from "react/jsx-runtime";
~~~
src/main.tsx:6:21 - error TS2345: Argument of type 'HTMLElement | null' is not assignable to parameter of type 'Element | DocumentFragment'.
Type 'null' is not assignable to type 'Element | DocumentFragment'.
ReactDOM.createRoot(document.getElementById("root")).render(
I have a hunch that maybe toying with the Vite plugin settings may fix this, possibly by changing the plugin ordering.
On another note, generation with .tsx
files now works. Sadly, I'm struggling to fit this generation step into the build process due to the regular tsconfig.json
including src/
, but then requiring the build to utilize the generated code from generated/
and not from src/
. It's almost as if I need two tsconfig.json
files: one for generation and one for post-generation build.
Update: Changing Vite's plugin ordering did me no good, however I did find a different "solution".
Essentially, I had to cut Vite and the @vite-plugin/react
out of the picture and use only rollup-plugin-typescript2
and the tspCompiler
from ts-patch
, as well as disabling Vite's esbuild
. The final result of my vite.tsconfig.ts
is below:
import { defineConfig } from "vite";
import typescript from "rollup-plugin-typescript2";
import tspCompiler from "ts-patch/compiler";
// https://vitejs.dev/config/
export default defineConfig({
plugins: [{...typescript({
typescript: tspCompiler,
sourceMap: true,
inlineSources: true
}), enforce:"post"}],
esbuild: false,
// Vite options tailored for Tauri development and only applied in `tauri dev` or `tauri build`
//
// 1. prevent vite from obscuring rust errors
clearScreen: false,
// 2. tauri expects a fixed port, fail if that port is not available
server: {
port: 1420,
strictPort: true,
},
// 3. to make use of `TAURI_DEBUG` and other env variables
// https://tauri.studio/v1/api/config#buildconfig.beforedevcommand
envPrefix: ["VITE_", "TAURI_"],
});
Additionally, my tsconfig.json
file looks as such:
"compilerOptions": {
"target": "ES2020",
"lib": ["ES2020", "DOM", "DOM.Iterable"],
"module": "ESNext",
"skipLibCheck": true,
/* Bundler mode */
"moduleResolution": "bundler",
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react-jsxdev",
/* Linting */
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true,
/* Needed for mobx */
"useDefineForClassFields": true,
/* Needed for typia */
"plugins": [
{ "transform": "typia/lib/transform" }
]
},
Note: Please ignore the clearScreen
, server
, and envPrefix
fields above, they are artifacts from Tauri's build settings and aren't necessary for Typia.
With these settings, I was able to get my React app to be transformed + transpiled to JavaScript, however the resulting .js
file was not minified. There is probably additional settings that I need to tweak to get the minified output, but I am excited to see that the Typia transforms were applied.
One good thing about using the tspCompiler
instead of ts-patch install
is that it sidesteps the fact that ts-patch
is broken for Yarn v3 (Berry) PnP mode due to how it "persistently installs" itself by patching the typescript compiler source in node_modules
. Using tspCompiler
sidesteps this entirely and allows you to use ts-patch
regardless of your package manager, which is pretty nice.
I'm also facing this issue, with Vite's react template.
I face this error when trying to start the dev server:
% yarn dev
yarn run v1.22.19
$ vite
error when starting dev server:
Error: error TS5096: Option 'allowImportingTsExtensions' can only be used when either 'noEmit' or 'emitDeclarationOnly' is set.
My tsconfig looks like this:
{
"compilerOptions": {
"target": "ES2020",
"useDefineForClassFields": true,
"lib": [
"ES2020",
"DOM",
"DOM.Iterable"
],
"module": "ESNext",
"skipLibCheck": true,
/* Bundler mode */
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react-jsx",
/* Linting */
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true,
"plugins": [
{
"transform": "typia/lib/transform"
}
],
"strictNullChecks": true
},
"include": [
"src"
],
"references": [
{
"path": "./tsconfig.node.json"
}
]
}
And my vite config is the same as what's used in the documentation:
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import typescript from "rollup-plugin-typescript2";
// https://vitejs.dev/config/
export default defineConfig({
esbuild: false,
plugins: [
typescript(),
react(),
],
server: {
port: 3000
}
})
The issue seems to be caused by rollup-plugin-typescript
which forces certain tsconfig parameters:
noEmit: false (Rollup controls emit)
This seems to make it virtually impossible to use with the react vite plugin, because the noEmit
option forces you to disable the allowImportingTsExtensions
option, which breaks compilation of tsx
files with this error:
[plugin:rpt2] src/main.tsx:1:10 - error TS2305: Module '"react/jsx-dev-runtime"' has no exported member 'jsxDEV'.
1 import { jsxDEV } from "react/jsx-dev-runtime";
~~~~~~
src/main.tsx:4:17 - error TS5097: An import path can only end with a '.tsx' extension when 'allowImportingTsExtensions' is enabled.
4 import App from "./App.tsx";
The issue seems to be caused by
rollup-plugin-typescript
which forces certain tsconfig parameters:noEmit: false (Rollup controls emit)
This seems to make it virtually impossible to use with the react vite plugin, because the
noEmit
option forces you to disable theallowImportingTsExtensions
option, which breaks compilation oftsx
files with this error:
I forgot to mention, when I got Typia to work in my above comment, I had to modify the rollup-plugin-typescript2
plugin to allow for the noEmit
option.
@tsengia how did you do this? did you modify the source or how else did you achieve it?
I use Typia with SvelteKit (+ MDsveX) and din't need to modify any code.
My vite.config.ts is like the Docs says:
import { sveltekit } from '@sveltejs/kit/vite';
import { defineConfig } from 'vite';
import typescript from "rollup-plugin-typescript2" // @rollup/plugin-typescript";
export default defineConfig({
esbuild: false,
plugins: [ sveltekit(), typescript()]
});
Typia is not working inside *.svelte files. But on *.ts files that can be imported.
My Workaround looks like this:
// Example.ts
import typia, { tags } from "typia";
export type Example = {
Id: string & tags.MinLength<12>;
Date: string & tags.Format<"date">;
editable: boolean;
}
export const ExampleToJson = typia.json.createAssertStringify<Example>();
export const ExampleFromJson = typia.json.createAssertParse<Example>();
export const ExampleWithRandomData: Example = typia.random<Example>();
<script lang="ts">
import type { Example } from '$lib/Example';
import { ExampleToJson, ExampleWithRandomData } from '$lib/Example';
let example: Example = ExampleWithRandomData;
let json = '';
try {
json = ExampleToJson(example);
} catch (error) {
console.error(error);
}
console.log(example);
</script>
{json}
Only that Typia isn't type-safe if i use it with classes (see #683 ) causes me headaches.
Experiencing this problem too.
Would love to use typia for svelte but I spent 30 minutes & still can't make it work so will wait for V5.
Note : on a new Sveltekit deployment,
I had to pass in the check: false arguments in vite.config.ts to stop the rollup plugin blocking the dev
typescript({ check: false }),
As it was raising a crazy amount of errors
It worked on Typescript files in the svelte repo so Typia can be used with sveltekit
BUT I then tried on a Turborepo and it did not work for other workspaces TS files (issue submitted here: https://github.com/ezolenko/rollup-plugin-typescript2/issues/465)
@MarArMar Do you need pnpm-workspaces? Without it I can use TS. This seems to be a Bug in Vite: https://github.com/vitejs/vite/issues/5370
Try this:
Move /packages/common/lib/log-ts.ts
to apps/SKImportTS/src/lib/log-ts.ts
and use import { log, messageLoaded } from "$lib/log-ts" // was "common/lib/log-ts"
;
And I don't need check: false
but "sourceMap": false,
in tsconfig.json to suppress all […] .ts" points to missing source files'
messages. The funny thing is that the Source-Maps are still there and working.
Ok here is a working example : Turborepo X Sveltekit X Typia
Main thing was the vite config :
import { sveltekit } from "@sveltejs/kit/vite";
import { defineConfig } from "vite";
import typescript from "rollup-plugin-typescript2";
export default defineConfig({
// esbuild: false,
plugins: [
sveltekit(),
typescript({
check: false,
}),
],
});
Have to not set esbuild: false else loading of workspace modules in ts do not work
Sidenote : I tested using typia in modules outside svelte imported in svelte, not sure it works within svelte files, but was good enough for me to be able to make wrappers outside of svelte & import them
@a-kla Unfortunaltely it didn't work for me :
in vite.config.ts
:
export default defineConfig({
// esbuild: false,
plugins: [
sveltekit(),
typescript({
// check: false,
sourceMap: false,
}),
],
});
Makes the page a 500 error,
If I do :
export default defineConfig({
// esbuild: false,
plugins: [
sveltekit(),
typescript({
check: false,
sourceMap: false,
}),
],
});
I can see the page but Typia seems to be not working when imported from a ts file :
"true (expected: true) & notMatched is true (expected: false)"
It does not change anything if I add in tsconfig.json
:
{
"compilerOptions": {
"sourceMap": false,
"checkJs": false,
}
}
Finally if I add the "esbuild: false," in vite.config.ts
, I cannot import ts files from other modules in the workspace (deal-breaker for a monorepo)
My repo : https://github.com/MarArMar/TurboSvelteKitTypia
I had to modify/hot patch
rollup-plugin-typescript2
to support"allowImportingTsExtensions": true
due to it defaulting to"noEmit": true
, but even with that hot patch I'm still not 100% of the way there. Typia transforms 2 modules but then rollup errors out with:
I am desperatly trying to make this work : https://github.com/MarArMar/TurboSvelteKitTypia
How did you manage to modify/hot patch the rollup-plugin-typescript2
? Is your patch live in typia ?
Update : Actually it might not be that at all, my problem is with importing ts files, not tsx files..
I had to modify/hot patch
rollup-plugin-typescript2
to support"allowImportingTsExtensions": true
due to it defaulting to"noEmit": true
, but even with that hot patch I'm still not 100% of the way there. Typia transforms 2 modules but then rollup errors out with:I am desperatly trying to make this work : https://github.com/MarArMar/TurboSvelteKitTypia
How did you manage to modify/hot patch the
rollup-plugin-typescript2
? Is your patch live in typia ?Update : Actually it might not be that at all, my problem is with importing ts files, not tsx files..
My patch is not in Typia; it was a local patch I did to rollup-plugin-typescript2
while experimenting with fixing the issue.
I believe the patch involved modifying this function so that when allowImportingTsExtensions
is set to true
, then noEmit
also gets set to true
.
Currently, rollup-plugin-typescript2
always has noEmit
set to false
, regardless of allowImportingTsExtensions
.
If I recall correctly, my patch amounted to: if (allowImportingTsExtenions) { noEmit = true; }
(note that this is pseudo code, but I hope it illustrates my point).
Later next week I'll be able to dig through my files again to get you an absolute answer, but right now I'm away from the PC that I used to perform this patch so I don't have the exact code I used on hand.
@a-kla Unfortunaltely it didn't work for me :
in
vite.config.ts
:export default defineConfig({ // esbuild: false, plugins: [ sveltekit(), typescript({ // check: false, sourceMap: false, }), ], });
I found out that this works well in my Project:
/// <reference types="@sveltejs/kit" />
import { sveltekit } from '@sveltejs/kit/vite';
import { defineConfig } from 'vitest/config';
// for Typia
import typescript from "rollup-plugin-typescript2"
export default defineConfig({
plugins: [
{
enforce: 'pre', // <= this line fixes all my initial problems
...typescript(),
},
sveltekit(),
],
});
Now I have no changes in my tsconfig.json, except the one the Setup Wizard added automatically.
! Important Note:
It seems that I don't get any Warnings from Typia/rollup-plugin-typescript2.
If I see no transform has been configured.
- Errors it just means that I did something wrong (used Date
for Protobuf) and no transform *could made*.
. If I test the code on https://typia.io/playground/ I see what's wrong.
@a-kla Thank you so much for your answer !
managed to finally make it work with this in vite.config.ts :
" include: ["../../**/*.ts+(|x)"],"
I'm using an ESM package and no matter how I tried this, even using the overrides for the tsconfig it would just break subsequent code.
The easiest way is to add in a generate function you trigger manually (yarn generate
) or similar, tie that into your build
phase too.
Then have all your code point to that registered code. (don't forget to get eslint to forget about it too if its in your src
folder) and it will work.
# trconfig-base.json
{
"$schema": "https://json.schemastore.org/tsconfig",
"compilerOptions": {
"allowJs": false,
"allowSyntheticDefaultImports": true,
"allowUnreachableCode": false,
"allowUnusedLabels": false,
"declaration": true,
"emitDeclarationOnly": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"noFallthroughCasesInSwitch": true,
"noImplicitAny": true,
"noImplicitReturns": true,
"noImplicitThis": true,
"removeComments": false,
"resolveJsonModule": true,
"skipDefaultLibCheck": true,
"sourceMap": true,
"strictFunctionTypes": true,
"strictNullChecks": true,
"stripInternal": true,
"allowImportingTsExtensions": true,
"baseUrl": "."
}
}
#tsconfig.json
{
"$schema": "https://json.schemastore.org/tsconfig",
"extends": "./tsconfig-base.json",
"compilerOptions": {
"lib": ["ESNext"],
"module": "NodeNext",
"moduleResolution": "NodeNext",
"target": "ESNext",
"baseUrl": ".",
"esModuleInterop": true,
"paths": {
"@api/*": ["src/*"]
},
"plugins": [
{
"transform": "typia/lib/transform"
}
],
"strictNullChecks": true,
"strict": true
},
"exclude": ["node_modules", ".build"]
}
# package.json (pertinent parts)
"type": "module",
"scripts": {
"format": "prettier --write .",
"lint": "eslint --cache . --ext ts,tsx",
"prebuild": "rimraf .build/ && yarn generate",
"build": "yarn generate && node -r dotenv/config --import tsx esbuild.config.js",
"prepare": "ts-patch install && typia patch && husky install",
"generate": "typia generate --input src/typia/ts --output src/typia --project tsconfig.json",
"postinstall": "husky install",
"start": "tsx src/index.ts",
"start:watch": "tsx watch src/index.ts",
"start:debug": "node --inspect --import tsx 'src/index.ts'",
"test": "vitest run --coverage",
"test:watch": "vitest",
"upgrade-all": "yarn-upgrade-all"
},
# vitest.config.mts
import { defineConfig } from 'vitest/config'
import tsconfigPaths from 'vite-tsconfig-paths'
export default defineConfig({
plugins: [tsconfigPaths()],
test: {
// ... Specify options here.
dir: './src',
setupFiles: ['./test/global-setup.ts'],
coverage: {
include: ['src/**/*.ts'],
},
},
})
# esbuild.config.js
import esbuild from 'esbuild'
esbuild.buildSync({
entryPoints: ['./src/'],
bundle: true,
minify: true,
sourcemap: true,
format: 'esm',
outfile: '.build/index.mjs',
platform: 'node',
external: ['node'],
target: ['node18'],
banner: {
js: "import { createRequire } from 'module'; const require = createRequire(import.meta.url);",
},
// external: ['react', 'react-dom', 'ejs', 'express'],
})
This works well. You still get the decorator creation in tsc which isn't really needed right now but the generate works well and now have no issues with all the weirdness you get with vitest and esbuild getting in the way.
If some of you have knowhow about this issue, please send a website PR please.
If you also experience "TypeError: Cannot read properties of undefined (reading 'add')" for using typia with vite & rollup-plugin-typescript2,
I have this issue opened : https://github.com/ezolenko/rollup-plugin-typescript2/issues/470
With a reproduction repo for those who might have fixed the problem already : https://github.com/MarArMar/Sveltekit-RPT2-Typia
Will update on fix & welcoming help
Hi
I made a bundler plugin using unplugin
https://github.com/ryoppippi/unplugin-typia/tree/main/packages/unplugin-typia
@MarArMar You can try it! it works fine with sveltekit https://github.com/ryoppippi/unplugin-typia/tree/main/examples/sveltekit
Will try and give feedback probably next week, thanks so much @ryoppippi !! 😀
@MarArMar Thanks! We added the setup instruction to the official docs! Check this out and plz give us a feedback!
https://typia.io/docs/setup/#unplugin-typia
@samchon
We can close this issue.
If unplugin-typia
does not work for Sveltekit
, open an issue for https://github.com/ryoppippi/unplugin-typia/
@ryoppippi thanks for the script !!! Could not manage to use typia correctly before,
I got it to work correctly in a monorepo, also with sourcemaps, meaning the browser & server debugger also functions correctly ✅