Giter Club home page Giter Club logo

vite-plugin-dts's Introduction

vite-plugin-dts

A Vite plugin that generates declaration files (*.d.ts) from .ts(x) or .vue source files when using Vite in library mode.

version license

English | 中文

Install

pnpm i vite-plugin-dts -D

Usage

In vite.config.ts:

import { resolve } from 'path'
import { defineConfig } from 'vite'
import dts from 'vite-plugin-dts'

export default defineConfig({
  build: {
    lib: {
      entry: resolve(__dirname, 'src/index.ts'),
      name: 'MyLib',
      formats: ['es'],
      fileName: 'my-lib'
    }
  },
  plugins: [dts()]
})

By default, the generated declaration files are following the source structure.

If you want to merge all declarations into one file, just specify rollupTypes: true:

{
  plugins: [dts({ rollupTypes: true })]
}

Starting with 3.0.0, you can use this plugin with Rollup.

FAQ

Here are some FAQ's and solutions.

Type errors that are unable to infer types from packages in node_modules

This is an existing TypeScript issue where TypeScript infers types from packages located in node_modules through soft links (pnpm). A workaround is to add baseUrl to your tsconfig.json and specify the paths for these packages:

{
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "third-lib": ["node_modules/third-lib"]
    }
  }
}

Internal Error occurs when using rollupTypes: true

Refer to this issue, it's due to a limitation of @microsoft/api-extractor or TypeScript resolver.

The main reason is that baseUrl is specified in tsconfig.json and non-standard paths are used directly when imported.

For example: baseUrl: 'src' is specified and importing from <root>/src/components/index.ts in <root>/src/index.ts, and import 'components' is used instead of import './components'.

Currently, you need to avoid the above situation, or use aliases instead (with the paths option).

Legacy

Missing some declaration files after build (before 1.7.0)

By default, the skipDiagnostics option is set to true which means type diagnostics will be skipped during the build process (some projects may have diagnostic tools such as vue-tsc). Files with type errors which interrupt the build process will not be emitted (declaration files won't be generated).

If your project doesn't use type diagnostic tools, you can set skipDiagnostics: false and logDiagnostics: true to turn on diagnostic and logging features of this plugin. Type errors during build will be logged to the terminal.

Type error when using both script and setup-script in Vue component (before 3.0.0)

This is usually caused by using the defineComponent function in both script and setup-script. When vue/compiler-sfc compiles these files, the default export result from script gets merged with the parameter object of defineComponent from setup-script. This is incompatible with parameters and types returned from defineComponent. This results in a type error.

Here is a simple example. You should remove the defineComponent in script and export a native object directly.

Options

import type ts from 'typescript'
import type { IExtractorConfigPrepareOptions, IExtractorInvokeOptions } from '@microsoft/api-extractor'
import type { LogLevel } from 'vite'

type MaybePromise<T> = T | Promise<T>

export type RollupConfig = Omit<
  IExtractorConfigPrepareOptions['configObject'],
  | 'projectFolder'
  | 'mainEntryPointFilePath'
  | 'compiler'
  | 'dtsRollup'
  >

export interface Resolver {
  /**
   * The name of the resolver
   *
   * The later resolver with the same name will overwrite the earlier
   */
  name: string,
  /**
   * Determine whether the resolver supports the file
   */
  supports: (id: string) => void | boolean,
  /**
   * Transform source to declaration files
   *
   * Note that the path of the returns should base on `outDir`, or relative path to `root`
   */
  transform: (payload: {
    id: string,
    code: string,
    root: string,
    outDir: string,
    host: ts.CompilerHost,
    program: ts.Program,
    service: ts.LanguageService
  }) => MaybePromise<{ path: string, content: string }[]>
}

export interface PluginOptions {
  /**
   * Specify root directory
   *
   * Defaults to the 'root' of the Vite config, or `process.cwd()` if using Rollup
   */
  root?: string,

  /**
   * Output directory for declaration files
   *
   * Can be an array to output to multiple directories
   *
   * Defaults to 'build.outDir' of the Vite config, or `outDir` of tsconfig.json if using Rollup
   */
  outDir?: string | string[],

  /**
   * Override root path of entry files (useful in monorepos)
   *
   * The output path of each file will be calculated based on the value provided
   *
   * The default is the smallest public path for all source files
   */
  entryRoot?: string,

  /**
   * Restrict declaration files output to `outDir`
   *
   * If true, generated declaration files outside `outDir` will be ignored
   *
   * @default true
   */
  strictOutput?: boolean,

  /**
   * Override compilerOptions
   *
   * @default null
   */
  compilerOptions?: ts.CompilerOptions | null,

  /**
   * Specify tsconfig.json path
   *
   * Plugin resolves `include` and `exclude` globs from tsconfig.json
   *
   * If not specified, plugin will find config file from root
   */
  tsconfigPath?: string,

  /**
   * Specify custom resolvers
   *
   * @default []
   */
  resolvers?: Resolver[],

  /**
   * Parsing `paths` of tsconfig.json to aliases
   *
   * Note that these aliases only use for declaration files
   *
   * @default true
   * @remarks Only use first replacement of each path
   */
  pathsToAliases?: boolean,

  /**
   * Set which paths should be excluded when transforming aliases
   *
   * @default []
   */
  aliasesExclude?: (string | RegExp)[],

  /**
   * Whether to transform file names ending in '.vue.d.ts' to '.d.ts'
   *
   * @default false
   */
  cleanVueFileName?: boolean,

  /**
   * Whether to transform dynamic imports to static (eg `import('vue').DefineComponent` to `import { DefineComponent } from 'vue'`)
   *
   * Value is forced to `true` when `rollupTypes` is `true`
   *
   * @default false
   */
  staticImport?: boolean,

  /**
   * Override `include` glob (relative to root)
   *
   * Defaults to `include` property of tsconfig.json (relative to tsconfig.json located)
   */
  include?: string | string[],

  /**
   * Override `exclude` glob
   *
   * Defaults to `exclude` property of tsconfig.json or `'node_modules/**'` if not supplied.
   */
  exclude?: string | string[],

  /**
   * Whether to remove `import 'xxx'`
   *
   * @default true
   */
  clearPureImport?: boolean,

  /**
   * Whether to generate types entry file(s)
   *
   * When `true`, uses package.json `types` property if it exists or `${outDir}/index.d.ts`
   *
   * Value is forced to `true` when `rollupTypes` is `true`
   *
   * @default false
   */
  insertTypesEntry?: boolean,

  /**
   * Rollup type declaration files after emitting them
   *
   * Powered by `@microsoft/api-extractor` - time-intensive operation
   *
   * @default false
   */
  rollupTypes?: boolean,

  /**
   * Bundled packages for `@microsoft/api-extractor`
   *
   * @default []
   * @see https://api-extractor.com/pages/configs/api-extractor_json/#bundledpackages
   */
  bundledPackages?: string[],

  /**
   * Override the config of `@microsoft/api-extractor`
   *
   * @default null
   * @see https://api-extractor.com/pages/setup/configure_api_report/
   */
  rollupConfig?: RollupConfig,

  /**
   * Override the invoke options of `@microsoft/api-extractor`
   *
   * @default null
   * @see https://api-extractor.com/pages/setup/invoking/#invoking-from-a-build-script
   */
  rollupOptions?: IExtractorInvokeOptions,

  /**
   * Whether to copy .d.ts source files to `outDir`
   *
   * @default false
   * @remarks Before 2.0, the default was `true`
   */
  copyDtsFiles?: boolean,

  /**
   * Whether to emit declaration files only
   *
   * When `true`, all the original outputs of vite (rollup) will be force removed
   *
   * @default false
   */
  declarationOnly?: boolean,

  /**
   * Logging level for this plugin
   *
   * Defaults to the 'logLevel' property of your Vite config
   */
  logLevel?: LogLevel,

  /**
   * Hook called after diagnostic is emitted
   *
   * According to the `diagnostics.length`, you can judge whether there is any type error
   *
   * @default () => {}
   */
  afterDiagnostic?: (diagnostics: readonly ts.Diagnostic[]) => MaybePromise<void>,

  /**
   * Hook called prior to writing each declaration file
   *
   * This allows you to transform the path or content
   *
   * The file will be skipped when the return value `false` or `Promise<false>`
   *
   * @default () => {}
   */
  beforeWriteFile?: (
    filePath: string,
    content: string
  ) => MaybePromise<
    | void
    | false
    | {
      filePath?: string,
      content?: string
    }
  >,

  /**
   * Hook called after rolling up declaration files
   *
   * @default () => {}
   */
  afterRollup?: (result: ExtractorResult) => MaybePromise<void>,

  /**
   * Hook called after all declaration files are written
   *
   * It will be received a map (path -> content) that records those emitted files
   *
   * @default () => {}
   */
  afterBuild?: () => MaybePromise<void>
}

Contributors

Thanks for all the contributions!

contributors

Example

Clone and run the following script:

pnpm run test:ts

Then check examples/ts/types.

Also Vue and React cases under examples.

A real project using this plugin: Vexip UI.

License

MIT License.

vite-plugin-dts's People

Contributors

2wheeh avatar alexaegis avatar anthonyblond avatar arpansaha13 avatar biggerstar avatar dependabot[bot] avatar donggua-nor avatar dreamofice avatar edielemoine avatar ekaradon avatar ettapp avatar fangyang921017 avatar gcaaa31928 avatar glitchboyl avatar javanshen avatar jiuranya avatar kubajastrz avatar ljwrer avatar luckylooke avatar markgaze avatar modularcoder avatar muryoh avatar nstuyvesant avatar partiality avatar qmhc avatar rorry121 avatar szamanr avatar wjq990112 avatar xingxiuyi avatar yoshida-valuesccg avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

vite-plugin-dts's Issues

dts() doesn't support multiple default exports when using new sfc `<script setup>`

Recently i changed from the default vue 3 boilerplate of using setup() for the recently out of experimental <script setup>, but when type gen with dts plugin comes in i found an issue when the sfc need to describe more than one default export at the same time, like is described here.

With out the secondary default export the dts plugin works well as far as i know.

Relevant output of the failing build:

error TS2528: A module cannot have multiple default exports

for reproduction:

  • clone this repo at branch 'development'
  • npm install
  • open the component located under src/components/layout/VContainer.vue
  • add the following line of code at the bottom of the component:
    <script lang="ts"> import { defineComponent } from 'vue'; export default defineComponent({ name: 'VuestrapedContainer', }); </script>
  • npm run build
  • Examine the output

生成.d.ts时部分文件丢失

emm. 我又来了,如图
image
当前有这两个文件,且在对外暴露的index.ts文件中有引入
image
但构建之后 丢失

composables/useForm.ts
types/form.ts

这两个文件。结果如下
image

demo

Typescript's type aliases are not resolved in Vue components

In my tsconfig.json file I specify the following path alias:

{
    "paths": {
      "~/*": ["src/*"]
    },
}

And then in a VueJS component I might import a dependencies like so:

import { TrueFalse, icon, isTrue } from "~/components/shared";

image

Vite compiles the source without issue and vite-plugin-dts also creates declaration files but as you can see below, the ~/ type alias is still present in the type which makes it unusable as an exported type file.

2021-10-29_14-53-32 (3)

Historically, when using Rollup directly I have used a combination of the ts-patch npm module and the typescript-transform-paths module:

  • ts-patch - patches Typescript's tsc to allow it to use the Typescript plugin API
  • typescript-transform-paths addresses converting type aliases back to full file paths

With this done, you just add the plugins to your tsconfig.json file like so:

{
    "plugins": [
      // Transform paths in output .js files
      { "transform": "typescript-transform-paths" },

      // Transform paths for declarations files
      { "transform": "typescript-transform-paths", "afterDeclarations": true }
    ]
}

This works and I've never found a way to get TYPES to export using the alias Rollup plugin (which is what ViteJS uses I believe). In any case, I'd really like to run everything in ViteJS and your plugin "almost" works ... hoping we can get path aliases incorporated.

Usage with TSX

I am trying to use it with react typescript i.e TSX but it is not generating types

How to infer component emitted event types?

image
image

我这里的onAdd应该是(value: number) => void,但生成的结果确是((...args: any[]) => any) | undefined,我想知道这是插件的问题还是vite打包的配置问题,应该怎么解决呢

dts doesn't resolve typescript paths on dts generation and wrong dts dist structure

Hello I'm trying to generate the .d.ts for my vite vue lib, but at the time that i inspect my dist folder i identify 2 problems so far:

  1. the .ts based .d.ts such as index.d.ts doesn't resolve correctly the typescript paths. eg. '@/' path. So module not found problem raises at the import and export of anything.

  2. The dist folder gets the intended declaration dir (in my case @types/), but have an incorrect folder structure for d.ts of my components. like copying the src/ dir inside. This maybe works alongside a correr path resolution buy i have no clue about it.

i have no idea if I'm misunderstanding something, or i have a wrong configuration for proper generation of types of my lib, so any advice is appreciated

For reproduction :

[Bug] The argument 'path' must be a string or Uint8Array without null bytes

Hi, thanks you @qmhc for great library! But today I had an error when I use this lib with yarn 3 pnp!

[vite:dts] The argument 'path' must be a string or Uint8Array without null bytes. Received '/home/techmely/techmely/packages/utils/\x00commonjsHelpers.js'
file: commonjsHelpers.js
error during build:
TypeError [PLUGIN_ERROR]: The argument 'path' must be a string or Uint8Array without null bytes. Received '/home/techmely/techmely/packages/utils/\x00commonjsHelpers.js'
    at Object.openSync (node:fs:577:10)
    at NodeFS.openSync (/home/techmely/techmely/.pnp.cjs:14347:24)
    at makeCallSync.subPath.subPath (/home/techmely/techmely/.pnp.cjs:17033:26)
    at ZipOpenFS.makeCallSync (/home/techmely/techmely/.pnp.cjs:17789:26)
    at ZipOpenFS.openSync (/home/techmely/techmely/.pnp.cjs:17032:17)
    at VirtualFS.openSync (/home/techmely/techmely/.pnp.cjs:14785:24)
    at PosixFS.openSync (/home/techmely/techmely/.pnp.cjs:14785:24)
    at URLFS.openSync (/home/techmely/techmely/.pnp.cjs:14785:24)
    at Object.readFileSync (node:fs:453:35)
    at NodeFS.readFileSync (/home/techmely/techmely/.pnp.cjs:14693:24)
    

Reproduction:
The repo https://github.com/techmely/techmely/blob/main/packages/utils/vite.config.ts

You can check the error with the command: yarn build:utils

Hope you or someone can fix that <3

A new update is breaking bundling of SSR application

Hello,

on update to 1.0.0 the DTS is breaking bundling of chalk,

failed to load config from /home/sionzee/projects/censured/editor/packages/editor/vite.config.ts
error when starting dev server:
Error [ERR_REQUIRE_ESM]: require() of ES Module /home/sionzee/projects/censured/editor/node_modules/.pnpm/[email protected]/node_modules/chalk/source/index.js from /home/sionzee/projects/censured/editor/node_modules/.pnpm/[email protected][email protected]/node_modules/vite-plugin-dts/dist/index.js not supported.
Instead change the require of /home/sionzee/projects/censured/editor/node_modules/.pnpm/[email protected]/node_modules/chalk/source/index.js in /home/sionzee/projects/censured/editor/node_modules/.pnpm/[email protected][email protected]/node_modules/vite-plugin-dts/dist/index.js to a dynamic import() which is available in all CommonJS modules.
    at Object.<anonymous> (/home/sionzee/projects/censured/editor/node_modules/.pnpm/[email protected][email protected]/node_modules/vite-plugin-dts/dist/index.js:34:28)
    at async Promise.all (index 0)
    at async loadConfigFromFile (/home/sionzee/projects/censured/editor/node_modules/.pnpm/[email protected]/node_modules/vite/dist/node/chunks/dep-9c153816.js:71326:31)
    at async resolveConfig (/home/sionzee/projects/censured/editor/node_modules/.pnpm/[email protected]/node_modules/vite/dist/node/chunks/dep-9c153816.js:70873:28)
    at async createServer (/home/sionzee/projects/censured/editor/node_modules/.pnpm/[email protected]/node_modules/vite/dist/node/chunks/dep-9c153816.js:56425:20)
    at async CAC.<anonymous> (/home/sionzee/projects/censured/editor/node_modules/.pnpm/[email protected]/node_modules/vite/dist/node/cli.js:688:24)
undefined

Returning back to ^0.9.10 fixes the error.


This looks like an include issue, because it is visiting node_modules of other packages in monorepo.
I'm using chalk in package where vite-plugin-dts is not included.

In the config I have:

    plugins: [
      dts({
        include: ['./index.ts', './src'],
      })
    ],

Unfortunately I cannot provide source code due NDA.

Output files is out of the `include` bounds

Hello, is it possible to override value of specific properties in tsconfig.json?

Say you have this in your tsconfig:

{
  "compilerOptions": {
    "target": "esnext",
    "module": "esnext",
    "moduleResolution": "node",
    "strict": true,
    "jsx": "preserve",
    "sourceMap": true,
    "resolveJsonModule": true,
    "esModuleInterop": true,
    "lib": ["esnext", "dom"]
  },
  "include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.vue", "lib/index.ts"]
}

and in your vite.config.ts

defineConfig({
  build: {
    lib: {
      entry: resolvePath('lib/index.ts'),
      name: 'sixty-nine',
      fileName: (format) => `sixty-nine.${format}.js`,
    },
    rollupOptions: {
      external: ['vue'],
      output: {
        globals: {
          vue: 'Vue'
        },
      },
    },
  },
  plugins: [
    dts({
      compilerOptions: {
        rootDir: resolvePath('lib'),
        exclude: resolvePath('node_modules/**'),
      },
    })
  ],
});

When building the library, I want to change

"include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.vue", "lib/index.ts"]

to

"include": ["lib/index.ts"]

Is that possible? Thanks!

setup script支持问题

image
如上图
因为 setup script 支持了 export interface Props {}
所以我准备在setup script中声明类型,再导出去,这样类型只用定义一次。但是发现使用dts生成.d.ts时报错

Supporting non-primitives in generated types

Hello again :)

I'm developing a component, and one thing I've noticed that props are converted to primitives.

So this
image

Outputs
image

So seems that property with an interface

 someObjectProp: {
      boolProp: boolean
      stringProp: 'one' | 'two' | 'three'
 }

Gets compiled to

someObjectProp: {
       type: ObjectConstructor;
       required: true;
};

Wondering if this can be improved or is this vue/compiler-sfc limitation?
Thanks

Compiled components lib VSCode Volar intellisense

Hello!
First of all I would like to thank and express my gratitude to @qmhc for this library. Was struggling a lot how to generate compiled library types before saw vite-plugin-dts.

I'm currently building a component library which should be published and distributed in npm and used in multiple projects. vite-plugin-dts seems to generate all the component types, but one thing that cough my eye is that the template intelisense is missing when importing compiled lib.

Imported compiled components (generated types seems ok)
image

Component intellisense not working inside template files
image

So I was wondering is this a Volar limitation or me not having the correct TS configs.
Thanks!

P.s. Sorry if this question isn't related to this project

Publish v0.3.4

Hello and thank you for the library, which fixes a pain point of mine. You have released v0.3.4 but haven't published to npm since v0.3.1. I'm sure that's just an accident by your part. :)

How to use `root` correctly?

Thanks for building this and sharing it!

My directory structure looks like this

My-Component/
    dist/
    lib/
    some-other-stuff/
    tsconfig.json

My vitejs build options are

 build: {
    lib: {
      entry: path.resolve(__dirname, 'lib/index.ts'),
      name: 'my-component',
      fileName: (format) => `my-component.${format}.js`,
    }
  },

If I use the plugin with the default options, vite-plugin-dts creates the files:

dist/
    lib/
        <stuff>.d.ts

That's good. But what I want to achieve is

dist/
    typings/
        <stuff>.d.ts

So I tried this

dts({
      root: 'lib',
      outputDir: 'dist/typings',
      tsConfigFilePath: '../tsconfig.json',
    }),

This runs without any errors:

[vite:dts] Start generate declaration files...
[vite:dts] Declaration files built in 5776ms.

However, now my dist directory does contain any output from the plugin. Setting logDiagnostics:true does not cause the plugin to tell me what it is doing or where it is putting the files.

So my question is, how do I set the options so that I can get the output structure I need?
Thanks!

Generated types stay primitives

Hello,

First of all thank you for your lib.
I'm encountering an issue with the generated types. I have a Button.vue component like this :

<script setup lang="ts">
type Props = {
  color: "blue" | "red";
};

defineProps<Props>();
</script>

<template>
  <button>Test</button>
</template>

The prop color is a String that only accepts 2 defined words blue and red.
But this is the result of the generated Button.vue.d.ts file :

image

As you can see, the color prop is now a StringConstructor and accepts every string. I'm losing the initial typing which is more strict.

This is my vite.config.ts file :

import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue";
import { resolve } from "path";
import dts from "vite-plugin-dts";

export default defineConfig({
  plugins: [vue(), dts()],
  build: {
    lib: {
      entry: resolve(__dirname, "src/main.ts"),
      name: "uikit",
    },
    rollupOptions: {
      external: ["vue"],
      output: {
        globals: {
          vue: "Vue",
        },
      },
    },
  },
});

Am I doing something wrong or the lib can't just be more precise with the types ?

not work with withDefaults

In Vue3's <script setup> syntax, withDefaults allows setting default values of props and make definition of property -?-able, here's a example:

<script setup>
import { withDefaults } from 'vue'

const props: withDefaults(defineProps<{
  foo?: string
}>(), {
  foo: 'bar',
})
/**
 * type of `props`:
 * props: {
 *   foo: string
 * }
 */
</script>

But when vite build with this plugin, compiler reports with:

index.vue.ts:10:3 - error TS2769: No overload matches this call.
  The last overload gave the following error.
    Type 'undefined' is not assignable to type 'Readonly<ComponentPropsOptions<Data>> & ThisType<void>'.
      Type '(this: void, __props: { foo?: string | undefined }' is not assignable to type '(this: void, props: Readonly<LooseRequired<Readonly<readonly unknown[] & { [x: number]: string; } & { [iterator]?: IterableIterator<string> | undefined; toString?: string | undefined; toLocaleString?: string | undefined; concat?: string[] | undefined; ... 19 more ...; flat?: unknown[] | undefined; }> | Readonly<...>...'.
        Types of parameters '__props' and 'props' are incompatible.
          Property 'foo' is missing in type 'Readonly<LooseRequired<Readonly<readonly unknown[] & { [x: number]: string; } & { [iterator]?: IterableIterator<string> | undefined; toString?: string | undefined; toLocaleString?: string | undefined; concat?: string[] | undefined; ... 19 more ...; flat?: unknown[] | undefined; }> | Readonly<...>>>' but required in type '{ foo: string; }'.

10   props: {
     ~~~~~

resolve.alias doesn't work is this plugin

Hello !

It looks like aliases are not correctly transformed in d.ts files.. All the JavaScript code is ok. It's just my d.ts files.

image

Here my vite config :

import { defineConfig } from 'vitest/config'
import tsconfigPaths from 'vite-tsconfig-paths'
import react from '@vitejs/plugin-react'
import peerDepsExternal from 'rollup-plugin-peer-deps-external'
import dts from 'vite-plugin-dts'

const path = require('path')

// https://vitejs.dev/config/
export default defineConfig({
  test: {
    environment: 'jsdom',
    globals: true
  },
  build: {
    sourcemap: true,
    target: 'esnext',
    minify: false,
    lib: {
      entry: path.resolve(__dirname, 'src/index.tsx'),
      name: 'Mui-phone-number',
      fileName: format => `mui-phone-number.${format}.js`
    },
    rollupOptions: {
      output: {
        sourcemapExcludeSources: true,
        globals: {
          react: 'React',
          '@mui/material/InputAdornment': 'InputAdornment',
          '@mui/material/TextField': 'TextField',
          '@mui/material/IconButton': 'IconButton',
          '@mui/material/styles': 'styles',
          'react/jsx-runtime': 'jsxRuntime',
          '@mui/material/Menu': 'Menu',
          '@mui/material/MenuItem': 'MenuItem',
          '@mui/material/Typography': 'Typography',
          '@mui/material/ListItemIcon': 'ListItemIcon',
          '@mui/material/ListItemText': 'ListItemText'
        }
      }
    }
  },
  plugins: [
    peerDepsExternal(),
    react(),
    tsconfigPaths(),
    dts({
      insertTypesEntry: true
    })
  ]
})

Is anyone has the same issue ?

feat: work during --watch

Not sure if this is possible with how vite's --watch is set up, but would be great if this plugin worked during watch mode.

This would be helpful for building a library and testing it out (i.e. with yarn link) in a separate app at the same time. Right now, in watch mode the types are removed from the output after reloading.

Couple of typescript related issues

I'm using vite for my vanilla typescript project along with this plugin. I found few bugs with this library,

  • When I build the project with this plugin, it leaves the converted javascript files in the disk as you can see in the project.

Screen Shot 2021-06-08 at 7 46 35 PM

  • If I use a non relative path like /@/, then the emitted declarations includes incorrect path. For example,

I have constants.ts,

export enum Color {
    Red,
    Blue,
    Green
}

export const colors = new Array<Color>(Color.Red, Color.Blue, Color.Green)

And in main.ts I have following,

import { Color } from "/@/constants"

export default function viteProject(): Color {
    console.log(Color.Red)
    return Color.Red
}

Then the emitted declaration file has src/constants which is an incorrect path,

import { Color } from 'src/constants';
export default function viteProject(): Color;

Here's the source code: https://github.com/sanjade/js-bug

用脚本去手动打包,脚本文件存放项目中不同路径下生成的文件结果不一样

我在使用dts()生成.d.ts文件时发现。
如果我写的脚本文件放于根目录下,也就是project/下。则打包能生成如下的文件(注意红框中的生成文件)
image

但是,如果把该脚本放于project/script下,则只会生成index.d.ts. 如下(与上图对比,少了两)
image

因为console也没有提示相关错误,所以不好排查。下面是这个demo的地址
demo

我希望的是,两者生成的结果,应该都是第一次的结果。:(

Error: File not found: commonjsHelpers.js

at DirectoryCoordinator.addSourceFileAtPath (./node_modules/ts-morph/dist/ts-morph.js:18117:19)
at Project.addSourceFileAtPath (./node_modules/ts-morph/dist/ts-morph.js:19567:51)
at Object.transform (./node_modules/vite-plugin-dts/dist/index.js:138846:17)
at ./node_modules/rollup/dist/shared/rollup.js:22620:25

Doesn't support script setup ?

The library is great. But it fails with the script setup rfc. There are couple of errors.

src/components/lib/FAlert.vue.ts:11:3 - error TS2769: No overload matches this call.
  The last overload gave the following error.
    Type 'undefined' is not assignable to type 'Readonly<ComponentPropsOptions<Data>> & ThisType<void>'.
      Type '(this: void, __props: { icon?: string | undefined; message: string; id: string; type: "success" | "danger" | "warning"; }) => { props: { icon?: string | undefined; message: string; id: string; type: "success" | ... 1 more ... | "warning"; }; bgColor: ComputedRef<...>; iconName: ComputedRef<...>; computed: { ...; }; ...' is not assignable to type '(this: void, props: Readonly<LooseRequired<Readonly<{ [x: number]: string; } & { [iterator]?: IterableIterator<string> | undefined; toString?: string | undefined; toLocaleString?: string | undefined; concat?: string[] | undefined; ... 19 more ...; flat?: unknown[] | undefined; }> | Readonly<...>>>, ctx: SetupContext...'.
        Types of parameters '__props' and 'props' are incompatible.
          Type 'Readonly<LooseRequired<Readonly<{ [x: number]: string; } & { [iterator]?: IterableIterator<string> | undefined; toString?: string | undefined; toLocaleString?: string | undefined; concat?: string[] | undefined; ... 19 more ...; flat?: unknown[] | undefined; }> | Readonly<...>>>' is missing the following properties from type '{ icon?: string | undefined; message: string; id: string; type: "success" | "danger" | "warning"; }': message, id, type

11   props: {
     ~~~~~

  node_modules/@vue/runtime-core/dist/runtime-core.d.ts:420:5
    420     props: PropsOptions & ThisType<void>;
            ~~~~~
    The expected type comes from property 'props' which is declared here on type 'ComponentOptionsWithObjectProps<Readonly<ComponentPropsOptions<Data>>, { props: { icon?: string | undefined; message: string; id: string; type: "success" | "danger" | "warning"; }; bgColor: ComputedRef<...>; iconName: ComputedRef<...>; computed: { ...; }; FIcon: DefineComponent<...>; }, ... 8 more ..., { ...; } | {}>'
  node_modules/@vue/runtime-core/dist/runtime-core.d.ts:585:25
    585 export declare function defineComponent<PropsOptions extends Readonly<ComponentPropsOptions>, RawBindings, D, C extends ComputedOptions = {}, M extends MethodOptions = {}, Mixin extends ComponentOptionsMixin = ComponentOptionsMixin, Extends extends ComponentOptionsMixin = ComponentOptionsMixin, E extends EmitsOptions = Record<string, any>, EE extends string = string>(options: ComponentOptionsWithObjectProps<PropsOptions, RawBindings, D, C, M, Mixin, Extends, E, EE>): DefineComponent<PropsOptions, RawBindings, D, C, M, Mixin, Extends, E, EE>;
                                ~~~~~~~~~~~~~~~
    The last overload is declared here.
src/components/lib/FAlert.vue.ts:17:3 - error TS2769: No overload matches this call.
  The last overload gave the following error.
    Type 'undefined' is not assignable to type 'Readonly<ComponentPropsOptions<Data>> & ThisType<void>'.
      Type '(this: void, __props: { icon?: string | undefined; message: string; id: string; type: "success" | "danger" | "warning"; }) => { props: { icon?: string | undefined; message: string; id: string; type: "success" | ... 1 more ... | "warning"; }; bgColor: ComputedRef<...>; iconName: ComputedRef<...>; computed: { ...; }; ...' is not assignable to type '(this: void, props: Readonly<LooseRequired<Readonly<{ [x: number]: string; } & { [iterator]?: IterableIterator<string> | undefined; toString?: string | undefined; toLocaleString?: string | undefined; concat?: string[] | undefined; ... 19 more ...; flat?: unknown[] | undefined; }> | Readonly<...>>>, ctx: SetupContext...'.
        Types of parameters '__props' and 'props' are incompatible.
          Type 'Readonly<LooseRequired<Readonly<{ [x: number]: string; } & { [iterator]?: IterableIterator<string> | undefined; toString?: string | undefined; toLocaleString?: string | undefined; concat?: string[] | undefined; ... 19 more ...; flat?: unknown[] | undefined; }> | Readonly<...>>>' is missing the following properties from type '{ icon?: string | undefined; message: string; id: string; type: "success" | "danger" | "warning"; }': message, id, type

17   setup(__props: {
     ~~~~~

  node_modules/@vue/runtime-core/dist/runtime-core.d.ts:389:5
    389     setup?: (this: void, props: Readonly<LooseRequired<Props & UnionToIntersection<ExtractOptionProp<Mixin>> & UnionToIntersection<ExtractOptionProp<Extends>>>>, ctx: SetupContext<E>) => Promise<RawBindings> | RawBindings | RenderFunction | void;
            ~~~~~
    The expected type comes from property 'setup' which is declared here on type 'ComponentOptionsWithObjectProps<Readonly<ComponentPropsOptions<Data>>, { props: { icon?: string | undefined; message: string; id: string; type: "success" | "danger" | "warning"; }; bgColor: ComputedRef<...>; iconName: ComputedRef<...>; computed: { ...; }; FIcon: DefineComponent<...>; }, ... 8 more ..., { ...; } | {}>'
  node_modules/@vue/runtime-core/dist/runtime-core.d.ts:585:25
    585 export declare function defineComponent<PropsOptions extends Readonly<ComponentPropsOptions>, RawBindings, D, C extends ComputedOptions = {}, M extends MethodOptions = {}, Mixin extends ComponentOptionsMixin = ComponentOptionsMixin, Extends extends ComponentOptionsMixin = ComponentOptionsMixin, E extends EmitsOptions = Record<string, any>, EE extends string = string>(options: ComponentOptionsWithObjectProps<PropsOptions, RawBindings, D, C, M, Mixin, Extends, E, EE>): DefineComponent<PropsOptions, RawBindings, D, C, M, Mixin, Extends, E, EE>;
                                ~~~~~~~~~~~~~~~
    The last overload is declared here.
src/components/lib/FMenu.vue.ts:8:3 - error TS2769: No overload matches this call.
  The last overload gave the following error.
    Type 'undefined' is not assignable to type 'Readonly<ComponentPropsOptions<Data>> & ThisType<void>'.
      Type '(this: void, __props: { options: string[] | Record<"label" | "value", any>[]; modelValue?: string | undefined; optionKey?: "label" | "value" | undefined; label?: string | undefined; icon?: string | undefined; size?: string | undefined; sm?: boolean | undefined; }, { emit }: SetupContext<...>) => { ...; }' is not assignable to type '(this: void, props: Readonly<LooseRequired<Readonly<{ [x: number]: string; } & { [iterator]?: IterableIterator<string> | undefined; toString?: string | undefined; toLocaleString?: string | undefined; concat?: string[] | undefined; ... 19 more ...; flat?: unknown[] | undefined; }> | Readonly<...>>>, ctx: SetupContext...'.
        Types of parameters '__props' and 'props' are incompatible.
          Property 'options' is missing in type 'Readonly<LooseRequired<Readonly<{ [x: number]: string; } & { [iterator]?: IterableIterator<string> | undefined; toString?: string | undefined; toLocaleString?: string | undefined; concat?: string[] | undefined; ... 19 more ...; flat?: unknown[] | undefined; }> | Readonly<...>>>' but required in type '{ options: string[] | Record<"label" | "value", any>[]; modelValue?: string | undefined; optionKey?: "label" | "value" | undefined; label?: string | undefined; icon?: string | undefined; size?: string | undefined; sm?: boolean | undefined; }'.

8   props: {
    ~~~~~

  node_modules/@vue/runtime-core/dist/runtime-core.d.ts:420:5
    420     props: PropsOptions & ThisType<void>;
            ~~~~~
    The expected type comes from property 'props' which is declared here on type 'ComponentOptionsWithObjectProps<Readonly<ComponentPropsOptions<Data>>, { emit: (event: "input" | "update:modelValue", ...args: any[]) => void; isMenu: Ref<boolean>; ... 6 more ...; FButton: DefineComponent<...>; }, ... 8 more ..., { ...; } | {}>'
  node_modules/@vue/runtime-core/dist/runtime-core.d.ts:585:25
    585 export declare function defineComponent<PropsOptions extends Readonly<ComponentPropsOptions>, RawBindings, D, C extends ComputedOptions = {}, M extends MethodOptions = {}, Mixin extends ComponentOptionsMixin = ComponentOptionsMixin, Extends extends ComponentOptionsMixin = ComponentOptionsMixin, E extends EmitsOptions = Record<string, any>, EE extends string = string>(options: ComponentOptionsWithObjectProps<PropsOptions, RawBindings, D, C, M, Mixin, Extends, E, EE>): DefineComponent<PropsOptions, RawBindings, D, C, M, Mixin, Extends, E, EE>;
                                ~~~~~~~~~~~~~~~
    The last overload is declared here.
src/components/lib/FMenu.vue.ts:18:3 - error TS2769: No overload matches this call.
  The last overload gave the following error.
    Type 'undefined' is not assignable to type 'Readonly<ComponentPropsOptions<Data>> & ThisType<void>'.
      Type '(this: void, __props: { options: string[] | Record<"label" | "value", any>[]; modelValue?: string | undefined; optionKey?: "label" | "value" | undefined; label?: string | undefined; icon?: string | undefined; size?: string | undefined; sm?: boolean | undefined; }, { emit }: SetupContext<...>) => { ...; }' is not assignable to type '(this: void, props: Readonly<LooseRequired<Readonly<{ [x: number]: string; } & { [iterator]?: IterableIterator<string> | undefined; toString?: string | undefined; toLocaleString?: string | undefined; concat?: string[] | undefined; ... 19 more ...; flat?: unknown[] | undefined; }> | Readonly<...>>>, ctx: SetupContext...'.
        Types of parameters '__props' and 'props' are incompatible.
          Property 'options' is missing in type 'Readonly<LooseRequired<Readonly<{ [x: number]: string; } & { [iterator]?: IterableIterator<string> | undefined; toString?: string | undefined; toLocaleString?: string | undefined; concat?: string[] | undefined; ... 19 more ...; flat?: unknown[] | undefined; }> | Readonly<...>>>' but required in type '{ options: string[] | Record<"label" | "value", any>[]; modelValue?: string | undefined; optionKey?: "label" | "value" | undefined; label?: string | undefined; icon?: string | undefined; size?: string | undefined; sm?: boolean | undefined; }'.

18   setup(__props: {
     ~~~~~

  src/components/lib/FMenu.vue.ts:19:3
    19   options: string[] | Record<'label' | 'value', any>[];
         ~~~~~~~
    'options' is declared here.
  node_modules/@vue/runtime-core/dist/runtime-core.d.ts:389:5
    389     setup?: (this: void, props: Readonly<LooseRequired<Props & UnionToIntersection<ExtractOptionProp<Mixin>> & UnionToIntersection<ExtractOptionProp<Extends>>>>, ctx: SetupContext<E>) => Promise<RawBindings> | RawBindings | RenderFunction | void;
            ~~~~~
    The expected type comes from property 'setup' which is declared here on type 'ComponentOptionsWithObjectProps<Readonly<ComponentPropsOptions<Data>>, { emit: (event: "input" | "update:modelValue", ...args: any[]) => void; isMenu: Ref<boolean>; ... 6 more ...; FButton: DefineComponent<...>; }, ... 8 more ..., { ...; } | {}>'
  node_modules/@vue/runtime-core/dist/runtime-core.d.ts:585:25
    585 export declare function defineComponent<PropsOptions extends Readonly<ComponentPropsOptions>, RawBindings, D, C extends ComputedOptions = {}, M extends MethodOptions = {}, Mixin extends ComponentOptionsMixin = ComponentOptionsMixin, Extends extends ComponentOptionsMixin = ComponentOptionsMixin, E extends EmitsOptions = Record<string, any>, EE extends string = string>(options: ComponentOptionsWithObjectProps<PropsOptions, RawBindings, D, C, M, Mixin, Extends, E, EE>): DefineComponent<PropsOptions, RawBindings, D, C, M, Mixin, Extends, E, EE>;
                                ~~~~~~~~~~~~~~~
    The last overload is declared here.

I think this is due to the chunks that vite build produces for the script setup syntax.

Types are being dropped if <script lang="ts"> is using defineComponent

Was struggling a lot to understand why at some points the types were gone. Then found out that is related to using defineComponents inside the script without setup.

This works as expected (as in example)

<script lang="ts">
  export default {
    name: 'BaseButton',
  }
</script>

However types are gone if the script without setup uses defineComponent

<script lang="ts">
  import { defineComponent } from 'vue'
  
  export default defineComponent({
    name: 'BaseButton',
  })
</script>

Can not resolve alias when using default import

source: import VContainer from '@components/layout/container/VContainer.vue'

outputs: import VContainer from '@components/layout/container/VContainer.vue'

correct outputs: import VContainer from './components/layout/container/VContainer.vue'

vite config:

{
  resolve: {
    alias: {
      '@': path.resolve(__dirname, 'src'),
      '@components': path.resolve(__dirname, 'src/components'),
    },
  }
}

Another issue:
When an alias is included by another alias and is in front of the another alias, can not resolve aliases correctly.
When an alias real dir path is using by a file which includes the alias real dir path, can not resolve aliases correctly.

origin: #19 (comment)

Warning js vue component

if there's at least one js vue component referenced, it would cause error when building.

maybe it should warn user check the type, or just ask user change "allowJs" option to true in tsconfig.json?

does not support Node.js 12

fs/promise is only available on Node.js 14 and above.

The engine verison requirment in package.json is not correct.

12 is still a supported version. I think it’s better to target 12 and above.

Thanks for great plug-in, anyway

Plugin not honouring `sourcemap: false`

It appears that the generated types files are still trying to create a source map link:

Screen Shot 2022-01-04 at 1 46 32 PM

No .map files actually exist though, as I have chosen not to include source maps.

test:e2e error

test:e2e error

SyntaxError: Unexpected token '.'
at wrapSafe (internal/modules/cjs/loader.js:1054:16)

Should filter vite virtual files when transform

为某个使用了 devextreme-vue 的组件生成 dts 时报错,内容如下:

[vite:dts] Start generate declaration files...
transforming (12) node_modules/devextreme/esm/ui/data_grid/ui.data_grid.base.js[vite:dts] Declaration files built in 2987ms.

[vite:dts] The argument 'path' must be a string or Uint8Array without null bytes. Received '/path-to-develop/test/vite-plugin-dts-test/\x00commonjsHelpers.js'
file: commonjsHelpers.js
error during build:
TypeError [PLUGIN_ERROR]: The argument 'path' must be a string or Uint8Array without null bytes. Received '/path-to-develop/test/vite-plugin-dts-test/\x00commonjsHelpers.js'
    at Object.openSync (node:fs:577:10)
    at Object.readFileSync (node:fs:453:35)
    at NodeRuntimeFileSystem.readFileSync (/path-to-develop/test/vite-plugin-dts-test/node_modules/@ts-morph/common/dist/ts-morph-common.js:1191:30)
    at RealFileSystemHost.readFileSync (/path-to-develop/test/vite-plugin-dts-test/node_modules/@ts-morph/common/dist/ts-morph-common.js:1894:23)
    at TransactionalFileSystem.readFileSync (/path-to-develop/test/vite-plugin-dts-test/node_modules/@ts-morph/common/dist/ts-morph-common.js:2431:32)
    at TransactionalFileSystem.readFileIfExistsSync (/path-to-develop/test/vite-plugin-dts-test/node_modules/@ts-morph/common/dist/ts-morph-common.js:2420:25)
    at CompilerFactory.addOrGetSourceFileFromFilePath (/path-to-develop/test/vite-plugin-dts-test/node_modules/ts-morph/dist/ts-morph.js:19160:61)
    at DirectoryCoordinator.addSourceFileAtPathIfExists (/path-to-develop/test/vite-plugin-dts-test/node_modules/ts-morph/dist/ts-morph.js:18633:37)
    at DirectoryCoordinator.addSourceFileAtPath (/path-to-develop/test/vite-plugin-dts-test/node_modules/ts-morph/dist/ts-morph.js:18639:33)
    at Project.addSourceFileAtPath (/path-to-develop/test/vite-plugin-dts-test/node_modules/ts-morph/dist/ts-morph.js:20086:51)
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

但其实 dts 已经生成出来了。
报错的根源不知道。我跟踪出来的是 \x00commonjsHelpers.js 这个"文件"存在于 vite 里,包含在某个 vite/dist/node/chunks/dep-xxx.js 中,仅仅是个声明:

const HELPERS_ID = '\0commonjsHelpers.js';

我修改了一下 dts 插件,简单过滤了一下,不添加这些 \0 开头的文件。

`copyDtsFiles` option has no effect

When the plugin is used with the copyDtsFiles option set to false, the src/env.d.ts file finds its way into the dist directory.

By looking at the code, I see that the option default value is never defined, nor used.
I'll send a quick pull requests to fix that as soon as possible 🙂

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.