Subscribe on changes!

Vite + Vue 3 + Typescript NPM import issue. "TS2306: File '.../index.d.ts' is not a module."

avatar
Nov 16th 2021

Version

3.2.16

Reproduction link

github.com

Steps to reproduce

  1. Clone repo
  2. npm run build

What is expected?

"consuming-app" successfully builds

What is actually happening?

src/App.vue:4:27 - error TS2306: File '/Users/user/Projects/vite-v3-ts-import-bug/packages/component/index.d.ts' is not a module.

4 import { Component } from '../../component'
                            ~~~~~~~~~~~~~~~~~

Encountered this bug when importing an NPM package containing an exported Vue component using Typescript, with typings using vue-tsc. The component is imported successfully, and it's more likely to be an issue with Typescript, since using ts-ignore will have it build successfully.

The "component" package is set up according to vite library mode documentation.

There might be something wrong with my setup, but not sure where to look.

avatar
Nov 16th 2021

You are generating types for a module called "index", which doesn't exist. That happens because you specifically compile a named input file. look at your generated types:

// ....

declare module "index" {
    export { default as Component } from "components/Component.vue";
}

You need to run (vue-)tsc against the tsconfig you built with, with a declarationDir (or at least outDir) being defined, and then point your "typings" field to that index.d.ts.

{
  "compilerOptions": {
    "target": "esnext",
    "useDefineForClassFields": true,
    "module": "esnext",
    "moduleResolution": "node",
    "strict": true,
    "jsx": "preserve",
    "sourceMap": true,
    "resolveJsonModule": true,
    "esModuleInterop": true,
    "lib": ["esnext", "dom"],
    "types": ["node"],
++    "declaration": true,
++    "declarationDir": "./types",
  },
  "include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"]
}
{
  "name": "component",
  "version": "0.0.0",
  "files": [
    "dist",
    "index.d.ts"
  ],
  "main": "./dist/my-lib.umd.js",
--  "typings": "./index.d.ts",
++ "typings": "./types/index.d.ts",
  "module": "./dist/my-lib.es.js",
  "exports": {
    ".": {
      "import": "./dist/my-lib.es.js",
      "require": "./dist/my-lib.umd.js"
    }
  },
  "scripts": {
    "dev": "vite",
--    "build": "vue-tsc src/index.ts --declaration --emitDeclarationOnly --outfile index.d.ts && vite build",
++   "build": "vue-tsc --emitDeclarationOnly && vite build",
    "serve": "vite preview"
  },

Be aware that right now, this will include a few unnecessary types for main.ts, App.vue and so on. you could create a dedicated tsconfig that only inlcudes files that will be part of the library to improve this.