vite-plugin-dts 2.0.0-beta.0 → 2.0.0-beta.2

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 CHANGED
@@ -112,6 +112,7 @@ This is a exist issue when TypeScript inferring types from packages which under
112
112
 
113
113
  ```ts
114
114
  import type { ts, Diagnostic } from 'ts-morph'
115
+ import type { LogLevel } from 'vite'
115
116
 
116
117
  interface TransformWriteFile {
117
118
  filePath?: string
@@ -122,7 +123,7 @@ export interface PluginOptions {
122
123
  /**
123
124
  * Depends on the root directory
124
125
  *
125
- * Defaults base on your vite config root options
126
+ * By Default it base on 'root' option of your vite config
126
127
  */
127
128
  root?: string
128
129
 
@@ -131,16 +132,16 @@ export interface PluginOptions {
131
132
  *
132
133
  * Can be specified a array to output to multiple directories
133
134
  *
134
- * Defaults base on your vite config output options
135
+ * By Default it base on 'build.outDir' option of your vite config
135
136
  */
136
137
  outputDir?: string | string[]
137
138
 
138
139
  /**
139
140
  * Manually set the root path of the entry files
140
141
  *
141
- * The output path of each file will be caculated base on it
142
+ * The output path of each file will be calculated base on it
142
143
  *
143
- * Defaults is the smallest public path for all files
144
+ * By Default it is the smallest public path for all files
144
145
  */
145
146
  entryRoot?: string
146
147
 
@@ -154,7 +155,7 @@ export interface PluginOptions {
154
155
  /**
155
156
  * Project init tsconfig.json file path by ts-morph
156
157
  *
157
- * Plugin also resolve incldue and exclude files from tsconfig.json
158
+ * Plugin also resolve include and exclude files from tsconfig.json
158
159
  *
159
160
  * @default 'tsconfig.json'
160
161
  */
@@ -190,14 +191,14 @@ export interface PluginOptions {
190
191
  /**
191
192
  * Manual set include glob
192
193
  *
193
- * Defaults base on your tsconfig.json include option
194
+ * By Default it base on 'include' option of the tsconfig.json
194
195
  */
195
196
  include?: string | string[]
196
197
 
197
198
  /**
198
199
  * Manual set exclude glob
199
200
  *
200
- * Defaults base on your tsconfig.json exclude option, be 'node_modules/**' when empty
201
+ * By Default it base on 'exclude' option of the tsconfig.json, be 'node_module/**' when empty
201
202
  */
202
203
  exclude?: string | string[]
203
204
 
@@ -253,16 +254,6 @@ export interface PluginOptions {
253
254
  */
254
255
  skipDiagnostics?: boolean
255
256
 
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
257
  /**
267
258
  * Customize typescript lib folder path
268
259
  *
@@ -272,6 +263,13 @@ export interface PluginOptions {
272
263
  */
273
264
  libFolderPath?: string
274
265
 
266
+ /**
267
+ * Specify the log level of plugin
268
+ *
269
+ * By Default it base on 'logLevel' option of your vite config
270
+ */
271
+ logLevel?: LogLevel
272
+
275
273
  /**
276
274
  * After emit diagnostic hook
277
275
  *
package/README.zh-CN.md CHANGED
@@ -111,6 +111,7 @@ const props = defineProps<{
111
111
 
112
112
  ```ts
113
113
  import type { ts, Diagnostic } from 'ts-morph'
114
+ import type { LogLevel } from 'vite'
114
115
 
115
116
  interface TransformWriteFile {
116
117
  filePath?: string
@@ -121,7 +122,7 @@ export interface PluginOptions {
121
122
  /**
122
123
  * 执行的根目录
123
124
  *
124
- * 默认基于 vite 配置的 root 选项
125
+ * 默认基于 vite 配置的 'root' 选项
125
126
  */
126
127
  root?: string
127
128
 
@@ -130,7 +131,7 @@ export interface PluginOptions {
130
131
  *
131
132
  * 可以指定一个数组来输出到多个目录中
132
133
  *
133
- * 默认基于 vite 配置的输出目录
134
+ * 默认基于 vite 配置的 'build.outDir' 选项
134
135
  */
135
136
  outputDir?: string | string[]
136
137
 
@@ -189,14 +190,14 @@ export interface PluginOptions {
189
190
  /**
190
191
  * 手动设置包含路径的 glob
191
192
  *
192
- * 默认基于 tsconfig.json 的 include 选项
193
+ * 默认基于 tsconfig.json 的 'include' 选项
193
194
  */
194
195
  include?: string | string[]
195
196
 
196
197
  /**
197
198
  * 手动设置排除路径的 glob
198
199
  *
199
- * 默认基于 tsconfig.json 的 exclude 选线,未设置时为 'node_module/**'
200
+ * 默认基于 tsconfig.json 的 'exclude' 选线,未设置时为 'node_module/**'
200
201
  */
201
202
  exclude?: string | string[]
202
203
 
@@ -252,16 +253,6 @@ export interface PluginOptions {
252
253
  */
253
254
  skipDiagnostics?: boolean
254
255
 
255
- /**
256
- * 是否打印类型诊断信息
257
- *
258
- * 当跳过类型诊断时该属性将不会生效
259
- *
260
- * @deprecated
261
- * @default false
262
- */
263
- logDiagnostics?: boolean
264
-
265
256
  /**
266
257
  * 定制 typescript 的 lib 文件夹路径
267
258
  *
@@ -271,6 +262,13 @@ export interface PluginOptions {
271
262
  */
272
263
  libFolderPath?: string
273
264
 
265
+ /**
266
+ * 指定插件的输出等级
267
+ *
268
+ * 默认基于 vite 配置的 'logLevel' 选项
269
+ */
270
+ logLevel?: LogLevel
271
+
274
272
  /**
275
273
  * 获取诊断信息后的钩子
276
274
  *
package/dist/index.cjs CHANGED
@@ -360,59 +360,90 @@ function preprocessVueCode(code, setupScript) {
360
360
  }
361
361
  }
362
362
  }
363
+ const declRecord = /* @__PURE__ */ new Map();
364
+ let defaultExport;
365
+ let options;
363
366
  for (const node of scriptAst) {
367
+ if (node.type === "VariableDeclaration") {
368
+ for (const decl of node.declarations) {
369
+ if (decl.id.type === "Identifier" && decl.init) {
370
+ let properties;
371
+ if (decl.init.type === "ObjectExpression") {
372
+ properties = decl.init.properties;
373
+ } else if (decl.init.type === "CallExpression" && decl.init.arguments[0].type === "ObjectExpression") {
374
+ properties = decl.init.arguments[0].properties;
375
+ }
376
+ if (!properties)
377
+ continue;
378
+ if (defaultExport && decl.id.name === defaultExport) {
379
+ options = properties;
380
+ break;
381
+ } else {
382
+ declRecord.set(decl.id.name, properties);
383
+ }
384
+ }
385
+ }
386
+ }
364
387
  if (node.type === "ExportDefaultDeclaration") {
365
- let options;
366
388
  if (node.declaration.type === "ObjectExpression") {
367
389
  options = node.declaration.properties;
368
390
  } else if (node.declaration.type === "CallExpression" && node.declaration.arguments[0].type === "ObjectExpression") {
369
391
  options = node.declaration.arguments[0].properties;
392
+ } else if (node.declaration.type === "Identifier") {
393
+ if (declRecord.has(node.declaration.name)) {
394
+ options = declRecord.get(node.declaration.name);
395
+ } else {
396
+ defaultExport = node.declaration.name;
397
+ }
370
398
  }
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 __PropType<${propsTypeName}['${prop.key.name}']>`
382
- );
383
- }
399
+ }
400
+ if (options) {
401
+ for (const option of options) {
402
+ if (propsTypeName && option.type === "ObjectProperty" && option.key.type === "Identifier" && option.key.name === "props" && option.value.type === "ObjectExpression") {
403
+ for (const prop of option.value.properties) {
404
+ if (prop.type === "ObjectProperty" && prop.key.type === "Identifier") {
405
+ if (prop.value.type === "ObjectExpression") {
406
+ for (const propDef of prop.value.properties) {
407
+ if (propDef.type === "ObjectProperty" && propDef.key.type === "Identifier" && propDef.key.name === "type") {
408
+ source.prependLeft(
409
+ propDef.end,
410
+ ` as unknown as __PropType<${propsTypeName}['${prop.key.name}']>`
411
+ );
384
412
  }
385
- } else {
386
- source.prependLeft(
387
- prop.end,
388
- ` as __PropType<${propsTypeName}['${prop.key.name}']>`
389
- );
390
413
  }
414
+ } else {
415
+ source.prependLeft(
416
+ prop.end,
417
+ ` as unknown as __PropType<${propsTypeName}['${prop.key.name}']>`
418
+ );
391
419
  }
392
420
  }
393
421
  }
394
- if (option.type === "ObjectMethod" && option.key.type === "Identifier" && option.key.name === "setup") {
395
- let exposed;
396
- let returned;
397
- for (const node2 of option.body.body) {
398
- if (!exposed && node2.type === "ExpressionStatement" && node2.expression.type === "CallExpression" && node2.expression.callee.type === "Identifier" && node2.expression.callee.name === "expose") {
399
- exposed = node2.expression.arguments[0];
400
- continue;
401
- }
402
- if (node2.type === "ReturnStatement") {
403
- returned = node2;
404
- break;
405
- }
422
+ }
423
+ if (option.type === "ObjectProperty" && option.key.type === "Identifier" && option.key.name === "components") {
424
+ source.remove(option.start, option.end);
425
+ }
426
+ if (option.type === "ObjectMethod" && option.key.type === "Identifier" && option.key.name === "setup") {
427
+ let exposed;
428
+ let returned;
429
+ for (const node2 of option.body.body) {
430
+ if (!exposed && node2.type === "ExpressionStatement" && node2.expression.type === "CallExpression" && node2.expression.callee.type === "Identifier" && node2.expression.callee.name === "expose") {
431
+ exposed = node2.expression.arguments[0];
432
+ continue;
406
433
  }
407
- const newReturned = exposed && exposed.type === "ObjectExpression" ? `return ${code.substring(exposed.start, exposed.end)}` : setupScript ? "return {}" : "";
408
- if (newReturned) {
409
- if (returned) {
410
- source.overwrite(returned.start, returned.end, newReturned);
411
- } else if (option.body.body.length) {
412
- source.appendRight(option.body.body.at(-1).end, `
434
+ if (node2.type === "ReturnStatement") {
435
+ returned = node2;
436
+ break;
437
+ }
438
+ }
439
+ const newReturned = exposed && exposed.type === "ObjectExpression" ? `return ${code.substring(exposed.start, exposed.end)}` : setupScript ? "return {}" : "";
440
+ if (newReturned) {
441
+ if (returned) {
442
+ source.overwrite(returned.start, returned.end, newReturned);
443
+ } else if (option.body.body.length) {
444
+ source.appendRight(option.body.body.at(-1).end, `
413
445
  ${newReturned}
414
446
  `);
415
- }
416
447
  }
417
448
  }
418
449
  }
@@ -472,10 +503,11 @@ function compileVueCode(code) {
472
503
  const dtsRE$1 = /\.d\.tsx?$/;
473
504
  function rollupDeclarationFiles({
474
505
  root,
506
+ compilerOptions,
475
507
  outputDir,
476
508
  entryPath,
477
509
  fileName,
478
- compilerOptions
510
+ libFolder
479
511
  }) {
480
512
  const configObjectFullPath = node_path.resolve(root, "api-extractor.json");
481
513
  const packageJsonLookup = new nodeCoreLibrary.PackageJsonLookup();
@@ -524,8 +556,9 @@ function rollupDeclarationFiles({
524
556
  packageJsonFullPath
525
557
  });
526
558
  const compilerState = apiExtractor.CompilerState.create(extractorConfig, {
527
- localBuild: true,
528
- showVerboseMessages: false
559
+ localBuild: false,
560
+ showVerboseMessages: false,
561
+ typescriptCompilerFolder: libFolder ? node_path.resolve(libFolder, "..") : void 0
529
562
  });
530
563
  const sourceMapper = new SourceMapper_js.SourceMapper();
531
564
  const messageRouter = new MessageRouter_js.MessageRouter({
@@ -579,9 +612,8 @@ function dtsPlugin(options = {}) {
579
612
  rollupTypes = false,
580
613
  noEmitOnError = false,
581
614
  skipDiagnostics = false,
582
- logDiagnostics = void 0,
583
615
  copyDtsFiles = true,
584
- libFolderPath = void 0,
616
+ logLevel = void 0,
585
617
  afterDiagnostic = noop,
586
618
  beforeWriteFile = noop,
587
619
  afterBuild = noop
@@ -601,10 +633,39 @@ function dtsPlugin(options = {}) {
601
633
  let include;
602
634
  let exclude;
603
635
  let filter;
636
+ let libFolderPath = options.libFolderPath;
604
637
  const sourceDtsFiles = /* @__PURE__ */ new Set();
638
+ const emittedFiles = /* @__PURE__ */ new Map();
605
639
  let hasJsVue = false;
606
640
  let allowJs = false;
607
641
  let transformError = false;
642
+ function internalTransform(code, id) {
643
+ if (!filter(id)) {
644
+ return;
645
+ }
646
+ if (vueRE.test(id)) {
647
+ const { error, content, ext } = compileVueCode(code);
648
+ if (!transformError && error) {
649
+ logger.error(
650
+ kolorist.red(
651
+ `
652
+ ${kolorist.cyan(
653
+ "[vite:dts]"
654
+ )} A error occurred when transform code, maybe there are some inertnal bugs.
655
+ `
656
+ )
657
+ );
658
+ transformError = true;
659
+ }
660
+ if (content) {
661
+ if (ext === "js" || ext === "jsx")
662
+ hasJsVue = true;
663
+ project.createSourceFile(`${id}.${ext || "js"}`, content, { overwrite: true });
664
+ }
665
+ } else if (!id.includes(".vue?vue") && (tsRE.test(id) || allowJs && jsRE.test(id))) {
666
+ project.createSourceFile(id, code, { overwrite: true });
667
+ }
668
+ }
608
669
  return {
609
670
  name: "vite:dts",
610
671
  apply: "build",
@@ -631,18 +692,7 @@ function dtsPlugin(options = {}) {
631
692
  configResolved(config) {
632
693
  if (isBundle)
633
694
  return;
634
- logger = config.logger;
635
- if (logDiagnostics != null) {
636
- logger.warn(
637
- kolorist.yellow(
638
- `
639
- ${kolorist.cyan(
640
- "[vite:dts]"
641
- )} 'logDiagnostics' has been deprecated, the original feature now following 'skipDiagnostics'.
642
- `
643
- )
644
- );
645
- }
695
+ logger = logLevel ? vite.createLogger(logLevel, { allowClearScreen: config.clearScreen }) : config.logger;
646
696
  if (!config.build.lib) {
647
697
  logger.warn(
648
698
  kolorist.yellow(
@@ -666,6 +716,7 @@ ${kolorist.cyan(
666
716
  }
667
717
  root = ensureAbsolute(options.root ?? "", config.root);
668
718
  tsConfigPath = ensureAbsolute(tsConfigFilePath, root);
719
+ libFolderPath = libFolderPath && ensureAbsolute(libFolderPath, root);
669
720
  outputDirs = options.outputDir ? ensureArray(options.outputDir).map((d) => ensureAbsolute(d, root)) : [ensureAbsolute(config.build.outDir, root)];
670
721
  if (!outputDirs[0]) {
671
722
  logger.error(
@@ -694,7 +745,7 @@ ${kolorist.cyan(
694
745
  }),
695
746
  tsConfigFilePath: tsConfigPath,
696
747
  skipAddingFilesFromTsConfig: true,
697
- libFolderPath: libFolderPath ? ensureAbsolute(libFolderPath, root) : void 0
748
+ libFolderPath
698
749
  });
699
750
  allowJs = project.getCompilerOptions().allowJs ?? false;
700
751
  const tsConfig = { compilerOptions: {} };
@@ -729,39 +780,16 @@ ${kolorist.cyan(
729
780
  }
730
781
  },
731
782
  transform(code, id) {
732
- if (!filter(id)) {
733
- return null;
734
- }
735
- if (vueRE.test(id)) {
736
- const { error, content, ext } = compileVueCode(code);
737
- if (!transformError && error) {
738
- logger.error(
739
- kolorist.red(
740
- `
741
- ${kolorist.cyan(
742
- "[vite:dts]"
743
- )} A error occurred when transform code, maybe there are some inertnal bugs.
744
- `
745
- )
746
- );
747
- transformError = true;
748
- }
749
- if (content) {
750
- if (ext === "js" || ext === "jsx")
751
- hasJsVue = true;
752
- project.createSourceFile(`${id}.${ext || "js"}`, content, { overwrite: true });
753
- }
754
- } else if (!id.includes(".vue?vue") && (tsRE.test(id) || allowJs && jsRE.test(id))) {
755
- project.createSourceFile(id, code, { overwrite: true });
756
- }
783
+ internalTransform(code, id);
757
784
  return null;
758
785
  },
759
- watchChange(id) {
786
+ async watchChange(id) {
760
787
  if (watchExtensionRE.test(id)) {
761
788
  isBundle = false;
762
789
  if (project) {
763
790
  const sourceFile = project.getSourceFile(vite.normalizePath(id));
764
791
  sourceFile && project.removeSourceFile(sourceFile);
792
+ internalTransform(await fs.readFile(id, "utf-8"), id);
765
793
  }
766
794
  }
767
795
  },
@@ -773,6 +801,7 @@ ${logPrefix} Start generate declaration files...`));
773
801
  bundleDebug("start");
774
802
  isBundle = true;
775
803
  sourceDtsFiles.clear();
804
+ emittedFiles.clear();
776
805
  const startTime = Date.now();
777
806
  const includedFileSet = /* @__PURE__ */ new Set();
778
807
  if (include && include.length) {
@@ -835,7 +864,6 @@ ${logPrefix} Start generate declaration files...`));
835
864
  entryRoot = queryPublicPath(outputFiles.map((file) => file.path));
836
865
  }
837
866
  entryRoot = ensureAbsolute(entryRoot, root);
838
- const wroteFiles = /* @__PURE__ */ new Set();
839
867
  const outputDir = outputDirs[0];
840
868
  await runParallel(os.cpus().length, outputFiles, async (outputFile) => {
841
869
  let filePath = outputFile.path;
@@ -868,7 +896,10 @@ ${logPrefix} Start generate declaration files...`));
868
896
  cleanVueFileName ? content.replace(/['"](.+)\.vue['"]/g, '"$1"') : content,
869
897
  "utf-8"
870
898
  );
871
- wroteFiles.add(vite.normalizePath(filePath));
899
+ emittedFiles.set(
900
+ vite.normalizePath(filePath),
901
+ cleanVueFileName ? content.replace(/['"](.+)\.vue['"]/g, '"$1"') : content
902
+ );
872
903
  });
873
904
  bundleDebug("output");
874
905
  if (insertTypesEntry || rollupTypes) {
@@ -909,13 +940,16 @@ export default ${libName}
909
940
  }
910
941
  if (result !== false) {
911
942
  await fs.writeFile(filePath, content, "utf-8");
912
- wroteFiles.add(vite.normalizePath(filePath));
943
+ emittedFiles.set(vite.normalizePath(filePath), content);
913
944
  }
914
945
  }
915
946
  bundleDebug("insert index");
916
947
  if (rollupTypes) {
917
948
  logger.info(kolorist.green(`${logPrefix} Start rollup declaration files...`));
918
949
  const rollupFiles = /* @__PURE__ */ new Set();
950
+ for (const [filePath, content] of emittedFiles) {
951
+ project.createSourceFile(filePath, content, { overwrite: true });
952
+ }
919
953
  if (multiple) {
920
954
  for (const name of entryNames) {
921
955
  const path = node_path.resolve(outputDir, `${name.replace(tsRE, "")}.d.ts`);
@@ -924,10 +958,11 @@ export default ${libName}
924
958
  compilerOptions,
925
959
  outputDir,
926
960
  entryPath: path,
927
- fileName: node_path.basename(path)
961
+ fileName: node_path.basename(path),
962
+ libFolder: libFolderPath
928
963
  });
929
964
  const wroteFile = vite.normalizePath(path);
930
- wroteFiles.delete(wroteFile);
965
+ emittedFiles.delete(wroteFile);
931
966
  rollupFiles.add(wroteFile);
932
967
  }
933
968
  } else {
@@ -936,23 +971,24 @@ export default ${libName}
936
971
  compilerOptions,
937
972
  outputDir,
938
973
  entryPath: typesPath,
939
- fileName: node_path.basename(typesPath)
974
+ fileName: node_path.basename(typesPath),
975
+ libFolder: libFolderPath
940
976
  });
941
977
  const wroteFile = vite.normalizePath(typesPath);
942
- wroteFiles.delete(wroteFile);
978
+ emittedFiles.delete(wroteFile);
943
979
  rollupFiles.add(wroteFile);
944
980
  }
945
- await runParallel(os.cpus().length, Array.from(wroteFiles), (f) => fs.unlink(f));
981
+ await runParallel(os.cpus().length, Array.from(emittedFiles.keys()), (f) => fs.unlink(f));
946
982
  removeDirIfEmpty(outputDir);
947
- wroteFiles.clear();
983
+ emittedFiles.clear();
948
984
  for (const file of rollupFiles) {
949
- wroteFiles.add(file);
985
+ emittedFiles.set(file, await fs.readFile(file, "utf-8"));
950
986
  }
951
987
  if (copyDtsFiles) {
952
988
  await runParallel(os.cpus().length, dtsOutputFiles, async ({ path, content }) => {
953
989
  const filePath = node_path.resolve(outputDir, node_path.basename(path));
954
990
  await fs.writeFile(filePath, content, "utf-8");
955
- wroteFiles.add(vite.normalizePath(filePath));
991
+ emittedFiles.set(vite.normalizePath(filePath), content);
956
992
  });
957
993
  }
958
994
  bundleDebug("rollup");
@@ -960,17 +996,20 @@ export default ${libName}
960
996
  }
961
997
  if (outputDirs.length > 1) {
962
998
  const dirs = outputDirs.slice(1);
963
- await runParallel(os.cpus().length, Array.from(wroteFiles), async (wroteFile) => {
964
- const relativePath = node_path.relative(outputDir, wroteFile);
965
- const content = await fs.readFile(wroteFile, "utf-8");
966
- await Promise.all(
967
- dirs.map(async (dir) => {
968
- const filePath = node_path.resolve(dir, relativePath);
969
- await fs.mkdir(node_path.dirname(filePath), { recursive: true });
970
- await fs.writeFile(filePath, content, "utf-8");
971
- })
972
- );
973
- });
999
+ await runParallel(
1000
+ os.cpus().length,
1001
+ Array.from(emittedFiles),
1002
+ async ([wroteFile, content]) => {
1003
+ const relativePath = node_path.relative(outputDir, wroteFile);
1004
+ await Promise.all(
1005
+ dirs.map(async (dir) => {
1006
+ const filePath = node_path.resolve(dir, relativePath);
1007
+ await fs.mkdir(node_path.dirname(filePath), { recursive: true });
1008
+ await fs.writeFile(filePath, content, "utf-8");
1009
+ })
1010
+ );
1011
+ }
1012
+ );
974
1013
  }
975
1014
  if (typeof afterBuild === "function") {
976
1015
  const result = afterBuild();
package/dist/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import * as vite from 'vite';
2
+ import { LogLevel } from 'vite';
2
3
  import { ts, Diagnostic } from 'ts-morph';
3
4
 
4
5
  interface TransformWriteFile {
@@ -9,7 +10,7 @@ interface PluginOptions {
9
10
  /**
10
11
  * Depends on the root directory
11
12
  *
12
- * Defaults base on your vite config root options
13
+ * By Default it base on 'root' option of your vite config
13
14
  */
14
15
  root?: string;
15
16
  /**
@@ -17,7 +18,7 @@ interface PluginOptions {
17
18
  *
18
19
  * Can be specified a array to output to multiple directories
19
20
  *
20
- * Defaults base on your vite config output options
21
+ * By Default it base on 'build.outDir' option of your vite config
21
22
  */
22
23
  outputDir?: string | string[];
23
24
  /**
@@ -25,7 +26,7 @@ interface PluginOptions {
25
26
  *
26
27
  * The output path of each file will be calculated base on it
27
28
  *
28
- * Defaults is the smallest public path for all files
29
+ * By Default it is the smallest public path for all files
29
30
  */
30
31
  entryRoot?: string;
31
32
  /**
@@ -69,13 +70,13 @@ interface PluginOptions {
69
70
  /**
70
71
  * Manual set include glob
71
72
  *
72
- * Defaults base on your tsconfig.json include option
73
+ * By Default it base on 'include' option of the tsconfig.json
73
74
  */
74
75
  include?: string | string[];
75
76
  /**
76
77
  * Manual set exclude glob
77
78
  *
78
- * Defaults base on your tsconfig.json exclude option, be 'node_module/**' when empty
79
+ * By Default it base on 'exclude' option of the tsconfig.json, be 'node_module/**' when empty
79
80
  */
80
81
  exclude?: string | string[];
81
82
  /**
@@ -124,15 +125,6 @@ interface PluginOptions {
124
125
  * @default false
125
126
  */
126
127
  skipDiagnostics?: boolean;
127
- /**
128
- * Whether log diagnostic informations
129
- *
130
- * Not effective when `skipDiagnostics` is true
131
- *
132
- * @deprecated
133
- * @default false
134
- */
135
- logDiagnostics?: boolean;
136
128
  /**
137
129
  * Customize typescript lib folder path
138
130
  *
@@ -141,6 +133,12 @@ interface PluginOptions {
141
133
  * @default undefined
142
134
  */
143
135
  libFolderPath?: string;
136
+ /**
137
+ * Specify the log level of plugin
138
+ *
139
+ * By Default it base on 'logLevel' option of your vite config
140
+ */
141
+ logLevel?: LogLevel;
144
142
  /**
145
143
  * After emit diagnostic hook
146
144
  *
package/dist/index.mjs CHANGED
@@ -12,7 +12,7 @@ import { cyan, yellow, red, green } from 'kolorist';
12
12
  import glob from 'fast-glob';
13
13
  import debug from 'debug';
14
14
  import { Project } from 'ts-morph';
15
- import { normalizePath } from 'vite';
15
+ import { normalizePath, createLogger } from 'vite';
16
16
  import typescript from 'typescript';
17
17
  import { createFilter } from '@rollup/pluginutils';
18
18
  import { existsSync, readdirSync, lstatSync, rmdirSync } from 'node:fs';
@@ -365,59 +365,90 @@ function preprocessVueCode(code, setupScript) {
365
365
  }
366
366
  }
367
367
  }
368
+ const declRecord = /* @__PURE__ */ new Map();
369
+ let defaultExport;
370
+ let options;
368
371
  for (const node of scriptAst) {
372
+ if (node.type === "VariableDeclaration") {
373
+ for (const decl of node.declarations) {
374
+ if (decl.id.type === "Identifier" && decl.init) {
375
+ let properties;
376
+ if (decl.init.type === "ObjectExpression") {
377
+ properties = decl.init.properties;
378
+ } else if (decl.init.type === "CallExpression" && decl.init.arguments[0].type === "ObjectExpression") {
379
+ properties = decl.init.arguments[0].properties;
380
+ }
381
+ if (!properties)
382
+ continue;
383
+ if (defaultExport && decl.id.name === defaultExport) {
384
+ options = properties;
385
+ break;
386
+ } else {
387
+ declRecord.set(decl.id.name, properties);
388
+ }
389
+ }
390
+ }
391
+ }
369
392
  if (node.type === "ExportDefaultDeclaration") {
370
- let options;
371
393
  if (node.declaration.type === "ObjectExpression") {
372
394
  options = node.declaration.properties;
373
395
  } else if (node.declaration.type === "CallExpression" && node.declaration.arguments[0].type === "ObjectExpression") {
374
396
  options = node.declaration.arguments[0].properties;
397
+ } else if (node.declaration.type === "Identifier") {
398
+ if (declRecord.has(node.declaration.name)) {
399
+ options = declRecord.get(node.declaration.name);
400
+ } else {
401
+ defaultExport = node.declaration.name;
402
+ }
375
403
  }
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 __PropType<${propsTypeName}['${prop.key.name}']>`
387
- );
388
- }
404
+ }
405
+ if (options) {
406
+ for (const option of options) {
407
+ if (propsTypeName && option.type === "ObjectProperty" && option.key.type === "Identifier" && option.key.name === "props" && option.value.type === "ObjectExpression") {
408
+ for (const prop of option.value.properties) {
409
+ if (prop.type === "ObjectProperty" && prop.key.type === "Identifier") {
410
+ if (prop.value.type === "ObjectExpression") {
411
+ for (const propDef of prop.value.properties) {
412
+ if (propDef.type === "ObjectProperty" && propDef.key.type === "Identifier" && propDef.key.name === "type") {
413
+ source.prependLeft(
414
+ propDef.end,
415
+ ` as unknown as __PropType<${propsTypeName}['${prop.key.name}']>`
416
+ );
389
417
  }
390
- } else {
391
- source.prependLeft(
392
- prop.end,
393
- ` as __PropType<${propsTypeName}['${prop.key.name}']>`
394
- );
395
418
  }
419
+ } else {
420
+ source.prependLeft(
421
+ prop.end,
422
+ ` as unknown as __PropType<${propsTypeName}['${prop.key.name}']>`
423
+ );
396
424
  }
397
425
  }
398
426
  }
399
- if (option.type === "ObjectMethod" && option.key.type === "Identifier" && option.key.name === "setup") {
400
- let exposed;
401
- let returned;
402
- for (const node2 of option.body.body) {
403
- if (!exposed && node2.type === "ExpressionStatement" && node2.expression.type === "CallExpression" && node2.expression.callee.type === "Identifier" && node2.expression.callee.name === "expose") {
404
- exposed = node2.expression.arguments[0];
405
- continue;
406
- }
407
- if (node2.type === "ReturnStatement") {
408
- returned = node2;
409
- break;
410
- }
427
+ }
428
+ if (option.type === "ObjectProperty" && option.key.type === "Identifier" && option.key.name === "components") {
429
+ source.remove(option.start, option.end);
430
+ }
431
+ if (option.type === "ObjectMethod" && option.key.type === "Identifier" && option.key.name === "setup") {
432
+ let exposed;
433
+ let returned;
434
+ for (const node2 of option.body.body) {
435
+ if (!exposed && node2.type === "ExpressionStatement" && node2.expression.type === "CallExpression" && node2.expression.callee.type === "Identifier" && node2.expression.callee.name === "expose") {
436
+ exposed = node2.expression.arguments[0];
437
+ continue;
411
438
  }
412
- const newReturned = exposed && exposed.type === "ObjectExpression" ? `return ${code.substring(exposed.start, exposed.end)}` : setupScript ? "return {}" : "";
413
- if (newReturned) {
414
- if (returned) {
415
- source.overwrite(returned.start, returned.end, newReturned);
416
- } else if (option.body.body.length) {
417
- source.appendRight(option.body.body.at(-1).end, `
439
+ if (node2.type === "ReturnStatement") {
440
+ returned = node2;
441
+ break;
442
+ }
443
+ }
444
+ const newReturned = exposed && exposed.type === "ObjectExpression" ? `return ${code.substring(exposed.start, exposed.end)}` : setupScript ? "return {}" : "";
445
+ if (newReturned) {
446
+ if (returned) {
447
+ source.overwrite(returned.start, returned.end, newReturned);
448
+ } else if (option.body.body.length) {
449
+ source.appendRight(option.body.body.at(-1).end, `
418
450
  ${newReturned}
419
451
  `);
420
- }
421
452
  }
422
453
  }
423
454
  }
@@ -477,10 +508,11 @@ function compileVueCode(code) {
477
508
  const dtsRE$1 = /\.d\.tsx?$/;
478
509
  function rollupDeclarationFiles({
479
510
  root,
511
+ compilerOptions,
480
512
  outputDir,
481
513
  entryPath,
482
514
  fileName,
483
- compilerOptions
515
+ libFolder
484
516
  }) {
485
517
  const configObjectFullPath = resolve(root, "api-extractor.json");
486
518
  const packageJsonLookup = new PackageJsonLookup();
@@ -529,8 +561,9 @@ function rollupDeclarationFiles({
529
561
  packageJsonFullPath
530
562
  });
531
563
  const compilerState = CompilerState.create(extractorConfig, {
532
- localBuild: true,
533
- showVerboseMessages: false
564
+ localBuild: false,
565
+ showVerboseMessages: false,
566
+ typescriptCompilerFolder: libFolder ? resolve(libFolder, "..") : void 0
534
567
  });
535
568
  const sourceMapper = new SourceMapper();
536
569
  const messageRouter = new MessageRouter({
@@ -584,9 +617,8 @@ function dtsPlugin(options = {}) {
584
617
  rollupTypes = false,
585
618
  noEmitOnError = false,
586
619
  skipDiagnostics = false,
587
- logDiagnostics = void 0,
588
620
  copyDtsFiles = true,
589
- libFolderPath = void 0,
621
+ logLevel = void 0,
590
622
  afterDiagnostic = noop,
591
623
  beforeWriteFile = noop,
592
624
  afterBuild = noop
@@ -606,10 +638,39 @@ function dtsPlugin(options = {}) {
606
638
  let include;
607
639
  let exclude;
608
640
  let filter;
641
+ let libFolderPath = options.libFolderPath;
609
642
  const sourceDtsFiles = /* @__PURE__ */ new Set();
643
+ const emittedFiles = /* @__PURE__ */ new Map();
610
644
  let hasJsVue = false;
611
645
  let allowJs = false;
612
646
  let transformError = false;
647
+ function internalTransform(code, id) {
648
+ if (!filter(id)) {
649
+ return;
650
+ }
651
+ if (vueRE.test(id)) {
652
+ const { error, content, ext } = compileVueCode(code);
653
+ if (!transformError && error) {
654
+ logger.error(
655
+ red(
656
+ `
657
+ ${cyan(
658
+ "[vite:dts]"
659
+ )} A error occurred when transform code, maybe there are some inertnal bugs.
660
+ `
661
+ )
662
+ );
663
+ transformError = true;
664
+ }
665
+ if (content) {
666
+ if (ext === "js" || ext === "jsx")
667
+ hasJsVue = true;
668
+ project.createSourceFile(`${id}.${ext || "js"}`, content, { overwrite: true });
669
+ }
670
+ } else if (!id.includes(".vue?vue") && (tsRE.test(id) || allowJs && jsRE.test(id))) {
671
+ project.createSourceFile(id, code, { overwrite: true });
672
+ }
673
+ }
613
674
  return {
614
675
  name: "vite:dts",
615
676
  apply: "build",
@@ -636,18 +697,7 @@ function dtsPlugin(options = {}) {
636
697
  configResolved(config) {
637
698
  if (isBundle)
638
699
  return;
639
- logger = config.logger;
640
- if (logDiagnostics != null) {
641
- logger.warn(
642
- yellow(
643
- `
644
- ${cyan(
645
- "[vite:dts]"
646
- )} 'logDiagnostics' has been deprecated, the original feature now following 'skipDiagnostics'.
647
- `
648
- )
649
- );
650
- }
700
+ logger = logLevel ? createLogger(logLevel, { allowClearScreen: config.clearScreen }) : config.logger;
651
701
  if (!config.build.lib) {
652
702
  logger.warn(
653
703
  yellow(
@@ -671,6 +721,7 @@ ${cyan(
671
721
  }
672
722
  root = ensureAbsolute(options.root ?? "", config.root);
673
723
  tsConfigPath = ensureAbsolute(tsConfigFilePath, root);
724
+ libFolderPath = libFolderPath && ensureAbsolute(libFolderPath, root);
674
725
  outputDirs = options.outputDir ? ensureArray(options.outputDir).map((d) => ensureAbsolute(d, root)) : [ensureAbsolute(config.build.outDir, root)];
675
726
  if (!outputDirs[0]) {
676
727
  logger.error(
@@ -699,7 +750,7 @@ ${cyan(
699
750
  }),
700
751
  tsConfigFilePath: tsConfigPath,
701
752
  skipAddingFilesFromTsConfig: true,
702
- libFolderPath: libFolderPath ? ensureAbsolute(libFolderPath, root) : void 0
753
+ libFolderPath
703
754
  });
704
755
  allowJs = project.getCompilerOptions().allowJs ?? false;
705
756
  const tsConfig = { compilerOptions: {} };
@@ -734,39 +785,16 @@ ${cyan(
734
785
  }
735
786
  },
736
787
  transform(code, id) {
737
- if (!filter(id)) {
738
- return null;
739
- }
740
- if (vueRE.test(id)) {
741
- const { error, content, ext } = compileVueCode(code);
742
- if (!transformError && error) {
743
- logger.error(
744
- red(
745
- `
746
- ${cyan(
747
- "[vite:dts]"
748
- )} A error occurred when transform code, maybe there are some inertnal bugs.
749
- `
750
- )
751
- );
752
- transformError = true;
753
- }
754
- if (content) {
755
- if (ext === "js" || ext === "jsx")
756
- hasJsVue = true;
757
- project.createSourceFile(`${id}.${ext || "js"}`, content, { overwrite: true });
758
- }
759
- } else if (!id.includes(".vue?vue") && (tsRE.test(id) || allowJs && jsRE.test(id))) {
760
- project.createSourceFile(id, code, { overwrite: true });
761
- }
788
+ internalTransform(code, id);
762
789
  return null;
763
790
  },
764
- watchChange(id) {
791
+ async watchChange(id) {
765
792
  if (watchExtensionRE.test(id)) {
766
793
  isBundle = false;
767
794
  if (project) {
768
795
  const sourceFile = project.getSourceFile(normalizePath(id));
769
796
  sourceFile && project.removeSourceFile(sourceFile);
797
+ internalTransform(await fs.readFile(id, "utf-8"), id);
770
798
  }
771
799
  }
772
800
  },
@@ -778,6 +806,7 @@ ${logPrefix} Start generate declaration files...`));
778
806
  bundleDebug("start");
779
807
  isBundle = true;
780
808
  sourceDtsFiles.clear();
809
+ emittedFiles.clear();
781
810
  const startTime = Date.now();
782
811
  const includedFileSet = /* @__PURE__ */ new Set();
783
812
  if (include && include.length) {
@@ -840,7 +869,6 @@ ${logPrefix} Start generate declaration files...`));
840
869
  entryRoot = queryPublicPath(outputFiles.map((file) => file.path));
841
870
  }
842
871
  entryRoot = ensureAbsolute(entryRoot, root);
843
- const wroteFiles = /* @__PURE__ */ new Set();
844
872
  const outputDir = outputDirs[0];
845
873
  await runParallel(os.cpus().length, outputFiles, async (outputFile) => {
846
874
  let filePath = outputFile.path;
@@ -873,7 +901,10 @@ ${logPrefix} Start generate declaration files...`));
873
901
  cleanVueFileName ? content.replace(/['"](.+)\.vue['"]/g, '"$1"') : content,
874
902
  "utf-8"
875
903
  );
876
- wroteFiles.add(normalizePath(filePath));
904
+ emittedFiles.set(
905
+ normalizePath(filePath),
906
+ cleanVueFileName ? content.replace(/['"](.+)\.vue['"]/g, '"$1"') : content
907
+ );
877
908
  });
878
909
  bundleDebug("output");
879
910
  if (insertTypesEntry || rollupTypes) {
@@ -914,13 +945,16 @@ export default ${libName}
914
945
  }
915
946
  if (result !== false) {
916
947
  await fs.writeFile(filePath, content, "utf-8");
917
- wroteFiles.add(normalizePath(filePath));
948
+ emittedFiles.set(normalizePath(filePath), content);
918
949
  }
919
950
  }
920
951
  bundleDebug("insert index");
921
952
  if (rollupTypes) {
922
953
  logger.info(green(`${logPrefix} Start rollup declaration files...`));
923
954
  const rollupFiles = /* @__PURE__ */ new Set();
955
+ for (const [filePath, content] of emittedFiles) {
956
+ project.createSourceFile(filePath, content, { overwrite: true });
957
+ }
924
958
  if (multiple) {
925
959
  for (const name of entryNames) {
926
960
  const path = resolve(outputDir, `${name.replace(tsRE, "")}.d.ts`);
@@ -929,10 +963,11 @@ export default ${libName}
929
963
  compilerOptions,
930
964
  outputDir,
931
965
  entryPath: path,
932
- fileName: basename(path)
966
+ fileName: basename(path),
967
+ libFolder: libFolderPath
933
968
  });
934
969
  const wroteFile = normalizePath(path);
935
- wroteFiles.delete(wroteFile);
970
+ emittedFiles.delete(wroteFile);
936
971
  rollupFiles.add(wroteFile);
937
972
  }
938
973
  } else {
@@ -941,23 +976,24 @@ export default ${libName}
941
976
  compilerOptions,
942
977
  outputDir,
943
978
  entryPath: typesPath,
944
- fileName: basename(typesPath)
979
+ fileName: basename(typesPath),
980
+ libFolder: libFolderPath
945
981
  });
946
982
  const wroteFile = normalizePath(typesPath);
947
- wroteFiles.delete(wroteFile);
983
+ emittedFiles.delete(wroteFile);
948
984
  rollupFiles.add(wroteFile);
949
985
  }
950
- await runParallel(os.cpus().length, Array.from(wroteFiles), (f) => fs.unlink(f));
986
+ await runParallel(os.cpus().length, Array.from(emittedFiles.keys()), (f) => fs.unlink(f));
951
987
  removeDirIfEmpty(outputDir);
952
- wroteFiles.clear();
988
+ emittedFiles.clear();
953
989
  for (const file of rollupFiles) {
954
- wroteFiles.add(file);
990
+ emittedFiles.set(file, await fs.readFile(file, "utf-8"));
955
991
  }
956
992
  if (copyDtsFiles) {
957
993
  await runParallel(os.cpus().length, dtsOutputFiles, async ({ path, content }) => {
958
994
  const filePath = resolve(outputDir, basename(path));
959
995
  await fs.writeFile(filePath, content, "utf-8");
960
- wroteFiles.add(normalizePath(filePath));
996
+ emittedFiles.set(normalizePath(filePath), content);
961
997
  });
962
998
  }
963
999
  bundleDebug("rollup");
@@ -965,17 +1001,20 @@ export default ${libName}
965
1001
  }
966
1002
  if (outputDirs.length > 1) {
967
1003
  const dirs = outputDirs.slice(1);
968
- await runParallel(os.cpus().length, Array.from(wroteFiles), async (wroteFile) => {
969
- const relativePath = relative(outputDir, wroteFile);
970
- const content = await fs.readFile(wroteFile, "utf-8");
971
- await Promise.all(
972
- dirs.map(async (dir) => {
973
- const filePath = resolve(dir, relativePath);
974
- await fs.mkdir(dirname(filePath), { recursive: true });
975
- await fs.writeFile(filePath, content, "utf-8");
976
- })
977
- );
978
- });
1004
+ await runParallel(
1005
+ os.cpus().length,
1006
+ Array.from(emittedFiles),
1007
+ async ([wroteFile, content]) => {
1008
+ const relativePath = relative(outputDir, wroteFile);
1009
+ await Promise.all(
1010
+ dirs.map(async (dir) => {
1011
+ const filePath = resolve(dir, relativePath);
1012
+ await fs.mkdir(dirname(filePath), { recursive: true });
1013
+ await fs.writeFile(filePath, content, "utf-8");
1014
+ })
1015
+ );
1016
+ }
1017
+ );
979
1018
  }
980
1019
  if (typeof afterBuild === "function") {
981
1020
  const result = afterBuild();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vite-plugin-dts",
3
- "version": "2.0.0-beta.0",
3
+ "version": "2.0.0-beta.2",
4
4
  "type": "module",
5
5
  "license": "MIT",
6
6
  "author": "qmhc",
@@ -29,6 +29,7 @@
29
29
  "prettier": "pretty-quick --staged",
30
30
  "release": "tsx scripts/release.ts",
31
31
  "test": "vitest run",
32
+ "test:react": "pnpm -C examples/react build",
32
33
  "test:ts": "pnpm -C examples/ts build",
33
34
  "test:vue": "pnpm -C examples/vue build"
34
35
  },