Search code examples
reactjstypescriptvitestorybook

Storybook design system declaration file not found


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.


Solution

  • 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"
        },
      },
    }