Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Duplicate definition of types when multiple entrypoints #321

Open
3 tasks done
Kegulf opened this issue Apr 19, 2024 · 4 comments
Open
3 tasks done

Duplicate definition of types when multiple entrypoints #321

Kegulf opened this issue Apr 19, 2024 · 4 comments

Comments

@Kegulf
Copy link

Kegulf commented Apr 19, 2024

Describe the bug

I have a project where I have two entrypoints, one is for the base functionality, one is for react specific functionality.

  "module": "./dist/index.js",
  "types": "./dist/index.d.ts",
  "exports": {
    ".": {
      "import": {
        "types": "./dist/index.d.ts",
        "default": "./dist/index.js"
      }
    },
    "./react": {
      "import": {
        "types": "./dist/react.d.ts",
        "default": "./dist/react.js"
      }
    }
  },

vite-plugin-dts handles two entrypoints quite well, and creates seperate d.ts files for both index.js and react.js.

The problem is they use common functionality, Vite detects this and extract this functionality into a seperate file, so both entrypoints can import from it. vite-plugin-dts takes a different approach to solve this problem; it inserts the typings in both .d.ts files instead of creating this "CommonCode" file. This leads to two definitions of several of the types, and leads to some interesting type mismatch bugs.

I only discovered this bug because I had a class in the common code, which defines private readonly some_value.

image

Reproduction

https://github.com/Kegulf/vitejs-vite-jbxngt

Steps to reproduce

  • Create package being bundled in lib mode by vite with two entrypoints ( See vite.config.ts below )
  • Add Entrypoint definitions to package.json (see section "In package.json" below)
  • Create three files in source, two is entrypoints, one is common code used by both entrypoints.
    • Make sure to export the code using the common code from both entrypoints.

In package.json

  "type": "module",
  "module": "./dist/index.js",
  "types": "./dist/index.d.ts",
  "exports": {
    ".": {
      "import": {
        "types": "./dist/index.d.ts",
        "default": "./dist/index.js"
      }
    },
    "./react": {
      "import": {
        "types": "./dist/react.d.ts",
        "default": "./dist/react.js"
      }
    }
  },

vite.config.ts

import { resolve } from "node:path";
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import dts from "vite-plugin-dts";
import packageJson from "./package.json";
import tsconfigJson from "./tsconfig.json";

export default defineConfig({
  plugins: [react(), dts({ rollupTypes: true })],
  build: {
    sourcemap: true,
    target: tsconfigJson.compilerOptions.target,
    lib: {
      entry: {
        index: resolve(__dirname, "src/index.ts"),
        react: resolve(__dirname, "src/react/index.ts"),
      },
      formats: ["es"],
    },
    rollupOptions: {
      external: [
        ...Object.keys(packageJson.peerDependencies),
        "react/jsx-runtime",
      ],
    },
  },
});

System Info

System:
    OS: Windows 11 10.0.22621
    CPU: (20) x64 12th Gen Intel(R) Core(TM) i7-12700H
    Memory: 9.38 GB / 31.68 GB
  Binaries:
    Node: 20.9.0 - C:\Program Files\nodejs\node.EXE
    npm: 10.2.3 - C:\Program Files\nodejs\npm.CMD
  Browsers:
    Edge: Chromium (123.0.2420.97)
    Internet Explorer: 11.0.22621.1
  npmPackages:
    @vitejs/plugin-react: ^4.2.1 => 4.2.1
    vite: ^5.2.9 => 5.2.9
    vite-plugin-dts: ^3.8.3 => 3.8.3

Validations

@Kegulf
Copy link
Author

Kegulf commented Apr 19, 2024

I see that before the rollupTypes the someCommonCode.d.ts actually exists, which is fascinating 😁
It might be possible to check if the contents of the files is used by several entrypoints, and avoid merging it into the rolled up typefiles?
image

@Kegulf Kegulf changed the title Match Vite outupt when several entrypoints is defined Duplicate definition of types when multiple entrypoints Apr 19, 2024
@qmhc
Copy link
Owner

qmhc commented Apr 23, 2024

Currently this is hard to implement.

The rollup process is powered by @microsoft/api-extractor and it's difficult (probably noway) to change its behavior.

@Kegulf
Copy link
Author

Kegulf commented Apr 25, 2024

I see, I don't have any suggestions on how to fix this without a rewrite, unless ms-api-extractor can be configured to fix it.

@NullVoxPopuli
Copy link

I just ran in to a very similar problem with symbols being duplicated between entrypoints.

With multiple entrypoints and rolled up types, I would still expect a common .d.ts file extracted that all entrypoint .d.ts files can import from so that the unique symbol behavior that tsc enforces works correctly between the multiple entrypoints. Today, every usage of a unique symbol in each entrypoint is treated as a totally different unique symbol in the .d.ts output :(

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants