I am struggling getting Vite to generate .d.ts
declaration files for my React TypeScript library. After running npm run build only the main.js and main.css files are present in the dist folder.
I do see that during the build several files including .d.ts
files are created in the dist/
folder but when the build is done everything is removed again and only the main.js
file and main.css
file remain there.
I've tried to change or omit the values for: noEmit
, declaration
, declarationMap
and emitDeclarationOnly
from the tsconfig.app.json
but without success. None of the examples I find on the internet seem to work.
package.json
tsconfig.json
tsconfig.app.json
tsconfig.node.json
vite.config.js
/src/main.ts
/src/SomeComponent.tsx
/src/SomeHook.ts
Vite should create a dist/
folder that contains a main.js
file and a main.d.ts
file that contains all the type information for the react SomeComponent
and SomeHook
.
main.ts
export { SomeComponent } from './SomeComponent';
export { useSomeHook } from './useSomeHook';
Example of useSomeHook.ts
:
type UseSomeHookProps = {
someArg?: () => void;
};
export const useSomeHook = ({ someArg }: UseSomeHookProps = {}) => {
return { ... };
};
/// <reference types="vite/client" />
import { defineConfig } from 'vite'
import { libInjectCss } from 'vite-plugin-lib-inject-css'
import react from '@vitejs/plugin-react'
import dts from 'vite-plugin-dts'
export default defineConfig({
plugins: [
react(),
libInjectCss(),
dts({
entryRoot: 'src',
outDir: 'dist',
}),
],
build: {
lib: {
entry: './src/main.ts',
name: 'ReactWizard',
fileName: 'main',
formats: ['es'],
},
rollupOptions: {
external: ['react', 'react-dom', 'react/jsx-runtime'],
output: {
globals: {
react: 'React',
'react-dom': 'React-dom',
'react/jsx-runtime': 'react/jsx-runtime',
},
},
},
},
})
tsconfig.app.json
{
"compilerOptions": {
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
"target": "ES2020",
"useDefineForClassFields": true,
"lib": ["ES2020", "DOM", "DOM.Iterable"],
"module": "ESNext",
"skipLibCheck": true,
/* Bundler mode */
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"isolatedModules": true,
"moduleDetection": "force",
"noEmit": false,
"jsx": "react-jsx",
/* Linting */
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true,
"noUncheckedSideEffectImports": true,
"declaration": true,
"declarationMap": true,
"emitDeclarationOnly": true,
"outDir": "dist",
},
"include": ["src"],
}
{
"name": "some-package",
"version": "0.0.0",
"type": "module",
"files": [
"dist"
],
"exports": "./dist/main.js",
"module": "./dist/main.js",
"types": "./dist/main.d.ts",
"scripts": {
"build": "tsc -b && vite build",
...
},
"dependencies": {
...
},
"devDependencies": {
"@vitejs/plugin-react": "^4.3.4",
"typescript": "~5.6.2",
"vite": "^6.0.5",
"vite-plugin-dts": "^4.4.0",
...
}
}
The terminal output when runningnpm run build
is:
> tsc -b && vite build
vite v6.0.6 building for production...
✓ 189 modules transformed.
[vite:dts] Start generate declaration files...
computing gzip size (0)...[vite:dts] Declaration files built in 1074ms.
dist/main.css 6.63 kB │ gzip: 1.74 kB
dist/main.js 23.50 kB │ gzip: 7.85 kB
✓ built in 1.97s
I am struggling getting Vite to generate .d.ts
declaration files for my React TypeScript library. After running npm run build only the main.js and main.css files are present in the dist folder.
I do see that during the build several files including .d.ts
files are created in the dist/
folder but when the build is done everything is removed again and only the main.js
file and main.css
file remain there.
I've tried to change or omit the values for: noEmit
, declaration
, declarationMap
and emitDeclarationOnly
from the tsconfig.app.json
but without success. None of the examples I find on the internet seem to work.
package.json
tsconfig.json
tsconfig.app.json
tsconfig.node.json
vite.config.js
/src/main.ts
/src/SomeComponent.tsx
/src/SomeHook.ts
Vite should create a dist/
folder that contains a main.js
file and a main.d.ts
file that contains all the type information for the react SomeComponent
and SomeHook
.
main.ts
export { SomeComponent } from './SomeComponent';
export { useSomeHook } from './useSomeHook';
Example of useSomeHook.ts
:
type UseSomeHookProps = {
someArg?: () => void;
};
export const useSomeHook = ({ someArg }: UseSomeHookProps = {}) => {
return { ... };
};
/// <reference types="vite/client" />
import { defineConfig } from 'vite'
import { libInjectCss } from 'vite-plugin-lib-inject-css'
import react from '@vitejs/plugin-react'
import dts from 'vite-plugin-dts'
export default defineConfig({
plugins: [
react(),
libInjectCss(),
dts({
entryRoot: 'src',
outDir: 'dist',
}),
],
build: {
lib: {
entry: './src/main.ts',
name: 'ReactWizard',
fileName: 'main',
formats: ['es'],
},
rollupOptions: {
external: ['react', 'react-dom', 'react/jsx-runtime'],
output: {
globals: {
react: 'React',
'react-dom': 'React-dom',
'react/jsx-runtime': 'react/jsx-runtime',
},
},
},
},
})
tsconfig.app.json
{
"compilerOptions": {
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
"target": "ES2020",
"useDefineForClassFields": true,
"lib": ["ES2020", "DOM", "DOM.Iterable"],
"module": "ESNext",
"skipLibCheck": true,
/* Bundler mode */
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"isolatedModules": true,
"moduleDetection": "force",
"noEmit": false,
"jsx": "react-jsx",
/* Linting */
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true,
"noUncheckedSideEffectImports": true,
"declaration": true,
"declarationMap": true,
"emitDeclarationOnly": true,
"outDir": "dist",
},
"include": ["src"],
}
{
"name": "some-package",
"version": "0.0.0",
"type": "module",
"files": [
"dist"
],
"exports": "./dist/main.js",
"module": "./dist/main.js",
"types": "./dist/main.d.ts",
"scripts": {
"build": "tsc -b && vite build",
...
},
"dependencies": {
...
},
"devDependencies": {
"@vitejs/plugin-react": "^4.3.4",
"typescript": "~5.6.2",
"vite": "^6.0.5",
"vite-plugin-dts": "^4.4.0",
...
}
}
The terminal output when runningnpm run build
is:
> tsc -b && vite build
vite v6.0.6 building for production...
✓ 189 modules transformed.
[vite:dts] Start generate declaration files...
computing gzip size (0)...[vite:dts] Declaration files built in 1074ms.
dist/main.css 6.63 kB │ gzip: 1.74 kB
dist/main.js 23.50 kB │ gzip: 7.85 kB
✓ built in 1.97s
I had the exact same issue was able to solve it by adding tsConfigPath. This is mentioned in the usage of the plugin.
If you start with official Vite template, you should specify the tsconfigPath:
{
plugins: [dts({ tsconfigPath: './tsconfig.app.json' })]
}
Reference: https://github.com/qmhc/vite-plugin-dts
tsc
thenvite build
in yourpackage.json
'sscripts
somewhere (per e.g. vite.dev/guide/features.html#typescript), and Vite empties the output directory by default. – jonrsharpe Commented Jan 2 at 15:43emptyOutDir
setting though, Vite's dts plugin is supposed to build the declaration files right, so why would it empty it afterwards, and how come the main.css file isn't emptied out? – Stefan Commented Jan 2 at 20:16