typescriptvitemonorepo

Vite generate typings for shared packages in monorepo


I am restructuring a repo to a monorepo and creating some shared packages i.e. components, theming, test-utils etc.

The repo was already using Vite so I have kept this and have introduced turborepo as well. I am using vite-plugin-dts.

My first package which is for theming using mantine I am having trouble exporting the types for the main theme.

This is the current structure:

repo/
└── packages/
    └── theming/
        ├── src/
        │   ├── colors/
        │   │   ├── colors.tsx
        │   │   ├── helpers.tsx
        │   │   └── index.ts
        │   └── theme/
        │       ├── theme.tsx
        │       └── index.ts
        ├── vite.config.ts
        └── tsconfig.ts

vite.config.ts:

export default defineConfig({
  build: {
    lib: {
      entry: path.resolve(__dirname, "src/index.ts"),
      formats: ["es"],
      fileName: "index",
    },
    rollupOptions: {
      external: [
        "react",
        "react-dom",
        "react/jsx-runtime",
        "@***/ui",
        "@mantine/core",
        "@mantine/hooks",
      ],
    },
  },
  plugins: [dts({ include: "src" }), react()],
});

tsconfig.json:

{
  "compilerOptions": {
    "types": ["node", "vitest/globals"],
    "target": "ESNext",
    "useDefineForClassFields": true,
    "lib": ["DOM", "DOM.Iterable", "ESNext"],
    "allowJs": false,
    "skipLibCheck": true,
    "esModuleInterop": false,
    "allowSyntheticDefaultImports": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "module": "ESNext",
    "moduleResolution": "bundler",
    "allowImportingTsExtensions": true,
    "resolveJsonModule": true,
    "isolatedModules": true,
    "jsx": "react-jsx",
    "noEmit": true,
    "preserveSymlinks": true,
    "typeRoots": ["node_modules/@mantine", "node_modules/@types"]
  },
  "include": ["src"]
}

When I run the build using vite the following output is generated, however notice that theme/index.ts doesn't have any exported declarations yet colors/helpers do. When importing this package in the main app and trying to import theme from the package TS says it doesn't exist as nothing from theme.tsx was exported.

repo/
└── packages/
    └── theming/
        ├── dist/
        │   ├── colors/
        │   │   ├── colors.d.ts
        │   │   ├── helpers.d.ts
        │   │   └── index.d.ts
        │   └── theme/
        │       └── index.d.ts
        ├── index.d.ts
        └── index.mjs

This is a cutdown version of the theme.tsx file:

export const theme = createTheme({
  variantColorResolver,
  spacing: {
    xxs: "4px",
    xs: "8px",
    sm: "12px",
    md: "16px",
    lg: "24px",
    xl: "32px",
    xxl: "40px",
  },
  fontFamily: "General Sans, sans-serif",

  lineHeights: {
    xs: "16px",
    sm: "18px",
    md: "22px",
    lg: "24px",
    xl: "26px",
  }
});

This theme object is what I am having trouble importing into the main app.

Looking at the built index.mjs file I can see the exported theme object e.g.

export {
  xa as GetName,
  wa as ThemedMantineProvider,
  Le as alterHslStringLightness,
  bn as colorPalette,
  $ as displayModes,
  A as fillRemainingShades,
  ya as getResolvedColors,
  ve as isInDisplayMode,
  la as theme,
  ha as useDisplayMode,
  gn as useMediaQueryValue,
  pn as variantColorResolver
};

Solution

  • Turns out this was caused by some typescript errors in the package that I hadn't seen.

    I added

     afterDiagnostic: (data) => console.log(data)
    

    to the dts plugin options, this logged out any errors during the build that seemed to be ignore.

    What I had seen was that them typing couldn't be exported. Instead of relying on the inferred return type for the Mantine theme I just declared it myself which solved the issue.