vite-plugin-dts 1.7.3 → 2.0.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +326 -318
- package/README.zh-CN.md +8 -0
- package/dist/index.cjs +169 -36
- package/dist/index.mjs +169 -36
- package/package.json +4 -1
package/README.md
CHANGED
|
@@ -1,318 +1,326 @@
|
|
|
1
|
-
<h1 align="center">vite-plugin-dts</h1>
|
|
2
|
-
|
|
3
|
-
<p align="center">
|
|
4
|
-
A vite plugin that generates declaration files (<code>*.d.ts</code>) from <code>.ts(x)</code> or <code>.vue</code> source files when using vite in <a href="https://vitejs.dev/guide/build.html#library-mode">library mode</a>.
|
|
5
|
-
</p>
|
|
6
|
-
|
|
7
|
-
<p align="center">
|
|
8
|
-
<a href="https://www.npmjs.com/package/vite-plugin-dts">
|
|
9
|
-
<img src="https://img.shields.io/npm/v/vite-plugin-dts?color=orange&label=" alt="version" />
|
|
10
|
-
</a>
|
|
11
|
-
</p>
|
|
12
|
-
|
|
13
|
-
<p align="center">
|
|
14
|
-
<strong>English</strong> | <a href="./README.zh-CN.md">中文</a>
|
|
15
|
-
</p>
|
|
16
|
-
|
|
17
|
-
<p align="center"><strong>Notice: </strong><code>skipDiagnostics</code> option default to <code>false</code> since 1.7.0.</p>
|
|
18
|
-
|
|
19
|
-
<br />
|
|
20
|
-
|
|
21
|
-
## Install
|
|
22
|
-
|
|
23
|
-
```sh
|
|
24
|
-
pnpm add vite-plugin-dts -D
|
|
25
|
-
```
|
|
26
|
-
|
|
27
|
-
## Usage
|
|
28
|
-
|
|
29
|
-
In `vite.config.ts`:
|
|
30
|
-
|
|
31
|
-
```ts
|
|
32
|
-
import { resolve } from 'path'
|
|
33
|
-
import { defineConfig } from 'vite'
|
|
34
|
-
import dts from 'vite-plugin-dts'
|
|
35
|
-
|
|
36
|
-
export default defineConfig({
|
|
37
|
-
build: {
|
|
38
|
-
lib: {
|
|
39
|
-
entry: resolve(__dirname, 'src/index.ts'),
|
|
40
|
-
name: 'MyLib',
|
|
41
|
-
formats: ['es'],
|
|
42
|
-
fileName: 'my-lib'
|
|
43
|
-
}
|
|
44
|
-
},
|
|
45
|
-
plugins: [dts()]
|
|
46
|
-
})
|
|
47
|
-
```
|
|
48
|
-
|
|
49
|
-
In your component:
|
|
50
|
-
|
|
51
|
-
```vue
|
|
52
|
-
<template>
|
|
53
|
-
<div></div>
|
|
54
|
-
</template>
|
|
55
|
-
|
|
56
|
-
<script lang="ts">
|
|
57
|
-
// using defineComponent for inferring types
|
|
58
|
-
import { defineComponent } from 'vue'
|
|
59
|
-
|
|
60
|
-
export default defineComponent({
|
|
61
|
-
name: 'Component'
|
|
62
|
-
})
|
|
63
|
-
</script>
|
|
64
|
-
```
|
|
65
|
-
|
|
66
|
-
```vue
|
|
67
|
-
<script setup lang="ts">
|
|
68
|
-
// Need to access the defineProps returned value to
|
|
69
|
-
// infer types although you never use the props directly
|
|
70
|
-
const props = defineProps<{
|
|
71
|
-
color: 'blue' | 'red'
|
|
72
|
-
}>()
|
|
73
|
-
</script>
|
|
74
|
-
|
|
75
|
-
<template>
|
|
76
|
-
<div>{{ color }}</div>
|
|
77
|
-
</template>
|
|
78
|
-
```
|
|
79
|
-
|
|
80
|
-
## FAQ
|
|
81
|
-
|
|
82
|
-
Here are some FAQ's and solutions.
|
|
83
|
-
|
|
84
|
-
### Missing some declaration files after build (before `1.7.0`)
|
|
85
|
-
|
|
86
|
-
By default `skipDiagnostics` option is `true`, which means that type diagnostic will be skipped during the build process (some projects may have diagnostic tools such as `vue-tsc`). If there are some files with type errors which interrupt the build process, these files will not be emitted (declaration files won't be generated).
|
|
87
|
-
|
|
88
|
-
If your project doesn't use type diagnostic tools, you can set `skipDiagnostics: false` and `logDiagnostics: true` to turn on the diagnostic and log features of this plugin. It will help you check the type errors during build and log error information to the terminal.
|
|
89
|
-
|
|
90
|
-
### Take type error when using both `script` and `setup-script` in vue component
|
|
91
|
-
|
|
92
|
-
This is usually caused by using `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`, which results in a type error.
|
|
93
|
-
|
|
94
|
-
Here is a simple [example](https://github.com/qmhc/vite-plugin-dts/blob/main/example/components/BothScripts.vue), you should remove the `defineComponent` which in `script` and export a native object directly.
|
|
95
|
-
|
|
96
|
-
### Take errors that unable to infer types from packages which under `node_modules`
|
|
97
|
-
|
|
98
|
-
This is a exist issue when TypeScript inferring types from packages which under `node_modules` through soft links (pnpm), you can refer to this [issue](https://github.com/microsoft/TypeScript/issues/42873). Currently has a workaround that add `baseUrl` to your `tsconfig.json` and specify the `paths` for these packages:
|
|
99
|
-
|
|
100
|
-
```json
|
|
101
|
-
{
|
|
102
|
-
"compilerOptions": {
|
|
103
|
-
"baseUrl": ".",
|
|
104
|
-
"paths": {
|
|
105
|
-
"third-lib": ["node_modules/third-lib"]
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
```
|
|
110
|
-
|
|
111
|
-
## Options
|
|
112
|
-
|
|
113
|
-
```ts
|
|
114
|
-
import type { ts, Diagnostic } from 'ts-morph'
|
|
115
|
-
|
|
116
|
-
interface TransformWriteFile {
|
|
117
|
-
filePath?: string
|
|
118
|
-
content?: string
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
export interface PluginOptions {
|
|
122
|
-
/**
|
|
123
|
-
* Depends on the root directory
|
|
124
|
-
*
|
|
125
|
-
* Defaults base on your vite config root options
|
|
126
|
-
*/
|
|
127
|
-
root?: string
|
|
128
|
-
|
|
129
|
-
/**
|
|
130
|
-
* Declaration files output directory
|
|
131
|
-
*
|
|
132
|
-
* Can be specified a array to output to multiple directories
|
|
133
|
-
*
|
|
134
|
-
* Defaults base on your vite config output options
|
|
135
|
-
*/
|
|
136
|
-
outputDir?: string | string[]
|
|
137
|
-
|
|
138
|
-
/**
|
|
139
|
-
* Manually set the root path of the entry files
|
|
140
|
-
*
|
|
141
|
-
* The output path of each file will be caculated base on it
|
|
142
|
-
*
|
|
143
|
-
* Defaults is the smallest public path for all files
|
|
144
|
-
*/
|
|
145
|
-
entryRoot?: string
|
|
146
|
-
|
|
147
|
-
/**
|
|
148
|
-
* Project init compilerOptions using by ts-morph
|
|
149
|
-
*
|
|
150
|
-
* @default null
|
|
151
|
-
*/
|
|
152
|
-
compilerOptions?: ts.CompilerOptions | null
|
|
153
|
-
|
|
154
|
-
/**
|
|
155
|
-
* Project init tsconfig.json file path by ts-morph
|
|
156
|
-
*
|
|
157
|
-
* Plugin also resolve incldue and exclude files from tsconfig.json
|
|
158
|
-
*
|
|
159
|
-
* @default 'tsconfig.json'
|
|
160
|
-
*/
|
|
161
|
-
tsConfigFilePath?: string
|
|
162
|
-
|
|
163
|
-
/**
|
|
164
|
-
* Set which paths should exclude when transform aliases
|
|
165
|
-
*
|
|
166
|
-
* If it's regexp, it will test the original import path directly
|
|
167
|
-
*
|
|
168
|
-
* @default []
|
|
169
|
-
*/
|
|
170
|
-
aliasesExclude?: (string | RegExp)[]
|
|
171
|
-
|
|
172
|
-
/**
|
|
173
|
-
* Whether transform file name '.vue.d.ts' to '.d.ts'
|
|
174
|
-
*
|
|
175
|
-
* @default false
|
|
176
|
-
*/
|
|
177
|
-
cleanVueFileName?: boolean
|
|
178
|
-
|
|
179
|
-
/**
|
|
180
|
-
* Whether transform dynamic import to static
|
|
181
|
-
*
|
|
182
|
-
* Force true when `rollupTypes` is effective
|
|
183
|
-
*
|
|
184
|
-
* eg. 'import('vue').DefineComponent' to 'import { DefineComponent } from "vue"'
|
|
185
|
-
*
|
|
186
|
-
* @default false
|
|
187
|
-
*/
|
|
188
|
-
staticImport?: boolean
|
|
189
|
-
|
|
190
|
-
/**
|
|
191
|
-
* Manual set include glob
|
|
192
|
-
*
|
|
193
|
-
* Defaults base on your tsconfig.json include option
|
|
194
|
-
*/
|
|
195
|
-
include?: string | string[]
|
|
196
|
-
|
|
197
|
-
/**
|
|
198
|
-
* Manual set exclude glob
|
|
199
|
-
*
|
|
200
|
-
* Defaults base on your tsconfig.json exclude option, be 'node_modules/**' when empty
|
|
201
|
-
*/
|
|
202
|
-
exclude?: string | string[]
|
|
203
|
-
|
|
204
|
-
/**
|
|
205
|
-
* Do not emit if content of file only includes 'export {}'
|
|
206
|
-
*
|
|
207
|
-
* @default true
|
|
208
|
-
*/
|
|
209
|
-
clearPureImport?: boolean
|
|
210
|
-
|
|
211
|
-
/**
|
|
212
|
-
* Whether generate types entry file
|
|
213
|
-
*
|
|
214
|
-
* When true will from package.json types field if exists or `${outputDir}/index.d.ts`
|
|
215
|
-
*
|
|
216
|
-
* Force true when `rollupTypes` is effective
|
|
217
|
-
*
|
|
218
|
-
* @default false
|
|
219
|
-
*/
|
|
220
|
-
insertTypesEntry?: boolean
|
|
221
|
-
|
|
222
|
-
/**
|
|
223
|
-
* Set to rollup declaration files after emit
|
|
224
|
-
*
|
|
225
|
-
* Power by `@microsoft/api-extractor`, it will start a new program which takes some time
|
|
226
|
-
*
|
|
227
|
-
* @default false
|
|
228
|
-
*/
|
|
229
|
-
rollupTypes?: boolean
|
|
230
|
-
|
|
231
|
-
/**
|
|
232
|
-
* Whether copy .d.ts source files into outputDir
|
|
233
|
-
*
|
|
234
|
-
* @default true
|
|
235
|
-
*/
|
|
236
|
-
copyDtsFiles?: boolean
|
|
237
|
-
|
|
238
|
-
/**
|
|
239
|
-
* Whether emit nothing when has any diagnostic
|
|
240
|
-
*
|
|
241
|
-
* @default false
|
|
242
|
-
*/
|
|
243
|
-
noEmitOnError?: boolean
|
|
244
|
-
|
|
245
|
-
/**
|
|
246
|
-
* Whether skip typescript diagnostics
|
|
247
|
-
*
|
|
248
|
-
* Skip type diagnostics means that type errors will not interrupt the build process
|
|
249
|
-
*
|
|
250
|
-
* But for the source files with type errors will not be emitted
|
|
251
|
-
*
|
|
252
|
-
* @default false
|
|
253
|
-
*/
|
|
254
|
-
skipDiagnostics?: boolean
|
|
255
|
-
|
|
256
|
-
/**
|
|
257
|
-
* Whether log diagnostic informations
|
|
258
|
-
*
|
|
259
|
-
* Not effective when `skipDiagnostics` is true
|
|
260
|
-
*
|
|
261
|
-
* @deprecated
|
|
262
|
-
* @default false
|
|
263
|
-
*/
|
|
264
|
-
logDiagnostics?: boolean
|
|
265
|
-
|
|
266
|
-
/**
|
|
267
|
-
* Customize typescript lib folder path
|
|
268
|
-
*
|
|
269
|
-
* Should pass a relative path to root or a absolute path
|
|
270
|
-
*
|
|
271
|
-
* @default undefined
|
|
272
|
-
*/
|
|
273
|
-
libFolderPath?: string
|
|
274
|
-
|
|
275
|
-
/**
|
|
276
|
-
* After emit diagnostic hook
|
|
277
|
-
*
|
|
278
|
-
* According to the length to judge whether there is any type error
|
|
279
|
-
*
|
|
280
|
-
* @default () => {}
|
|
281
|
-
*/
|
|
282
|
-
afterDiagnostic?: (diagnostics: Diagnostic[]) => void | Promise<void>
|
|
283
|
-
|
|
284
|
-
/**
|
|
285
|
-
* Before declaration file be writed hook
|
|
286
|
-
*
|
|
287
|
-
* You can transform declaration file-path and content through it
|
|
288
|
-
*
|
|
289
|
-
* The file will be skipped when return exact false
|
|
290
|
-
*
|
|
291
|
-
* @default () => {}
|
|
292
|
-
*/
|
|
293
|
-
beforeWriteFile?: (filePath: string, content: string) => void | false | TransformWriteFile
|
|
294
|
-
|
|
295
|
-
/**
|
|
296
|
-
* After build hook
|
|
297
|
-
*
|
|
298
|
-
* It wil be called after all declaration files are written
|
|
299
|
-
*
|
|
300
|
-
* @default () => {}
|
|
301
|
-
*/
|
|
302
|
-
afterBuild?: () => void | Promise<void>
|
|
303
|
-
}
|
|
304
|
-
```
|
|
305
|
-
|
|
306
|
-
##
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
1
|
+
<h1 align="center">vite-plugin-dts</h1>
|
|
2
|
+
|
|
3
|
+
<p align="center">
|
|
4
|
+
A vite plugin that generates declaration files (<code>*.d.ts</code>) from <code>.ts(x)</code> or <code>.vue</code> source files when using vite in <a href="https://vitejs.dev/guide/build.html#library-mode">library mode</a>.
|
|
5
|
+
</p>
|
|
6
|
+
|
|
7
|
+
<p align="center">
|
|
8
|
+
<a href="https://www.npmjs.com/package/vite-plugin-dts">
|
|
9
|
+
<img src="https://img.shields.io/npm/v/vite-plugin-dts?color=orange&label=" alt="version" />
|
|
10
|
+
</a>
|
|
11
|
+
</p>
|
|
12
|
+
|
|
13
|
+
<p align="center">
|
|
14
|
+
<strong>English</strong> | <a href="./README.zh-CN.md">中文</a>
|
|
15
|
+
</p>
|
|
16
|
+
|
|
17
|
+
<p align="center"><strong>Notice: </strong><code>skipDiagnostics</code> option default to <code>false</code> since 1.7.0.</p>
|
|
18
|
+
|
|
19
|
+
<br />
|
|
20
|
+
|
|
21
|
+
## Install
|
|
22
|
+
|
|
23
|
+
```sh
|
|
24
|
+
pnpm add vite-plugin-dts -D
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Usage
|
|
28
|
+
|
|
29
|
+
In `vite.config.ts`:
|
|
30
|
+
|
|
31
|
+
```ts
|
|
32
|
+
import { resolve } from 'path'
|
|
33
|
+
import { defineConfig } from 'vite'
|
|
34
|
+
import dts from 'vite-plugin-dts'
|
|
35
|
+
|
|
36
|
+
export default defineConfig({
|
|
37
|
+
build: {
|
|
38
|
+
lib: {
|
|
39
|
+
entry: resolve(__dirname, 'src/index.ts'),
|
|
40
|
+
name: 'MyLib',
|
|
41
|
+
formats: ['es'],
|
|
42
|
+
fileName: 'my-lib'
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
plugins: [dts()]
|
|
46
|
+
})
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
In your component:
|
|
50
|
+
|
|
51
|
+
```vue
|
|
52
|
+
<template>
|
|
53
|
+
<div></div>
|
|
54
|
+
</template>
|
|
55
|
+
|
|
56
|
+
<script lang="ts">
|
|
57
|
+
// using defineComponent for inferring types
|
|
58
|
+
import { defineComponent } from 'vue'
|
|
59
|
+
|
|
60
|
+
export default defineComponent({
|
|
61
|
+
name: 'Component'
|
|
62
|
+
})
|
|
63
|
+
</script>
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
```vue
|
|
67
|
+
<script setup lang="ts">
|
|
68
|
+
// Need to access the defineProps returned value to
|
|
69
|
+
// infer types although you never use the props directly
|
|
70
|
+
const props = defineProps<{
|
|
71
|
+
color: 'blue' | 'red'
|
|
72
|
+
}>()
|
|
73
|
+
</script>
|
|
74
|
+
|
|
75
|
+
<template>
|
|
76
|
+
<div>{{ color }}</div>
|
|
77
|
+
</template>
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## FAQ
|
|
81
|
+
|
|
82
|
+
Here are some FAQ's and solutions.
|
|
83
|
+
|
|
84
|
+
### Missing some declaration files after build (before `1.7.0`)
|
|
85
|
+
|
|
86
|
+
By default `skipDiagnostics` option is `true`, which means that type diagnostic will be skipped during the build process (some projects may have diagnostic tools such as `vue-tsc`). If there are some files with type errors which interrupt the build process, these files will not be emitted (declaration files won't be generated).
|
|
87
|
+
|
|
88
|
+
If your project doesn't use type diagnostic tools, you can set `skipDiagnostics: false` and `logDiagnostics: true` to turn on the diagnostic and log features of this plugin. It will help you check the type errors during build and log error information to the terminal.
|
|
89
|
+
|
|
90
|
+
### Take type error when using both `script` and `setup-script` in vue component
|
|
91
|
+
|
|
92
|
+
This is usually caused by using `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`, which results in a type error.
|
|
93
|
+
|
|
94
|
+
Here is a simple [example](https://github.com/qmhc/vite-plugin-dts/blob/main/example/components/BothScripts.vue), you should remove the `defineComponent` which in `script` and export a native object directly.
|
|
95
|
+
|
|
96
|
+
### Take errors that unable to infer types from packages which under `node_modules`
|
|
97
|
+
|
|
98
|
+
This is a exist issue when TypeScript inferring types from packages which under `node_modules` through soft links (pnpm), you can refer to this [issue](https://github.com/microsoft/TypeScript/issues/42873). Currently has a workaround that add `baseUrl` to your `tsconfig.json` and specify the `paths` for these packages:
|
|
99
|
+
|
|
100
|
+
```json
|
|
101
|
+
{
|
|
102
|
+
"compilerOptions": {
|
|
103
|
+
"baseUrl": ".",
|
|
104
|
+
"paths": {
|
|
105
|
+
"third-lib": ["node_modules/third-lib"]
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
## Options
|
|
112
|
+
|
|
113
|
+
```ts
|
|
114
|
+
import type { ts, Diagnostic } from 'ts-morph'
|
|
115
|
+
|
|
116
|
+
interface TransformWriteFile {
|
|
117
|
+
filePath?: string
|
|
118
|
+
content?: string
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
export interface PluginOptions {
|
|
122
|
+
/**
|
|
123
|
+
* Depends on the root directory
|
|
124
|
+
*
|
|
125
|
+
* Defaults base on your vite config root options
|
|
126
|
+
*/
|
|
127
|
+
root?: string
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Declaration files output directory
|
|
131
|
+
*
|
|
132
|
+
* Can be specified a array to output to multiple directories
|
|
133
|
+
*
|
|
134
|
+
* Defaults base on your vite config output options
|
|
135
|
+
*/
|
|
136
|
+
outputDir?: string | string[]
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Manually set the root path of the entry files
|
|
140
|
+
*
|
|
141
|
+
* The output path of each file will be caculated base on it
|
|
142
|
+
*
|
|
143
|
+
* Defaults is the smallest public path for all files
|
|
144
|
+
*/
|
|
145
|
+
entryRoot?: string
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Project init compilerOptions using by ts-morph
|
|
149
|
+
*
|
|
150
|
+
* @default null
|
|
151
|
+
*/
|
|
152
|
+
compilerOptions?: ts.CompilerOptions | null
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Project init tsconfig.json file path by ts-morph
|
|
156
|
+
*
|
|
157
|
+
* Plugin also resolve incldue and exclude files from tsconfig.json
|
|
158
|
+
*
|
|
159
|
+
* @default 'tsconfig.json'
|
|
160
|
+
*/
|
|
161
|
+
tsConfigFilePath?: string
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* Set which paths should exclude when transform aliases
|
|
165
|
+
*
|
|
166
|
+
* If it's regexp, it will test the original import path directly
|
|
167
|
+
*
|
|
168
|
+
* @default []
|
|
169
|
+
*/
|
|
170
|
+
aliasesExclude?: (string | RegExp)[]
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* Whether transform file name '.vue.d.ts' to '.d.ts'
|
|
174
|
+
*
|
|
175
|
+
* @default false
|
|
176
|
+
*/
|
|
177
|
+
cleanVueFileName?: boolean
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* Whether transform dynamic import to static
|
|
181
|
+
*
|
|
182
|
+
* Force true when `rollupTypes` is effective
|
|
183
|
+
*
|
|
184
|
+
* eg. 'import('vue').DefineComponent' to 'import { DefineComponent } from "vue"'
|
|
185
|
+
*
|
|
186
|
+
* @default false
|
|
187
|
+
*/
|
|
188
|
+
staticImport?: boolean
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* Manual set include glob
|
|
192
|
+
*
|
|
193
|
+
* Defaults base on your tsconfig.json include option
|
|
194
|
+
*/
|
|
195
|
+
include?: string | string[]
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* Manual set exclude glob
|
|
199
|
+
*
|
|
200
|
+
* Defaults base on your tsconfig.json exclude option, be 'node_modules/**' when empty
|
|
201
|
+
*/
|
|
202
|
+
exclude?: string | string[]
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* Do not emit if content of file only includes 'export {}'
|
|
206
|
+
*
|
|
207
|
+
* @default true
|
|
208
|
+
*/
|
|
209
|
+
clearPureImport?: boolean
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* Whether generate types entry file
|
|
213
|
+
*
|
|
214
|
+
* When true will from package.json types field if exists or `${outputDir}/index.d.ts`
|
|
215
|
+
*
|
|
216
|
+
* Force true when `rollupTypes` is effective
|
|
217
|
+
*
|
|
218
|
+
* @default false
|
|
219
|
+
*/
|
|
220
|
+
insertTypesEntry?: boolean
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* Set to rollup declaration files after emit
|
|
224
|
+
*
|
|
225
|
+
* Power by `@microsoft/api-extractor`, it will start a new program which takes some time
|
|
226
|
+
*
|
|
227
|
+
* @default false
|
|
228
|
+
*/
|
|
229
|
+
rollupTypes?: boolean
|
|
230
|
+
|
|
231
|
+
/**
|
|
232
|
+
* Whether copy .d.ts source files into outputDir
|
|
233
|
+
*
|
|
234
|
+
* @default true
|
|
235
|
+
*/
|
|
236
|
+
copyDtsFiles?: boolean
|
|
237
|
+
|
|
238
|
+
/**
|
|
239
|
+
* Whether emit nothing when has any diagnostic
|
|
240
|
+
*
|
|
241
|
+
* @default false
|
|
242
|
+
*/
|
|
243
|
+
noEmitOnError?: boolean
|
|
244
|
+
|
|
245
|
+
/**
|
|
246
|
+
* Whether skip typescript diagnostics
|
|
247
|
+
*
|
|
248
|
+
* Skip type diagnostics means that type errors will not interrupt the build process
|
|
249
|
+
*
|
|
250
|
+
* But for the source files with type errors will not be emitted
|
|
251
|
+
*
|
|
252
|
+
* @default false
|
|
253
|
+
*/
|
|
254
|
+
skipDiagnostics?: boolean
|
|
255
|
+
|
|
256
|
+
/**
|
|
257
|
+
* Whether log diagnostic informations
|
|
258
|
+
*
|
|
259
|
+
* Not effective when `skipDiagnostics` is true
|
|
260
|
+
*
|
|
261
|
+
* @deprecated
|
|
262
|
+
* @default false
|
|
263
|
+
*/
|
|
264
|
+
logDiagnostics?: boolean
|
|
265
|
+
|
|
266
|
+
/**
|
|
267
|
+
* Customize typescript lib folder path
|
|
268
|
+
*
|
|
269
|
+
* Should pass a relative path to root or a absolute path
|
|
270
|
+
*
|
|
271
|
+
* @default undefined
|
|
272
|
+
*/
|
|
273
|
+
libFolderPath?: string
|
|
274
|
+
|
|
275
|
+
/**
|
|
276
|
+
* After emit diagnostic hook
|
|
277
|
+
*
|
|
278
|
+
* According to the length to judge whether there is any type error
|
|
279
|
+
*
|
|
280
|
+
* @default () => {}
|
|
281
|
+
*/
|
|
282
|
+
afterDiagnostic?: (diagnostics: Diagnostic[]) => void | Promise<void>
|
|
283
|
+
|
|
284
|
+
/**
|
|
285
|
+
* Before declaration file be writed hook
|
|
286
|
+
*
|
|
287
|
+
* You can transform declaration file-path and content through it
|
|
288
|
+
*
|
|
289
|
+
* The file will be skipped when return exact false
|
|
290
|
+
*
|
|
291
|
+
* @default () => {}
|
|
292
|
+
*/
|
|
293
|
+
beforeWriteFile?: (filePath: string, content: string) => void | false | TransformWriteFile
|
|
294
|
+
|
|
295
|
+
/**
|
|
296
|
+
* After build hook
|
|
297
|
+
*
|
|
298
|
+
* It wil be called after all declaration files are written
|
|
299
|
+
*
|
|
300
|
+
* @default () => {}
|
|
301
|
+
*/
|
|
302
|
+
afterBuild?: () => void | Promise<void>
|
|
303
|
+
}
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
## Contributors
|
|
307
|
+
|
|
308
|
+
Thanks for all their contributions!
|
|
309
|
+
|
|
310
|
+
<a href="https://github.com/qmhc/vite-plugin-dts/graphs/contributors">
|
|
311
|
+
<img src="https://contrib.rocks/image?repo=qmhc/vite-plugin-dts" />
|
|
312
|
+
</a>
|
|
313
|
+
|
|
314
|
+
## Example
|
|
315
|
+
|
|
316
|
+
Clone and run the following script:
|
|
317
|
+
|
|
318
|
+
```sh
|
|
319
|
+
pnpm run test:ts
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
Then check `examples/ts/types`.
|
|
323
|
+
|
|
324
|
+
## License
|
|
325
|
+
|
|
326
|
+
MIT License.
|
package/README.zh-CN.md
CHANGED
|
@@ -302,6 +302,14 @@ export interface PluginOptions {
|
|
|
302
302
|
}
|
|
303
303
|
```
|
|
304
304
|
|
|
305
|
+
## 贡献者
|
|
306
|
+
|
|
307
|
+
感谢他们的所做的一切贡献!
|
|
308
|
+
|
|
309
|
+
<a href="https://github.com/qmhc/vite-plugin-dts/graphs/contributors">
|
|
310
|
+
<img src="https://contrib.rocks/image?repo=qmhc/vite-plugin-dts" />
|
|
311
|
+
</a>
|
|
312
|
+
|
|
305
313
|
## 示例
|
|
306
314
|
|
|
307
315
|
克隆项目然后执行下列命令:
|
package/dist/index.cjs
CHANGED
|
@@ -12,6 +12,8 @@ const typescript = require('typescript');
|
|
|
12
12
|
const pluginutils = require('@rollup/pluginutils');
|
|
13
13
|
const node_fs = require('node:fs');
|
|
14
14
|
const node_module = require('node:module');
|
|
15
|
+
const parser = require('@babel/parser');
|
|
16
|
+
const MagicString = require('magic-string');
|
|
15
17
|
const apiExtractor = require('@microsoft/api-extractor');
|
|
16
18
|
const Collector_js = require('@microsoft/api-extractor/lib/collector/Collector.js');
|
|
17
19
|
const MessageRouter_js = require('@microsoft/api-extractor/lib/collector/MessageRouter.js');
|
|
@@ -240,8 +242,6 @@ function transferSetupPosition(content) {
|
|
|
240
242
|
return content;
|
|
241
243
|
}
|
|
242
244
|
|
|
243
|
-
const exportDefaultRE = /export\s+default/;
|
|
244
|
-
const exportDefaultClassRE = /(?:(?:^|\n|;)\s*)export\s+default\s+class\s+([\w$]+)/;
|
|
245
245
|
const noScriptContent = "import { defineComponent } from 'vue'\nexport default defineComponent({})";
|
|
246
246
|
const _require = node_module.createRequire((typeof document === 'undefined' ? new (require('u' + 'rl').URL)('file:' + __filename).href : (document.currentScript && document.currentScript.src || new URL('index.cjs', document.baseURI).href)));
|
|
247
247
|
let index = 1;
|
|
@@ -299,58 +299,177 @@ function setCompileRoot(root) {
|
|
|
299
299
|
}
|
|
300
300
|
}
|
|
301
301
|
function parseCode(code) {
|
|
302
|
-
const { parse } = requireCompiler();
|
|
302
|
+
const { parse: parseVueCode } = requireCompiler();
|
|
303
303
|
let descriptor;
|
|
304
304
|
if (isVue3()) {
|
|
305
|
-
descriptor =
|
|
305
|
+
descriptor = parseVueCode(code).descriptor;
|
|
306
306
|
} else {
|
|
307
|
-
descriptor =
|
|
307
|
+
descriptor = parseVueCode({ source: code });
|
|
308
308
|
}
|
|
309
309
|
return descriptor;
|
|
310
310
|
}
|
|
311
|
+
function transformJsToTs(script) {
|
|
312
|
+
if (!script)
|
|
313
|
+
return script;
|
|
314
|
+
const lang = !script.lang || script.lang === "js" ? "ts" : script.lang === "jsx" ? "tsx" : script.lang;
|
|
315
|
+
return { ...script, lang };
|
|
316
|
+
}
|
|
317
|
+
function preprocessVueCode(code, setupScript) {
|
|
318
|
+
const plugins = ["typescript", "decorators-legacy", "jsx"];
|
|
319
|
+
const scriptAst = parser.parse(code, { sourceType: "module", plugins }).program.body;
|
|
320
|
+
const source = new MagicString(code);
|
|
321
|
+
let propsTypeName;
|
|
322
|
+
let propsTypeLiteral;
|
|
323
|
+
if (setupScript) {
|
|
324
|
+
let processDefineProps = function(node) {
|
|
325
|
+
if (node.type === "CallExpression" && node.callee.type === "Identifier") {
|
|
326
|
+
if (node.callee.name === "defineProps") {
|
|
327
|
+
defineProps = node;
|
|
328
|
+
return true;
|
|
329
|
+
} else if (node.callee.name === "withDefaults") {
|
|
330
|
+
const propsDef = node.arguments[0];
|
|
331
|
+
if (propsDef.type === "CallExpression" && propsDef.callee.type === "Identifier" && propsDef.callee.name === "defineProps") {
|
|
332
|
+
defineProps = propsDef;
|
|
333
|
+
return true;
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
return false;
|
|
338
|
+
};
|
|
339
|
+
const setupAst = parser.parse(setupScript.content, { sourceType: "module", plugins }).program.body;
|
|
340
|
+
let defineProps;
|
|
341
|
+
for (const node of setupAst) {
|
|
342
|
+
if (node.type === "ExpressionStatement") {
|
|
343
|
+
processDefineProps(node.expression);
|
|
344
|
+
} else if (node.type === "VariableDeclaration" && !node.declare) {
|
|
345
|
+
for (const decl of node.declarations) {
|
|
346
|
+
if (decl.init && processDefineProps(decl.init)) {
|
|
347
|
+
break;
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
if (defineProps) {
|
|
352
|
+
const type = defineProps.typeParameters?.params[0];
|
|
353
|
+
if (type && type.type === "TSTypeReference" && type.typeName.type === "Identifier") {
|
|
354
|
+
propsTypeName = type.typeName.name;
|
|
355
|
+
} else if (type?.type === "TSTypeLiteral") {
|
|
356
|
+
propsTypeName = "__DTS_Props__";
|
|
357
|
+
propsTypeLiteral = setupScript.content.substring(type.start, type.end);
|
|
358
|
+
}
|
|
359
|
+
break;
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
for (const node of scriptAst) {
|
|
364
|
+
if (node.type === "ExportDefaultDeclaration") {
|
|
365
|
+
let options;
|
|
366
|
+
if (node.declaration.type === "ObjectExpression") {
|
|
367
|
+
options = node.declaration.properties;
|
|
368
|
+
} else if (node.declaration.type === "CallExpression" && node.declaration.arguments[0].type === "ObjectExpression") {
|
|
369
|
+
options = node.declaration.arguments[0].properties;
|
|
370
|
+
}
|
|
371
|
+
if (options) {
|
|
372
|
+
for (const option of options) {
|
|
373
|
+
if (propsTypeName && option.type === "ObjectProperty" && option.key.type === "Identifier" && option.key.name === "props" && option.value.type === "ObjectExpression") {
|
|
374
|
+
for (const prop of option.value.properties) {
|
|
375
|
+
if (prop.type === "ObjectProperty" && prop.key.type === "Identifier") {
|
|
376
|
+
if (prop.value.type === "ObjectExpression") {
|
|
377
|
+
for (const propDef of prop.value.properties) {
|
|
378
|
+
if (propDef.type === "ObjectProperty" && propDef.key.type === "Identifier" && propDef.key.name === "type") {
|
|
379
|
+
source.prependLeft(
|
|
380
|
+
propDef.end,
|
|
381
|
+
` as unknown as __PropType<${propsTypeName}['${prop.key.name}']>`
|
|
382
|
+
);
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
} else {
|
|
386
|
+
source.prependLeft(
|
|
387
|
+
prop.end,
|
|
388
|
+
` as unknown as __PropType<${propsTypeName}['${prop.key.name}']>`
|
|
389
|
+
);
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
if (option.type === "ObjectProperty" && option.key.type === "Identifier" && option.key.name === "components") {
|
|
395
|
+
source.remove(option.start, option.end);
|
|
396
|
+
}
|
|
397
|
+
if (option.type === "ObjectMethod" && option.key.type === "Identifier" && option.key.name === "setup") {
|
|
398
|
+
let exposed;
|
|
399
|
+
let returned;
|
|
400
|
+
for (const node2 of option.body.body) {
|
|
401
|
+
if (!exposed && node2.type === "ExpressionStatement" && node2.expression.type === "CallExpression" && node2.expression.callee.type === "Identifier" && node2.expression.callee.name === "expose") {
|
|
402
|
+
exposed = node2.expression.arguments[0];
|
|
403
|
+
continue;
|
|
404
|
+
}
|
|
405
|
+
if (node2.type === "ReturnStatement") {
|
|
406
|
+
returned = node2;
|
|
407
|
+
break;
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
const newReturned = exposed && exposed.type === "ObjectExpression" ? `return ${code.substring(exposed.start, exposed.end)}` : setupScript ? "return {}" : "";
|
|
411
|
+
if (newReturned) {
|
|
412
|
+
if (returned) {
|
|
413
|
+
source.overwrite(returned.start, returned.end, newReturned);
|
|
414
|
+
} else if (option.body.body.length) {
|
|
415
|
+
source.appendRight(option.body.body.at(-1).end, `
|
|
416
|
+
${newReturned}
|
|
417
|
+
`);
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
break;
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
if (propsTypeName) {
|
|
427
|
+
if (propsTypeLiteral) {
|
|
428
|
+
source.prepend(`
|
|
429
|
+
type ${propsTypeName} = ${propsTypeLiteral}
|
|
430
|
+
|
|
431
|
+
`);
|
|
432
|
+
}
|
|
433
|
+
source.prepend("import type { PropType as __PropType } from 'vue'\n");
|
|
434
|
+
}
|
|
435
|
+
return source.toString();
|
|
436
|
+
}
|
|
311
437
|
function compileVueCode(code) {
|
|
312
438
|
const { compileScript, rewriteDefault } = requireCompiler();
|
|
313
439
|
const descriptor = parseCode(code);
|
|
314
440
|
const { script, scriptSetup } = descriptor;
|
|
315
|
-
let
|
|
316
|
-
let
|
|
441
|
+
let error;
|
|
442
|
+
let content;
|
|
443
|
+
let ext = "js";
|
|
317
444
|
if (script || scriptSetup) {
|
|
445
|
+
const compiled = compileScript(
|
|
446
|
+
{
|
|
447
|
+
...descriptor,
|
|
448
|
+
script: transformJsToTs(script),
|
|
449
|
+
scriptSetup: transformJsToTs(scriptSetup),
|
|
450
|
+
cssVars: []
|
|
451
|
+
},
|
|
452
|
+
{ id: `${index++}` }
|
|
453
|
+
);
|
|
454
|
+
try {
|
|
455
|
+
content = preprocessVueCode(compiled.content, scriptSetup);
|
|
456
|
+
} catch (e) {
|
|
457
|
+
error = e;
|
|
458
|
+
content = compiled.content;
|
|
459
|
+
}
|
|
460
|
+
content = rewriteDefault(content, "_sfc_main", ["typescript", "decorators-legacy"]);
|
|
318
461
|
if (scriptSetup) {
|
|
319
|
-
const compiled = compileScript(descriptor, {
|
|
320
|
-
id: `${index++}`
|
|
321
|
-
});
|
|
322
|
-
const classMatch = compiled.content.match(exportDefaultClassRE);
|
|
323
|
-
const plugins = scriptSetup.lang === "ts" ? ["typescript", "decorators-legacy"] : void 0;
|
|
324
|
-
if (classMatch) {
|
|
325
|
-
content = compiled.content.replace(exportDefaultClassRE, "\nclass $1") + `
|
|
326
|
-
const _sfc_main = ${classMatch[1]}`;
|
|
327
|
-
if (exportDefaultRE.test(content)) {
|
|
328
|
-
content = rewriteDefault(compiled.content, "_sfc_main", plugins);
|
|
329
|
-
}
|
|
330
|
-
} else {
|
|
331
|
-
content = rewriteDefault(compiled.content, "_sfc_main", plugins);
|
|
332
|
-
}
|
|
333
462
|
content = transferSetupPosition(content);
|
|
334
|
-
content = content.replace(/(const __returned__\s?=\s?\{[\s\S]+?)(props)(\s?\})/, "$1props: props as any$3").replace(
|
|
335
|
-
/(const __returned__\s?=\s?\{[\s\S]+?)(props,)([\s\S]+?)/,
|
|
336
|
-
"$1props: props as any,$3"
|
|
337
|
-
);
|
|
338
|
-
content += "\nexport default _sfc_main\n";
|
|
339
463
|
ext = scriptSetup.lang || "js";
|
|
340
464
|
} else if (script && script.content) {
|
|
341
|
-
content = rewriteDefault(
|
|
342
|
-
script.content,
|
|
343
|
-
"_sfc_main",
|
|
344
|
-
script.lang === "ts" ? ["typescript", "decorators-legacy"] : void 0
|
|
345
|
-
);
|
|
346
|
-
content += "\nexport default _sfc_main\n";
|
|
347
465
|
ext = script.lang || "js";
|
|
348
466
|
}
|
|
467
|
+
content += "\nexport default _sfc_main\n";
|
|
349
468
|
} else {
|
|
350
469
|
content = noScriptContent;
|
|
351
470
|
ext = "ts";
|
|
352
471
|
}
|
|
353
|
-
return { content, ext };
|
|
472
|
+
return { error, content, ext };
|
|
354
473
|
}
|
|
355
474
|
|
|
356
475
|
const dtsRE$1 = /\.d\.tsx?$/;
|
|
@@ -488,6 +607,7 @@ function dtsPlugin(options = {}) {
|
|
|
488
607
|
const sourceDtsFiles = /* @__PURE__ */ new Set();
|
|
489
608
|
let hasJsVue = false;
|
|
490
609
|
let allowJs = false;
|
|
610
|
+
let transformError = false;
|
|
491
611
|
return {
|
|
492
612
|
name: "vite:dts",
|
|
493
613
|
apply: "build",
|
|
@@ -568,11 +688,12 @@ ${kolorist.cyan(
|
|
|
568
688
|
rootDir: compilerOptions.rootDir || root,
|
|
569
689
|
noEmitOnError,
|
|
570
690
|
outDir: ".",
|
|
571
|
-
declarationDir:
|
|
691
|
+
declarationDir: void 0,
|
|
572
692
|
noUnusedParameters: false,
|
|
573
693
|
declaration: true,
|
|
574
694
|
noEmit: false,
|
|
575
|
-
emitDeclarationOnly: true
|
|
695
|
+
emitDeclarationOnly: true,
|
|
696
|
+
composite: false
|
|
576
697
|
}),
|
|
577
698
|
tsConfigFilePath: tsConfigPath,
|
|
578
699
|
skipAddingFilesFromTsConfig: true,
|
|
@@ -615,7 +736,19 @@ ${kolorist.cyan(
|
|
|
615
736
|
return null;
|
|
616
737
|
}
|
|
617
738
|
if (vueRE.test(id)) {
|
|
618
|
-
const { content, ext } = compileVueCode(code);
|
|
739
|
+
const { error, content, ext } = compileVueCode(code);
|
|
740
|
+
if (!transformError && error) {
|
|
741
|
+
logger.error(
|
|
742
|
+
kolorist.red(
|
|
743
|
+
`
|
|
744
|
+
${kolorist.cyan(
|
|
745
|
+
"[vite:dts]"
|
|
746
|
+
)} A error occurred when transform code, maybe there are some inertnal bugs.
|
|
747
|
+
`
|
|
748
|
+
)
|
|
749
|
+
);
|
|
750
|
+
transformError = true;
|
|
751
|
+
}
|
|
619
752
|
if (content) {
|
|
620
753
|
if (ext === "js" || ext === "jsx")
|
|
621
754
|
hasJsVue = true;
|
package/dist/index.mjs
CHANGED
|
@@ -17,6 +17,8 @@ import typescript from 'typescript';
|
|
|
17
17
|
import { createFilter } from '@rollup/pluginutils';
|
|
18
18
|
import { existsSync, readdirSync, lstatSync, rmdirSync } from 'node:fs';
|
|
19
19
|
import { createRequire } from 'node:module';
|
|
20
|
+
import { parse } from '@babel/parser';
|
|
21
|
+
import MagicString from 'magic-string';
|
|
20
22
|
import { ExtractorConfig, CompilerState } from '@microsoft/api-extractor';
|
|
21
23
|
import { Collector } from '@microsoft/api-extractor/lib/collector/Collector.js';
|
|
22
24
|
import { MessageRouter } from '@microsoft/api-extractor/lib/collector/MessageRouter.js';
|
|
@@ -245,8 +247,6 @@ function transferSetupPosition(content) {
|
|
|
245
247
|
return content;
|
|
246
248
|
}
|
|
247
249
|
|
|
248
|
-
const exportDefaultRE = /export\s+default/;
|
|
249
|
-
const exportDefaultClassRE = /(?:(?:^|\n|;)\s*)export\s+default\s+class\s+([\w$]+)/;
|
|
250
250
|
const noScriptContent = "import { defineComponent } from 'vue'\nexport default defineComponent({})";
|
|
251
251
|
const _require = createRequire(import.meta.url);
|
|
252
252
|
let index = 1;
|
|
@@ -304,58 +304,177 @@ function setCompileRoot(root) {
|
|
|
304
304
|
}
|
|
305
305
|
}
|
|
306
306
|
function parseCode(code) {
|
|
307
|
-
const { parse } = requireCompiler();
|
|
307
|
+
const { parse: parseVueCode } = requireCompiler();
|
|
308
308
|
let descriptor;
|
|
309
309
|
if (isVue3()) {
|
|
310
|
-
descriptor =
|
|
310
|
+
descriptor = parseVueCode(code).descriptor;
|
|
311
311
|
} else {
|
|
312
|
-
descriptor =
|
|
312
|
+
descriptor = parseVueCode({ source: code });
|
|
313
313
|
}
|
|
314
314
|
return descriptor;
|
|
315
315
|
}
|
|
316
|
+
function transformJsToTs(script) {
|
|
317
|
+
if (!script)
|
|
318
|
+
return script;
|
|
319
|
+
const lang = !script.lang || script.lang === "js" ? "ts" : script.lang === "jsx" ? "tsx" : script.lang;
|
|
320
|
+
return { ...script, lang };
|
|
321
|
+
}
|
|
322
|
+
function preprocessVueCode(code, setupScript) {
|
|
323
|
+
const plugins = ["typescript", "decorators-legacy", "jsx"];
|
|
324
|
+
const scriptAst = parse(code, { sourceType: "module", plugins }).program.body;
|
|
325
|
+
const source = new MagicString(code);
|
|
326
|
+
let propsTypeName;
|
|
327
|
+
let propsTypeLiteral;
|
|
328
|
+
if (setupScript) {
|
|
329
|
+
let processDefineProps = function(node) {
|
|
330
|
+
if (node.type === "CallExpression" && node.callee.type === "Identifier") {
|
|
331
|
+
if (node.callee.name === "defineProps") {
|
|
332
|
+
defineProps = node;
|
|
333
|
+
return true;
|
|
334
|
+
} else if (node.callee.name === "withDefaults") {
|
|
335
|
+
const propsDef = node.arguments[0];
|
|
336
|
+
if (propsDef.type === "CallExpression" && propsDef.callee.type === "Identifier" && propsDef.callee.name === "defineProps") {
|
|
337
|
+
defineProps = propsDef;
|
|
338
|
+
return true;
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
return false;
|
|
343
|
+
};
|
|
344
|
+
const setupAst = parse(setupScript.content, { sourceType: "module", plugins }).program.body;
|
|
345
|
+
let defineProps;
|
|
346
|
+
for (const node of setupAst) {
|
|
347
|
+
if (node.type === "ExpressionStatement") {
|
|
348
|
+
processDefineProps(node.expression);
|
|
349
|
+
} else if (node.type === "VariableDeclaration" && !node.declare) {
|
|
350
|
+
for (const decl of node.declarations) {
|
|
351
|
+
if (decl.init && processDefineProps(decl.init)) {
|
|
352
|
+
break;
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
if (defineProps) {
|
|
357
|
+
const type = defineProps.typeParameters?.params[0];
|
|
358
|
+
if (type && type.type === "TSTypeReference" && type.typeName.type === "Identifier") {
|
|
359
|
+
propsTypeName = type.typeName.name;
|
|
360
|
+
} else if (type?.type === "TSTypeLiteral") {
|
|
361
|
+
propsTypeName = "__DTS_Props__";
|
|
362
|
+
propsTypeLiteral = setupScript.content.substring(type.start, type.end);
|
|
363
|
+
}
|
|
364
|
+
break;
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
for (const node of scriptAst) {
|
|
369
|
+
if (node.type === "ExportDefaultDeclaration") {
|
|
370
|
+
let options;
|
|
371
|
+
if (node.declaration.type === "ObjectExpression") {
|
|
372
|
+
options = node.declaration.properties;
|
|
373
|
+
} else if (node.declaration.type === "CallExpression" && node.declaration.arguments[0].type === "ObjectExpression") {
|
|
374
|
+
options = node.declaration.arguments[0].properties;
|
|
375
|
+
}
|
|
376
|
+
if (options) {
|
|
377
|
+
for (const option of options) {
|
|
378
|
+
if (propsTypeName && option.type === "ObjectProperty" && option.key.type === "Identifier" && option.key.name === "props" && option.value.type === "ObjectExpression") {
|
|
379
|
+
for (const prop of option.value.properties) {
|
|
380
|
+
if (prop.type === "ObjectProperty" && prop.key.type === "Identifier") {
|
|
381
|
+
if (prop.value.type === "ObjectExpression") {
|
|
382
|
+
for (const propDef of prop.value.properties) {
|
|
383
|
+
if (propDef.type === "ObjectProperty" && propDef.key.type === "Identifier" && propDef.key.name === "type") {
|
|
384
|
+
source.prependLeft(
|
|
385
|
+
propDef.end,
|
|
386
|
+
` as unknown as __PropType<${propsTypeName}['${prop.key.name}']>`
|
|
387
|
+
);
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
} else {
|
|
391
|
+
source.prependLeft(
|
|
392
|
+
prop.end,
|
|
393
|
+
` as unknown as __PropType<${propsTypeName}['${prop.key.name}']>`
|
|
394
|
+
);
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
if (option.type === "ObjectProperty" && option.key.type === "Identifier" && option.key.name === "components") {
|
|
400
|
+
source.remove(option.start, option.end);
|
|
401
|
+
}
|
|
402
|
+
if (option.type === "ObjectMethod" && option.key.type === "Identifier" && option.key.name === "setup") {
|
|
403
|
+
let exposed;
|
|
404
|
+
let returned;
|
|
405
|
+
for (const node2 of option.body.body) {
|
|
406
|
+
if (!exposed && node2.type === "ExpressionStatement" && node2.expression.type === "CallExpression" && node2.expression.callee.type === "Identifier" && node2.expression.callee.name === "expose") {
|
|
407
|
+
exposed = node2.expression.arguments[0];
|
|
408
|
+
continue;
|
|
409
|
+
}
|
|
410
|
+
if (node2.type === "ReturnStatement") {
|
|
411
|
+
returned = node2;
|
|
412
|
+
break;
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
const newReturned = exposed && exposed.type === "ObjectExpression" ? `return ${code.substring(exposed.start, exposed.end)}` : setupScript ? "return {}" : "";
|
|
416
|
+
if (newReturned) {
|
|
417
|
+
if (returned) {
|
|
418
|
+
source.overwrite(returned.start, returned.end, newReturned);
|
|
419
|
+
} else if (option.body.body.length) {
|
|
420
|
+
source.appendRight(option.body.body.at(-1).end, `
|
|
421
|
+
${newReturned}
|
|
422
|
+
`);
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
break;
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
if (propsTypeName) {
|
|
432
|
+
if (propsTypeLiteral) {
|
|
433
|
+
source.prepend(`
|
|
434
|
+
type ${propsTypeName} = ${propsTypeLiteral}
|
|
435
|
+
|
|
436
|
+
`);
|
|
437
|
+
}
|
|
438
|
+
source.prepend("import type { PropType as __PropType } from 'vue'\n");
|
|
439
|
+
}
|
|
440
|
+
return source.toString();
|
|
441
|
+
}
|
|
316
442
|
function compileVueCode(code) {
|
|
317
443
|
const { compileScript, rewriteDefault } = requireCompiler();
|
|
318
444
|
const descriptor = parseCode(code);
|
|
319
445
|
const { script, scriptSetup } = descriptor;
|
|
320
|
-
let
|
|
321
|
-
let
|
|
446
|
+
let error;
|
|
447
|
+
let content;
|
|
448
|
+
let ext = "js";
|
|
322
449
|
if (script || scriptSetup) {
|
|
450
|
+
const compiled = compileScript(
|
|
451
|
+
{
|
|
452
|
+
...descriptor,
|
|
453
|
+
script: transformJsToTs(script),
|
|
454
|
+
scriptSetup: transformJsToTs(scriptSetup),
|
|
455
|
+
cssVars: []
|
|
456
|
+
},
|
|
457
|
+
{ id: `${index++}` }
|
|
458
|
+
);
|
|
459
|
+
try {
|
|
460
|
+
content = preprocessVueCode(compiled.content, scriptSetup);
|
|
461
|
+
} catch (e) {
|
|
462
|
+
error = e;
|
|
463
|
+
content = compiled.content;
|
|
464
|
+
}
|
|
465
|
+
content = rewriteDefault(content, "_sfc_main", ["typescript", "decorators-legacy"]);
|
|
323
466
|
if (scriptSetup) {
|
|
324
|
-
const compiled = compileScript(descriptor, {
|
|
325
|
-
id: `${index++}`
|
|
326
|
-
});
|
|
327
|
-
const classMatch = compiled.content.match(exportDefaultClassRE);
|
|
328
|
-
const plugins = scriptSetup.lang === "ts" ? ["typescript", "decorators-legacy"] : void 0;
|
|
329
|
-
if (classMatch) {
|
|
330
|
-
content = compiled.content.replace(exportDefaultClassRE, "\nclass $1") + `
|
|
331
|
-
const _sfc_main = ${classMatch[1]}`;
|
|
332
|
-
if (exportDefaultRE.test(content)) {
|
|
333
|
-
content = rewriteDefault(compiled.content, "_sfc_main", plugins);
|
|
334
|
-
}
|
|
335
|
-
} else {
|
|
336
|
-
content = rewriteDefault(compiled.content, "_sfc_main", plugins);
|
|
337
|
-
}
|
|
338
467
|
content = transferSetupPosition(content);
|
|
339
|
-
content = content.replace(/(const __returned__\s?=\s?\{[\s\S]+?)(props)(\s?\})/, "$1props: props as any$3").replace(
|
|
340
|
-
/(const __returned__\s?=\s?\{[\s\S]+?)(props,)([\s\S]+?)/,
|
|
341
|
-
"$1props: props as any,$3"
|
|
342
|
-
);
|
|
343
|
-
content += "\nexport default _sfc_main\n";
|
|
344
468
|
ext = scriptSetup.lang || "js";
|
|
345
469
|
} else if (script && script.content) {
|
|
346
|
-
content = rewriteDefault(
|
|
347
|
-
script.content,
|
|
348
|
-
"_sfc_main",
|
|
349
|
-
script.lang === "ts" ? ["typescript", "decorators-legacy"] : void 0
|
|
350
|
-
);
|
|
351
|
-
content += "\nexport default _sfc_main\n";
|
|
352
470
|
ext = script.lang || "js";
|
|
353
471
|
}
|
|
472
|
+
content += "\nexport default _sfc_main\n";
|
|
354
473
|
} else {
|
|
355
474
|
content = noScriptContent;
|
|
356
475
|
ext = "ts";
|
|
357
476
|
}
|
|
358
|
-
return { content, ext };
|
|
477
|
+
return { error, content, ext };
|
|
359
478
|
}
|
|
360
479
|
|
|
361
480
|
const dtsRE$1 = /\.d\.tsx?$/;
|
|
@@ -493,6 +612,7 @@ function dtsPlugin(options = {}) {
|
|
|
493
612
|
const sourceDtsFiles = /* @__PURE__ */ new Set();
|
|
494
613
|
let hasJsVue = false;
|
|
495
614
|
let allowJs = false;
|
|
615
|
+
let transformError = false;
|
|
496
616
|
return {
|
|
497
617
|
name: "vite:dts",
|
|
498
618
|
apply: "build",
|
|
@@ -573,11 +693,12 @@ ${cyan(
|
|
|
573
693
|
rootDir: compilerOptions.rootDir || root,
|
|
574
694
|
noEmitOnError,
|
|
575
695
|
outDir: ".",
|
|
576
|
-
declarationDir:
|
|
696
|
+
declarationDir: void 0,
|
|
577
697
|
noUnusedParameters: false,
|
|
578
698
|
declaration: true,
|
|
579
699
|
noEmit: false,
|
|
580
|
-
emitDeclarationOnly: true
|
|
700
|
+
emitDeclarationOnly: true,
|
|
701
|
+
composite: false
|
|
581
702
|
}),
|
|
582
703
|
tsConfigFilePath: tsConfigPath,
|
|
583
704
|
skipAddingFilesFromTsConfig: true,
|
|
@@ -620,7 +741,19 @@ ${cyan(
|
|
|
620
741
|
return null;
|
|
621
742
|
}
|
|
622
743
|
if (vueRE.test(id)) {
|
|
623
|
-
const { content, ext } = compileVueCode(code);
|
|
744
|
+
const { error, content, ext } = compileVueCode(code);
|
|
745
|
+
if (!transformError && error) {
|
|
746
|
+
logger.error(
|
|
747
|
+
red(
|
|
748
|
+
`
|
|
749
|
+
${cyan(
|
|
750
|
+
"[vite:dts]"
|
|
751
|
+
)} A error occurred when transform code, maybe there are some inertnal bugs.
|
|
752
|
+
`
|
|
753
|
+
)
|
|
754
|
+
);
|
|
755
|
+
transformError = true;
|
|
756
|
+
}
|
|
624
757
|
if (content) {
|
|
625
758
|
if (ext === "js" || ext === "jsx")
|
|
626
759
|
hasJsVue = true;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vite-plugin-dts",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0-beta.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "qmhc",
|
|
@@ -53,6 +53,7 @@
|
|
|
53
53
|
"typescript"
|
|
54
54
|
],
|
|
55
55
|
"dependencies": {
|
|
56
|
+
"@babel/parser": "^7.20.15",
|
|
56
57
|
"@microsoft/api-extractor": "^7.33.5",
|
|
57
58
|
"@rollup/pluginutils": "^5.0.2",
|
|
58
59
|
"@rushstack/node-core-library": "^3.53.2",
|
|
@@ -60,9 +61,11 @@
|
|
|
60
61
|
"fast-glob": "^3.2.12",
|
|
61
62
|
"fs-extra": "^10.1.0",
|
|
62
63
|
"kolorist": "^1.6.0",
|
|
64
|
+
"magic-string": "^0.29.0",
|
|
63
65
|
"ts-morph": "17.0.1"
|
|
64
66
|
},
|
|
65
67
|
"devDependencies": {
|
|
68
|
+
"@babel/types": "^7.20.7",
|
|
66
69
|
"@commitlint/cli": "^17.1.2",
|
|
67
70
|
"@commitlint/config-conventional": "^17.1.0",
|
|
68
71
|
"@types/debug": "^4.1.7",
|