I'm trying to create a design system using Storybook, ViteJS, React and TypeScript. I've created the whole system and built it, but when I try to link the package to a project, then I receive this error message:
TS7016: Could not find a declaration file for module 'mypackage'. 'C:/filepath/mypackage.es.js' implicitly has an 'any' type. There are types at 'C:/filepath/node_modules/mypackage/dist/index.d.ts', but this result could not be resolved when respecting package.json "exports". The 'mypackage' library may need to update its package.json or typings.
My package.json file looks like this:
{
"name": "mypackage",
"private": true,
"version": "0.8.0",
"engines": {
"node": "20"
},
"main": "dist/mypackage.cjs",
"type": "module",
"types": "dist/index.d.ts",
"scripts": {
"build": "tsc && vite build",
"lint": "eslint src --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
"format": "prettier \"src/**/*.+(ts|tsx|js|jsx)\" --write",
"storybook": "storybook dev -p 6006",
"build-storybook": "storybook build",
"test": "vitest"
},
"peerDependencies": {
"react": "^18.2.0",
"react-dom": "^18.2.0"
},
"devDependencies": {
"@storybook/addon-essentials": "^7.0.23",
"@storybook/addon-interactions": "^7.0.23",
"@storybook/addon-links": "^7.0.23",
"@storybook/blocks": "^7.0.23",
"@storybook/react": "^7.0.23",
"@storybook/react-vite": "^7.0.23",
"@storybook/testing-library": "^0.2.0",
"@testing-library/jest-dom": "^5.16.5",
"@testing-library/react": "^14.0.0",
"@types/bytes": "^3.1.1",
"@types/react": "^18.2.13",
"@types/react-dom": "^18.2.6",
"@types/react-helmet": "^6.1.6",
"@typescript-eslint/eslint-plugin": "^5.60.0",
"@typescript-eslint/parser": "^5.60.0",
"@vitejs/plugin-react": "^4.0.1",
"axios": "^1.4.0",
"eslint": "^8.43.0",
"eslint-config-prettier": "^8.8.0",
"eslint-plugin-prettier": "^4.2.1",
"eslint-plugin-react": "^7.32.2",
"eslint-plugin-react-hooks": "^4.6.0",
"eslint-plugin-react-refresh": "^0.4.1",
"eslint-plugin-storybook": "^0.6.12",
"i18next": "^23.2.3",
"jsdom": "^22.1.0",
"prettier": "^2.8.8",
"prop-types": "^15.8.1",
"redux-saga": "^1.2.3",
"sass": "^1.63.6",
"storybook": "^7.0.23",
"typescript": "^5.0.2",
"vite": "^4.3.9",
"vitest": "^0.32.2"
},
"exports": {
".": {
"require": "./dist/mypackage.cjs",
"import": "./dist/mypackage.es.js"
}
},
"files": [
"dist"
],
"dependencies": {
"@emotion/react": "^11.11.1",
"@emotion/styled": "^11.11.0",
"@mui/lab": "^5.0.0-alpha.134",
"@mui/material": "^5.13.5",
"@mui/x-date-pickers": "^6.9.0",
"@storybook/addon-knobs": "^7.0.2",
"bytes": "^3.1.2",
"history": "^5.3.0",
"i18next-http-backend": "^2.2.1",
"moment": "^2.29.4",
"object-path-immutable": "^4.1.2",
"path": "^0.12.7",
"react-helmet": "^6.1.0",
"react-idle-timer": "^5.7.2",
"typed-redux-saga": "^1.5.0",
"vite-plugin-dts": "^2.3.0",
"vite-plugin-svgr": "^3.2.0",
"vite-tsconfig-paths": "^4.2.0",
"yup": "^1.2.0"
}
}
and my Vite config file looks like this:
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import tsconfigPaths from 'vite-tsconfig-paths';
import dts from 'vite-plugin-dts';
import { resolve } from 'path';
import * as packageJson from './package.json';
import svgr from 'vite-plugin-svgr';
export default defineConfig(() => ({
plugins: [
react(),
tsconfigPaths(),
dts({
include: ['src'],
}),
svgr(),
],
build: {
lib: {
entry: resolve('src', 'index.ts'),
name: 'ds-can',
formats: ['es', 'cjs'],
fileName: (format) => `mypackage.${format === 'cjs' ? 'cjs' : 'es.js'}`,
},
optimizeDeps: {
exclude: Object.keys(packageJson.peerDependencies),
},
esbuild: {
minify: true,
},
rollupOptions: {
external: [...Object.keys(packageJson.peerDependencies)],
}
},
test: {
environment: 'jsdom',
globals: true,
setupFiles: './setupTests.ts'
}
}));
And finally my tsconfig.json looks like this:
{
"compilerOptions": {
"target": "ESNext",
"useDefineForClassFields": true,
"lib": ["DOM", "DOM.Iterable", "ESNext"],
"allowJs": false,
"allowSyntheticDefaultImports": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"module": "ESNext",
"moduleResolution": "Node",
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react-jsx",
"declaration": true,
"skipLibCheck": true,
"esModuleInterop": true,
"declarationMap": true,
"baseUrl": ".",
"paths": {
"mypackage": ["src/index.ts"],
},
"typeRoots": ["node_modules/@types", "src/index.d.ts"]
},
"include": ["src"],
"references": [{ "path": "./tsconfig.node.json" }]
}
I've done some searches, but can't find someone that has encountered the same problem.
I finally figured out the problem. The types
field in package.json
will not be utilized if exports
field exists: https://www.typescriptlang.org/docs/handbook/esm-node.html#packagejson-exports-imports-and-self-referencing
If you need to point to a different location for your type declarations, you need to add a
"types"
import condition.
So to fix the problem I needed to add "types": "./dist/index.d.ts"
indication within the exports."."
declaration:
{
"exports": {
".": {
"types": "./dist/index.d.ts",
"require": "./dist/mypackage.cjs",
"import": "./dist/mypackage.es.js"
},
},
}