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

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/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,64 +299,179 @@ 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 = parse(code).descriptor;
305
+ descriptor = parseVueCode(code).descriptor;
306
306
  } else {
307
- descriptor = parse({ source: code });
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 __PropType<${propsTypeName}['${prop.key.name}']>`
382
+ );
383
+ }
384
+ }
385
+ } else {
386
+ source.prependLeft(
387
+ prop.end,
388
+ ` as __PropType<${propsTypeName}['${prop.key.name}']>`
389
+ );
390
+ }
391
+ }
392
+ }
393
+ }
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
+ }
406
+ }
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, `
413
+ ${newReturned}
414
+ `);
415
+ }
416
+ }
417
+ }
418
+ }
419
+ }
420
+ break;
421
+ }
422
+ }
423
+ if (propsTypeName) {
424
+ if (propsTypeLiteral) {
425
+ source.prepend(`
426
+ type ${propsTypeName} = ${propsTypeLiteral}
427
+
428
+ `);
429
+ }
430
+ source.prepend("import type { PropType as __PropType } from 'vue'\n");
431
+ }
432
+ return source.toString();
433
+ }
311
434
  function compileVueCode(code) {
312
435
  const { compileScript, rewriteDefault } = requireCompiler();
313
436
  const descriptor = parseCode(code);
314
437
  const { script, scriptSetup } = descriptor;
315
- let content = null;
316
- let ext = null;
438
+ let error;
439
+ let content;
440
+ let ext = "js";
317
441
  if (script || scriptSetup) {
442
+ const compiled = compileScript(
443
+ {
444
+ ...descriptor,
445
+ script: transformJsToTs(script),
446
+ scriptSetup: transformJsToTs(scriptSetup),
447
+ cssVars: []
448
+ },
449
+ { id: `${index++}` }
450
+ );
451
+ try {
452
+ content = preprocessVueCode(compiled.content, scriptSetup);
453
+ } catch (e) {
454
+ error = e;
455
+ content = compiled.content;
456
+ }
457
+ content = rewriteDefault(content, "_sfc_main", ["typescript", "decorators-legacy"]);
318
458
  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
459
  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
460
  ext = scriptSetup.lang || "js";
340
461
  } 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
462
  ext = script.lang || "js";
348
463
  }
464
+ content += "\nexport default _sfc_main\n";
349
465
  } else {
350
466
  content = noScriptContent;
351
467
  ext = "ts";
352
468
  }
353
- return { content, ext };
469
+ return { error, content, ext };
354
470
  }
355
471
 
356
472
  const dtsRE$1 = /\.d\.tsx?$/;
357
473
  function rollupDeclarationFiles({
358
474
  root,
359
- tsConfigPath,
360
475
  outputDir,
361
476
  entryPath,
362
477
  fileName,
@@ -373,8 +488,10 @@ function rollupDeclarationFiles({
373
488
  projectFolder: root,
374
489
  mainEntryPointFilePath: entryPath,
375
490
  compiler: {
376
- tsconfigFilePath: tsConfigPath,
377
- overrideTsconfig: compilerOptions
491
+ overrideTsconfig: {
492
+ $schema: "http://json.schemastore.org/tsconfig",
493
+ compilerOptions
494
+ }
378
495
  },
379
496
  apiReport: {
380
497
  enabled: false,
@@ -439,13 +556,16 @@ const noneExport = "export {};\n";
439
556
  const vueRE = /\.vue$/;
440
557
  const tsRE = /\.(m|c)?tsx?$/;
441
558
  const jsRE = /\.(m|c)?jsx?$/;
442
- const dtsRE = /\.d\.tsx?$/;
559
+ const dtsRE = /\.d\.(m|c)?tsx?$/;
443
560
  const tjsRE = /\.(m|c)?(t|j)sx?$/;
561
+ const mtjsRE = /\.m(t|j)sx?$/;
562
+ const ctjsRE = /\.c(t|j)sx?$/;
444
563
  const watchExtensionRE = /\.(vue|(m|c)?(t|j)sx?)$/;
445
564
  const fullRelativeRE = /^\.\.?\//;
446
565
  const defaultIndex = "index.d.ts";
447
566
  const noop = () => {
448
567
  };
568
+ const extPrefix = (file) => mtjsRE.test(file) ? "m" : ctjsRE.test(file) ? "c" : "";
449
569
  const logPrefix = kolorist.cyan("[vite:dts]");
450
570
  const bundleDebug = debug("vite-plugin-dts:bundle");
451
571
  function dtsPlugin(options = {}) {
@@ -466,7 +586,7 @@ function dtsPlugin(options = {}) {
466
586
  beforeWriteFile = noop,
467
587
  afterBuild = noop
468
588
  } = options;
469
- const compilerOptions = options.compilerOptions ?? {};
589
+ let compilerOptions = options.compilerOptions ?? {};
470
590
  let root;
471
591
  let entryRoot = options.entryRoot ?? "";
472
592
  let libName;
@@ -484,6 +604,7 @@ function dtsPlugin(options = {}) {
484
604
  const sourceDtsFiles = /* @__PURE__ */ new Set();
485
605
  let hasJsVue = false;
486
606
  let allowJs = false;
607
+ let transformError = false;
487
608
  return {
488
609
  name: "vite:dts",
489
610
  apply: "build",
@@ -540,7 +661,7 @@ ${kolorist.cyan(
540
661
  libName = config.build.lib.name || "_default";
541
662
  indexName = typeof filename === "string" ? filename : filename("es", entry);
542
663
  if (!dtsRE.test(indexName)) {
543
- indexName = `${tjsRE.test(indexName) ? indexName.replace(tjsRE, "") : indexName}.d.ts`;
664
+ indexName = `${indexName.replace(tjsRE, "")}.d.${extPrefix(indexName)}ts`;
544
665
  }
545
666
  }
546
667
  root = ensureAbsolute(options.root ?? "", config.root);
@@ -559,32 +680,43 @@ ${kolorist.cyan(
559
680
  return;
560
681
  }
561
682
  setCompileRoot(root);
562
- compilerOptions.rootDir || (compilerOptions.rootDir = root);
563
683
  project = new tsMorph.Project({
564
684
  compilerOptions: mergeObjects(compilerOptions, {
685
+ rootDir: compilerOptions.rootDir || root,
565
686
  noEmitOnError,
566
687
  outDir: ".",
567
- declarationDir: null,
688
+ declarationDir: void 0,
568
689
  noUnusedParameters: false,
569
690
  declaration: true,
570
691
  noEmit: false,
571
- emitDeclarationOnly: true
692
+ emitDeclarationOnly: true,
693
+ composite: false
572
694
  }),
573
695
  tsConfigFilePath: tsConfigPath,
574
696
  skipAddingFilesFromTsConfig: true,
575
697
  libFolderPath: libFolderPath ? ensureAbsolute(libFolderPath, root) : void 0
576
698
  });
577
699
  allowJs = project.getCompilerOptions().allowJs ?? false;
578
- const tsConfig = typescript.readConfigFile(tsConfigPath, project.getFileSystem().readFileSync).config ?? {};
579
- const parentTsConfigPath = tsConfig.extends && ensureAbsolute(tsConfig.extends, root);
580
- const parentTsConfig = parentTsConfigPath ? typescript.readConfigFile(parentTsConfigPath, project.getFileSystem().readFileSync).config : {};
581
- include = ensureArray(
582
- options.include ?? tsConfig.include ?? parentTsConfig.include ?? "**/*"
583
- ).map(normalizeGlob);
584
- exclude = ensureArray(
585
- options.exclude ?? tsConfig.exclude ?? parentTsConfig.exclude ?? "node_modules/**"
586
- ).map(normalizeGlob);
700
+ const tsConfig = { compilerOptions: {} };
701
+ const readFile = project.getFileSystem().readFileSync;
702
+ let currentConfigPath = tsConfigPath;
703
+ while (currentConfigPath) {
704
+ const currentConfig = typescript.readConfigFile(currentConfigPath, readFile).config ?? {};
705
+ Object.assign(tsConfig.compilerOptions, currentConfig.compilerOptions || {});
706
+ if (!tsConfig.include) {
707
+ tsConfig.include = currentConfig.include;
708
+ }
709
+ if (!tsConfig.exclude) {
710
+ tsConfig.exclude = currentConfig.exclude;
711
+ }
712
+ currentConfigPath = currentConfig.extends;
713
+ }
714
+ include = ensureArray(options.include ?? tsConfig.include ?? "**/*").map(normalizeGlob);
715
+ exclude = ensureArray(options.exclude ?? tsConfig.exclude ?? "node_modules/**").map(
716
+ normalizeGlob
717
+ );
587
718
  filter = pluginutils.createFilter(include, exclude, { resolve: root });
719
+ compilerOptions = tsConfig.compilerOptions;
588
720
  },
589
721
  buildStart(inputOptions) {
590
722
  if (Array.isArray(inputOptions.input)) {
@@ -601,7 +733,19 @@ ${kolorist.cyan(
601
733
  return null;
602
734
  }
603
735
  if (vueRE.test(id)) {
604
- const { content, ext } = compileVueCode(code);
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
+ }
605
749
  if (content) {
606
750
  if (ext === "js" || ext === "jsx")
607
751
  hasJsVue = true;
@@ -646,7 +790,7 @@ ${logPrefix} Start generate declaration files...`));
646
790
  includedFileSet.add(file);
647
791
  return;
648
792
  }
649
- includedFileSet.add(`${tjsRE.test(file) ? file.replace(tjsRE, "") : file}.d.ts`);
793
+ includedFileSet.add(`${file.replace(tjsRE, "")}.d.${extPrefix(file)}ts`);
650
794
  });
651
795
  if (hasJsVue) {
652
796
  if (!allowJs) {
@@ -777,7 +921,6 @@ export default ${libName}
777
921
  const path = node_path.resolve(outputDir, `${name.replace(tsRE, "")}.d.ts`);
778
922
  rollupDeclarationFiles({
779
923
  root,
780
- tsConfigPath,
781
924
  compilerOptions,
782
925
  outputDir,
783
926
  entryPath: path,
@@ -790,7 +933,6 @@ export default ${libName}
790
933
  } else {
791
934
  rollupDeclarationFiles({
792
935
  root,
793
- tsConfigPath,
794
936
  compilerOptions,
795
937
  outputDir,
796
938
  entryPath: typesPath,