vite-plugin-dts 2.2.0 → 3.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/dist/index.mjs CHANGED
@@ -5,20 +5,17 @@ import __cjs_mod__ from 'module';
5
5
  const __filename = __cjs_url__.fileURLToPath(import.meta.url);
6
6
  const __dirname = __cjs_path__.dirname(__filename);
7
7
  const require = __cjs_mod__.createRequire(import.meta.url);
8
- import { isAbsolute, resolve as resolve$1, dirname, normalize, sep, relative, basename } from 'node:path';
9
- import fs from 'fs-extra';
10
- import os from 'os';
11
- import { cyan, yellow, red, green } from 'kolorist';
12
- import glob from 'fast-glob';
13
- import debug from 'debug';
14
- import { Project } from 'ts-morph';
15
- import { normalizePath, createLogger } from 'vite';
16
- import typescript from 'typescript';
17
- import { createFilter } from '@rollup/pluginutils';
8
+ import { resolve as resolve$1, posix, isAbsolute, dirname, normalize, sep, relative, basename } from 'node:path';
18
9
  import { existsSync, readdirSync, lstatSync, rmdirSync } from 'node:fs';
19
- import { createRequire } from 'node:module';
20
- import { parse } from '@babel/parser';
21
- import MagicString from 'magic-string';
10
+ import { readFile, writeFile, mkdir, unlink } from 'node:fs/promises';
11
+ import { platform, cpus } from 'os';
12
+ import ts from 'typescript';
13
+ import { normalizePath as normalizePath$1, createLogger } from 'vite';
14
+ import { createFilter } from '@rollup/pluginutils';
15
+ import { createParsedCommandLine } from '@vue/language-core';
16
+ import { createProgram } from 'vue-tsc';
17
+ import debug from 'debug';
18
+ import { cyan, yellow, green } from 'kolorist';
22
19
  import { ExtractorConfig, CompilerState } from '@microsoft/api-extractor';
23
20
  import { Collector } from '@microsoft/api-extractor/lib/collector/Collector.js';
24
21
  import { MessageRouter } from '@microsoft/api-extractor/lib/collector/MessageRouter.js';
@@ -26,6 +23,105 @@ import { SourceMapper } from '@microsoft/api-extractor/lib/collector/SourceMappe
26
23
  import { DtsRollupGenerator, DtsRollupKind } from '@microsoft/api-extractor/lib/generators/DtsRollupGenerator.js';
27
24
  import { PackageJsonLookup } from '@rushstack/node-core-library';
28
25
 
26
+ const dtsRE$1 = /\.d\.tsx?$/;
27
+ function rollupDeclarationFiles({
28
+ root,
29
+ compilerOptions,
30
+ outDir,
31
+ entryPath,
32
+ fileName,
33
+ libFolder,
34
+ bundledPackages
35
+ }) {
36
+ const configObjectFullPath = resolve$1(root, "api-extractor.json");
37
+ const packageJsonLookup = new PackageJsonLookup();
38
+ const packageJsonFullPath = packageJsonLookup.tryGetPackageJsonFilePathFor(configObjectFullPath);
39
+ if (!dtsRE$1.test(fileName)) {
40
+ fileName += ".d.ts";
41
+ }
42
+ const extractorConfig = ExtractorConfig.prepare({
43
+ configObject: {
44
+ projectFolder: root,
45
+ mainEntryPointFilePath: entryPath,
46
+ bundledPackages,
47
+ compiler: {
48
+ // tsconfigFilePath: tsConfigPath,
49
+ overrideTsconfig: {
50
+ $schema: "http://json.schemastore.org/tsconfig",
51
+ compilerOptions: {
52
+ ...compilerOptions,
53
+ target: "ESNext"
54
+ }
55
+ }
56
+ },
57
+ apiReport: {
58
+ enabled: false,
59
+ reportFileName: "<unscopedPackageName>.api.md"
60
+ },
61
+ docModel: {
62
+ enabled: false
63
+ },
64
+ dtsRollup: {
65
+ enabled: true,
66
+ publicTrimmedFilePath: resolve$1(outDir, fileName)
67
+ },
68
+ tsdocMetadata: {
69
+ enabled: false
70
+ },
71
+ messages: {
72
+ compilerMessageReporting: {
73
+ default: {
74
+ logLevel: "none"
75
+ }
76
+ },
77
+ extractorMessageReporting: {
78
+ default: {
79
+ logLevel: "none"
80
+ }
81
+ }
82
+ }
83
+ },
84
+ configObjectFullPath,
85
+ packageJsonFullPath
86
+ });
87
+ const compilerState = CompilerState.create(extractorConfig, {
88
+ localBuild: false,
89
+ showVerboseMessages: false,
90
+ typescriptCompilerFolder: libFolder ? resolve$1(libFolder, "..") : void 0
91
+ });
92
+ const sourceMapper = new SourceMapper();
93
+ const messageRouter = new MessageRouter({
94
+ workingPackageFolder: root,
95
+ messageCallback: void 0,
96
+ messagesConfig: extractorConfig.messages,
97
+ showVerboseMessages: false,
98
+ showDiagnostics: false,
99
+ tsdocConfiguration: extractorConfig.tsdocConfiguration,
100
+ sourceMapper
101
+ });
102
+ const collector = new Collector({
103
+ program: compilerState.program,
104
+ messageRouter,
105
+ extractorConfig,
106
+ sourceMapper
107
+ });
108
+ collector.analyze();
109
+ DtsRollupGenerator.writeTypingsFile(
110
+ collector,
111
+ extractorConfig.publicTrimmedFilePath,
112
+ DtsRollupKind.PublicRelease,
113
+ extractorConfig.newlineKind
114
+ );
115
+ }
116
+
117
+ const windowsSlashRE = /\\/g;
118
+ function slash(p) {
119
+ return p.replace(windowsSlashRE, "/");
120
+ }
121
+ const isWindows = platform() === "win32";
122
+ function normalizePath(id) {
123
+ return posix.normalize(isWindows ? slash(id) : id);
124
+ }
29
125
  function isNativeObj(value) {
30
126
  return Object.prototype.toString.call(value) === "[object Object]";
31
127
  }
@@ -35,39 +131,6 @@ function isRegExp(value) {
35
131
  function isPromise(value) {
36
132
  return !!value && typeof value.then === "function" && typeof value.catch === "function";
37
133
  }
38
- function mergeObjects(sourceObj, targetObj) {
39
- const loop = [
40
- {
41
- source: sourceObj,
42
- target: targetObj
43
- }
44
- ];
45
- while (loop.length) {
46
- const { source, target } = loop.pop();
47
- Object.keys(target).forEach((key) => {
48
- if (isNativeObj(target[key])) {
49
- if (!isNativeObj(source[key])) {
50
- source[key] = {};
51
- }
52
- loop.push({
53
- source: source[key],
54
- target: target[key]
55
- });
56
- } else if (Array.isArray(target[key])) {
57
- if (!Array.isArray(source[key])) {
58
- source[key] = [];
59
- }
60
- loop.push({
61
- source: source[key],
62
- target: target[key]
63
- });
64
- } else {
65
- source[key] = target[key];
66
- }
67
- });
68
- }
69
- return sourceObj;
70
- }
71
134
  function ensureAbsolute(path, root) {
72
135
  return path ? isAbsolute(path) ? path : resolve$1(root, path) : root;
73
136
  }
@@ -220,7 +283,7 @@ function transformAliasImport(filePath, content, aliases, exclude = []) {
220
283
  if (exclude.some((e) => isRegExp(e) ? e.test(matchResult[1]) : String(e) === matchResult[1])) {
221
284
  return str;
222
285
  }
223
- const truthPath = isAbsolute(matchedAlias.replacement) ? normalizePath(relative(dirname(filePath), matchedAlias.replacement)) : normalizePath(matchedAlias.replacement);
286
+ const truthPath = isAbsolute(matchedAlias.replacement) ? normalizePath$1(relative(dirname(filePath), matchedAlias.replacement)) : normalizePath$1(matchedAlias.replacement);
224
287
  return str.replace(
225
288
  isDynamic ? simpleDynamicImportRE : simpleStaticImportRE,
226
289
  `$1'${matchResult[1].replace(
@@ -237,456 +300,67 @@ const pureImportRE = /import\s?['"][^;\n]+?['"];?\n?/g;
237
300
  function removePureImport(content) {
238
301
  return content.replace(pureImportRE, "");
239
302
  }
240
- const setupFunctionRE = /function setup\([\s\S]+\)\s+?\{[\s\S]+return __returned__\n\}/;
241
- function transferSetupPosition(content) {
242
- const match = content.match(setupFunctionRE);
243
- if (match) {
244
- const setupFunction = match[0];
245
- return content.replace(setupFunction, "").replace("setup})", setupFunction.slice("function ".length) + "\n\r})");
246
- }
247
- return content;
248
- }
249
-
250
- const noScriptContent = "import { defineComponent } from 'vue'\nexport default defineComponent({})";
251
- const _require = createRequire(import.meta.url);
252
- let index = 1;
253
- let compileRoot = null;
254
- let compiler;
255
- let vue;
256
- function requireCompiler() {
257
- if (!compiler) {
258
- if (compileRoot) {
259
- try {
260
- compiler = _require(_require.resolve("vue/compiler-sfc", { paths: [compileRoot] }));
261
- } catch (e) {
262
- try {
263
- compiler = _require(_require.resolve("@vue/compiler-sfc", { paths: [compileRoot] }));
264
- } catch (e2) {
265
- }
266
- }
267
- }
268
- if (!compiler) {
269
- try {
270
- compiler = _require("vue/compiler-sfc");
271
- } catch (e) {
272
- try {
273
- compiler = _require("@vue/compiler-sfc");
274
- } catch (e2) {
275
- throw new Error("@vue/compiler-sfc is not present in the dependency tree.\n");
276
- }
277
- }
278
- }
279
- }
280
- return compiler;
281
- }
282
- function isVue3() {
283
- if (!vue) {
284
- if (compileRoot) {
285
- try {
286
- vue = _require(_require.resolve("vue", { paths: [compileRoot] }));
287
- } catch (e) {
288
- }
289
- }
290
- if (!vue) {
291
- try {
292
- vue = _require("vue");
293
- } catch (e) {
294
- throw new Error("vue is not present in the dependency tree.\n");
295
- }
296
- }
297
- }
298
- return vue.version.startsWith("3");
299
- }
300
- function setCompileRoot(root) {
301
- if (root && root !== compileRoot) {
302
- compileRoot = root;
303
- compiler = null;
304
- }
305
- }
306
- function parseCode(code) {
307
- const { parse: parseVueCode } = requireCompiler();
308
- let descriptor;
309
- if (isVue3()) {
310
- descriptor = parseVueCode(code).descriptor;
311
- } else {
312
- descriptor = parseVueCode({ source: code });
313
- }
314
- return descriptor;
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
- const declRecord = /* @__PURE__ */ new Map();
369
- let defaultExport;
370
- let options;
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
- }
392
- if (node.type === "ExportDefaultDeclaration") {
393
- if (node.declaration.type === "ObjectExpression") {
394
- options = node.declaration.properties;
395
- } else if (node.declaration.type === "CallExpression" && node.declaration.arguments[0]?.type === "ObjectExpression") {
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
- }
403
- }
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
- );
417
- }
418
- }
419
- } else {
420
- source.prependLeft(
421
- prop.end,
422
- ` as unknown as __PropType<${propsTypeName}['${prop.key.name}']>`
423
- );
424
- }
425
- }
426
- }
427
- }
428
- if (option.type === "ObjectProperty" && option.key.type === "Identifier" && option.key.name === "components") {
429
- source.overwrite(option.value.start, option.value.end, "undefined");
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;
438
- }
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, `
450
- ${newReturned}
451
- `);
452
- }
453
- }
454
- }
455
- }
456
- break;
457
- }
458
- }
459
- if (propsTypeName) {
460
- if (propsTypeLiteral) {
461
- source.prepend(`
462
- type ${propsTypeName} = ${propsTypeLiteral}
463
-
464
- `);
465
- }
466
- source.prepend("import type { PropType as __PropType } from 'vue'\n");
467
- }
468
- return source.toString();
469
- }
470
- function compileVueCode(code) {
471
- const { compileScript, rewriteDefault } = requireCompiler();
472
- const descriptor = parseCode(code);
473
- const { script, scriptSetup } = descriptor;
474
- let error;
475
- let content;
476
- let ext = "js";
477
- if (script || scriptSetup) {
478
- const compiled = compileScript(
479
- {
480
- ...descriptor,
481
- script: transformJsToTs(script),
482
- scriptSetup: transformJsToTs(scriptSetup),
483
- cssVars: []
484
- },
485
- { id: `${index++}` }
486
- );
487
- try {
488
- content = preprocessVueCode(compiled.content, scriptSetup);
489
- } catch (e) {
490
- error = e;
491
- content = compiled.content;
492
- }
493
- content = rewriteDefault(content, "_sfc_main", ["typescript", "decorators-legacy"]);
494
- if (scriptSetup) {
495
- content = transferSetupPosition(content);
496
- ext = scriptSetup.lang || "js";
497
- } else if (script && script.content) {
498
- ext = script.lang || "js";
499
- }
500
- content += "\nexport default _sfc_main\n";
501
- } else {
502
- content = noScriptContent;
503
- ext = "ts";
504
- }
505
- return { error, content, ext };
506
- }
507
303
 
508
- const dtsRE$1 = /\.d\.tsx?$/;
509
- function rollupDeclarationFiles({
510
- root,
511
- compilerOptions,
512
- outputDir,
513
- entryPath,
514
- fileName,
515
- libFolder,
516
- bundledPackages
517
- }) {
518
- const configObjectFullPath = resolve$1(root, "api-extractor.json");
519
- const packageJsonLookup = new PackageJsonLookup();
520
- const packageJsonFullPath = packageJsonLookup.tryGetPackageJsonFilePathFor(configObjectFullPath);
521
- if (!dtsRE$1.test(fileName)) {
522
- fileName += ".d.ts";
523
- }
524
- const extractorConfig = ExtractorConfig.prepare({
525
- configObject: {
526
- projectFolder: root,
527
- mainEntryPointFilePath: entryPath,
528
- bundledPackages,
529
- compiler: {
530
- overrideTsconfig: {
531
- $schema: "http://json.schemastore.org/tsconfig",
532
- compilerOptions
533
- }
534
- },
535
- apiReport: {
536
- enabled: false,
537
- reportFileName: "<unscopedPackageName>.api.md"
538
- },
539
- docModel: {
540
- enabled: false
541
- },
542
- dtsRollup: {
543
- enabled: true,
544
- publicTrimmedFilePath: resolve$1(outputDir, fileName)
545
- },
546
- tsdocMetadata: {
547
- enabled: false
548
- },
549
- messages: {
550
- compilerMessageReporting: {
551
- default: {
552
- logLevel: "none"
553
- }
554
- },
555
- extractorMessageReporting: {
556
- default: {
557
- logLevel: "none"
558
- }
559
- }
560
- }
561
- },
562
- configObjectFullPath,
563
- packageJsonFullPath
564
- });
565
- const compilerState = CompilerState.create(extractorConfig, {
566
- localBuild: false,
567
- showVerboseMessages: false,
568
- typescriptCompilerFolder: libFolder ? resolve$1(libFolder, "..") : void 0
569
- });
570
- const sourceMapper = new SourceMapper();
571
- const messageRouter = new MessageRouter({
572
- workingPackageFolder: root,
573
- messageCallback: void 0,
574
- messagesConfig: extractorConfig.messages,
575
- showVerboseMessages: false,
576
- showDiagnostics: false,
577
- tsdocConfiguration: extractorConfig.tsdocConfiguration,
578
- sourceMapper
579
- });
580
- const collector = new Collector({
581
- program: compilerState.program,
582
- messageRouter,
583
- extractorConfig,
584
- sourceMapper
585
- });
586
- collector.analyze();
587
- DtsRollupGenerator.writeTypingsFile(
588
- collector,
589
- extractorConfig.publicTrimmedFilePath,
590
- DtsRollupKind.PublicRelease,
591
- extractorConfig.newlineKind
592
- );
593
- }
594
-
595
- const noneExport = "export {};\n";
596
- const vueRE = /\.vue$/;
597
- const svelteRE = /\.svelte$/;
598
304
  const tsRE = /\.(m|c)?tsx?$/;
599
- const jsRE = /\.(m|c)?jsx?$/;
600
305
  const dtsRE = /\.d\.(m|c)?tsx?$/;
601
306
  const tjsRE = /\.(m|c)?(t|j)sx?$/;
602
307
  const mtjsRE = /\.m(t|j)sx?$/;
603
308
  const ctjsRE = /\.c(t|j)sx?$/;
604
- const watchExtensionRE = /\.(vue|(m|c)?(t|j)sx?)$/;
605
309
  const fullRelativeRE = /^\.\.?\//;
310
+ const watchExtensionRE = /\.(vue|(m|c)?(t|j)sx?)$/;
606
311
  const defaultIndex = "index.d.ts";
312
+ const logPrefix = cyan("[vite:dts]");
313
+ const bundleDebug = debug("vite-plugin-dts:bundle");
314
+ const fixedCompilerOptions = {
315
+ noEmit: false,
316
+ declaration: true,
317
+ emitDeclarationOnly: true,
318
+ noUnusedParameters: false,
319
+ checkJs: false,
320
+ skipLibCheck: true,
321
+ preserveSymlinks: false,
322
+ noEmitOnError: void 0,
323
+ target: ts.ScriptTarget.ESNext
324
+ };
607
325
  const noop = () => {
608
326
  };
609
327
  const extPrefix = (file) => mtjsRE.test(file) ? "m" : ctjsRE.test(file) ? "c" : "";
610
328
  const resolve = (...paths) => normalizePath(resolve$1(...paths));
611
- const logPrefix = cyan("[vite:dts]");
612
- const bundleDebug = debug("vite-plugin-dts:bundle");
613
329
  function dtsPlugin(options = {}) {
614
330
  const {
615
- tsConfigFilePath = "tsconfig.json",
616
- aliasesExclude = [],
617
- cleanVueFileName = false,
331
+ tsconfigPath,
618
332
  staticImport = false,
619
333
  clearPureImport = true,
334
+ cleanVueFileName = false,
620
335
  insertTypesEntry = false,
621
336
  rollupTypes = false,
622
337
  bundledPackages = [],
623
- noEmitOnError = false,
624
- skipDiagnostics = false,
338
+ aliasesExclude = [],
339
+ logLevel,
625
340
  copyDtsFiles = false,
626
- logLevel = void 0,
627
341
  afterDiagnostic = noop,
628
342
  beforeWriteFile = noop,
629
343
  afterBuild = noop
630
344
  } = options;
631
- let compilerOptions = options.compilerOptions ?? {};
632
- let root;
345
+ let compilerOptions;
346
+ let rawCompilerOptions;
347
+ let root = ensureAbsolute(options.root ?? "", process.cwd());
633
348
  let entryRoot = options.entryRoot ?? "";
634
- let libName;
635
- let indexName;
636
- let aliases;
637
349
  let entries;
638
- let logger;
639
- let project;
640
- let tsConfigPath;
641
- let outputDirs;
642
- let isBundle = false;
643
350
  let include;
644
351
  let exclude;
645
- let filter;
646
- let libFolderPath = options.libFolderPath;
647
- const sourceDtsFiles = /* @__PURE__ */ new Set();
648
- const includedFiles = /* @__PURE__ */ new Set();
649
- const emittedFiles = /* @__PURE__ */ new Map();
650
- let hasJsVue = false;
651
- let allowJs = false;
652
- let transformError = false;
653
- async function internalTransform(id) {
654
- if (!project || !filter(id)) {
655
- return;
656
- }
657
- if (vueRE.test(id)) {
658
- const { error, content, ext } = compileVueCode(await fs.readFile(id, "utf-8"));
659
- if (!transformError && error) {
660
- logger.error(
661
- red(
662
- `
663
- ${cyan(
664
- "[vite:dts]"
665
- )} A error occurred when transform code, maybe there are some inertnal bugs.
666
- `
667
- )
668
- );
669
- transformError = true;
670
- }
671
- if (content) {
672
- if (ext === "js" || ext === "jsx")
673
- hasJsVue = true;
674
- project.createSourceFile(`${id}.${ext || "js"}`, content, { overwrite: true });
675
- }
676
- } else if (!id.includes(".vue?vue") && (tsRE.test(id) || allowJs && jsRE.test(id))) {
677
- project.createSourceFile(id, await fs.readFile(id, "utf-8"), { overwrite: true });
678
- } else if (svelteRE.test(id)) {
679
- const content = "export { SvelteComponentTyped as default } from 'svelte/internal';";
680
- project.createSourceFile(`${id}.ts`, content, { overwrite: true });
681
- }
682
- }
352
+ let outDirs;
353
+ let aliases;
354
+ let libName;
355
+ let indexName;
356
+ let logger;
357
+ let bundled = false;
358
+ let program;
683
359
  return {
684
360
  name: "vite:dts",
685
361
  apply: "build",
686
362
  enforce: "pre",
687
363
  config(config) {
688
- if (isBundle)
689
- return;
690
364
  const aliasOptions = config?.resolve?.alias ?? [];
691
365
  if (isNativeObj(aliasOptions)) {
692
366
  aliases = Object.entries(aliasOptions).map(([key, value]) => {
@@ -704,22 +378,18 @@ ${cyan(
704
378
  }
705
379
  },
706
380
  configResolved(config) {
707
- if (isBundle)
708
- return;
709
381
  logger = logLevel ? createLogger(logLevel, { allowClearScreen: config.clearScreen }) : config.logger;
710
- if (!config.build.lib) {
711
- logger.warn(
712
- yellow(
713
- `
714
- ${cyan(
715
- "[vite:dts]"
716
- )} You are building a library that may not need to generate declaration files.
717
- `
718
- )
719
- );
720
- libName = "_default";
721
- indexName = defaultIndex;
722
- } else {
382
+ root = ensureAbsolute(options.root ?? "", config.root);
383
+ if (config.build.lib) {
384
+ const input = typeof config.build.lib.entry === "string" ? [config.build.lib.entry] : config.build.lib.entry;
385
+ if (Array.isArray(input)) {
386
+ entries = input.reduce((prev, current) => {
387
+ prev[basename(current)] = current;
388
+ return prev;
389
+ }, {});
390
+ } else {
391
+ entries = { ...input };
392
+ }
723
393
  const filename = config.build.lib.fileName ?? defaultIndex;
724
394
  const entry = typeof config.build.lib.entry === "string" ? config.build.lib.entry : Object.values(config.build.lib.entry)[0];
725
395
  libName = config.build.lib.name || "_default";
@@ -727,212 +397,177 @@ ${cyan(
727
397
  if (!dtsRE.test(indexName)) {
728
398
  indexName = `${indexName.replace(tjsRE, "")}.d.${extPrefix(indexName)}ts`;
729
399
  }
730
- }
731
- root = ensureAbsolute(options.root ?? "", config.root);
732
- tsConfigPath = ensureAbsolute(tsConfigFilePath, root);
733
- libFolderPath = libFolderPath && ensureAbsolute(libFolderPath, root);
734
- outputDirs = options.outputDir ? ensureArray(options.outputDir).map((d) => ensureAbsolute(d, root)) : [ensureAbsolute(config.build.outDir, root)];
735
- if (!outputDirs[0]) {
736
- logger.error(
737
- red(
400
+ } else {
401
+ logger.warn(
402
+ yellow(
738
403
  `
739
404
  ${cyan(
740
405
  "[vite:dts]"
741
- )} Can not resolve declaration directory. Please check your vite config and plugin options.
406
+ )} You are building a library that may not need to generate declaration files.
742
407
  `
743
408
  )
744
409
  );
745
- return;
410
+ libName = "_default";
411
+ indexName = defaultIndex;
746
412
  }
747
- setCompileRoot(root);
748
- project = new Project({
749
- compilerOptions: mergeObjects(compilerOptions, {
750
- rootDir: compilerOptions.rootDir || root,
751
- noEmitOnError,
752
- outDir: outputDirs[0],
753
- declarationDir: void 0,
754
- noUnusedParameters: false,
755
- declaration: true,
756
- noEmit: false,
757
- emitDeclarationOnly: true,
758
- composite: false
759
- }),
760
- tsConfigFilePath: tsConfigPath,
761
- skipAddingFilesFromTsConfig: true,
762
- libFolderPath
763
- });
764
- allowJs = project.getCompilerOptions().allowJs ?? false;
765
- const tsConfig = { compilerOptions: {} };
766
- const readFile = project.getFileSystem().readFileSync;
767
- let currentConfigPath = tsConfigPath;
768
- while (currentConfigPath) {
769
- const currentConfig = typescript.readConfigFile(currentConfigPath, readFile).config ?? {};
770
- Object.assign(tsConfig.compilerOptions, currentConfig.compilerOptions || {});
771
- if (!tsConfig.include) {
772
- tsConfig.include = currentConfig.include;
773
- }
774
- if (!tsConfig.exclude) {
775
- tsConfig.exclude = currentConfig.exclude;
776
- }
777
- currentConfigPath = currentConfig.extends && ensureAbsolute(currentConfig.extends, dirname(currentConfigPath));
413
+ if (!options.outDir) {
414
+ outDirs = [ensureAbsolute(config.build.outDir, root)];
778
415
  }
779
- include = ensureArray(options.include ?? tsConfig.include ?? "**/*").map(normalizeGlob);
780
- exclude = ensureArray(options.exclude ?? tsConfig.exclude ?? "node_modules/**").map(
781
- normalizeGlob
782
- );
783
- filter = createFilter(include, exclude, { resolve: root });
784
- compilerOptions = tsConfig.compilerOptions;
416
+ bundleDebug("parse vite config");
785
417
  },
786
- async buildStart(inputOptions) {
787
- if (Array.isArray(inputOptions.input)) {
788
- entries = inputOptions.input.reduce((prev, current) => {
418
+ options(options2) {
419
+ if (entries)
420
+ return;
421
+ const input = typeof options2.input === "string" ? [options2.input] : options2.input;
422
+ if (Array.isArray(input)) {
423
+ entries = input.reduce((prev, current) => {
789
424
  prev[basename(current)] = current;
790
425
  return prev;
791
426
  }, {});
792
427
  } else {
793
- entries = { ...inputOptions.input };
428
+ entries = { ...input };
794
429
  }
795
- bundleDebug("parse entries");
796
- sourceDtsFiles.clear();
797
- includedFiles.clear();
798
- if (project && include && include.length) {
799
- const files = await glob(include, {
800
- cwd: root,
801
- absolute: true,
802
- ignore: exclude
803
- });
804
- for (const file of files) {
805
- this.addWatchFile(file);
806
- if (dtsRE.test(file)) {
807
- sourceDtsFiles.add(project.addSourceFileAtPath(file));
808
- if (!copyDtsFiles) {
809
- continue;
810
- }
811
- includedFiles.add(file);
812
- continue;
813
- }
814
- includedFiles.add(`${file.replace(tjsRE, "")}.d.${extPrefix(file)}ts`);
815
- }
816
- if (hasJsVue) {
817
- if (!allowJs) {
818
- logger.warn(
819
- yellow(
820
- `${cyan(
821
- "[vite:dts]"
822
- )} Some js files are referenced, but you may not enable the 'allowJs' option.`
823
- )
824
- );
825
- }
826
- project.compilerOptions.set({ allowJs: true });
827
- }
828
- bundleDebug("collect files");
829
- }
830
- },
831
- async transform(_, id) {
832
- await internalTransform(id);
833
- return null;
430
+ logger = logger || console;
431
+ libName = "_default";
432
+ indexName = defaultIndex;
433
+ bundleDebug("parse options");
834
434
  },
835
- async watchChange(id) {
435
+ watchChange(id) {
836
436
  if (watchExtensionRE.test(id)) {
837
- isBundle = false;
838
- if (project) {
839
- const sourceFile = project.getSourceFile(normalizePath(id));
840
- sourceFile && project.removeSourceFile(sourceFile);
841
- await internalTransform(id);
437
+ bundled = false;
438
+ program?.getSourceFile(normalizePath(id));
439
+ }
440
+ },
441
+ async buildStart() {
442
+ if (program)
443
+ return;
444
+ const configPath = tsconfigPath ? ensureAbsolute(tsconfigPath, root) : ts.findConfigFile(root, ts.sys.fileExists);
445
+ const content = configPath && createParsedCommandLine(ts, ts.sys, configPath);
446
+ const config = content ? {
447
+ include: content.raw.include,
448
+ exclude: content.raw.exclude,
449
+ fileNames: content.fileNames,
450
+ raw: content.raw,
451
+ options: {
452
+ ...content.options,
453
+ ...options.compilerOptions || {},
454
+ ...fixedCompilerOptions
842
455
  }
456
+ } : { options: { ...options.compilerOptions || {}, ...fixedCompilerOptions } };
457
+ if (!outDirs) {
458
+ outDirs = options.outDir ? ensureArray(options.outDir).map((d) => ensureAbsolute(d, root)) : [ensureAbsolute(config.raw?.compilerOptions?.outDir || "dist", root)];
843
459
  }
460
+ include = ensureArray(options.include ?? config.include ?? "**/*").map(normalizeGlob);
461
+ exclude = ensureArray(options.exclude ?? config.exclude ?? "node_modules/**").map(
462
+ normalizeGlob
463
+ );
464
+ compilerOptions = { ...config.options, outDir: outDirs[0] };
465
+ rawCompilerOptions = config.raw?.compilerOptions || {};
466
+ const host = ts.createCompilerHost(compilerOptions, true);
467
+ program = createProgram({
468
+ host,
469
+ rootNames: Object.values(entries).concat(
470
+ config.fileNames?.filter((name) => dtsRE.test(name)) || []
471
+ ),
472
+ options: compilerOptions
473
+ });
474
+ libName = libName || "_default";
475
+ indexName = indexName || defaultIndex;
476
+ const diagnostics = program.getDeclarationDiagnostics();
477
+ if (diagnostics?.length) {
478
+ logger.error(ts.formatDiagnostics(diagnostics, host));
479
+ }
480
+ if (typeof afterDiagnostic === "function") {
481
+ const result = afterDiagnostic(diagnostics);
482
+ isPromise(result) && await result;
483
+ }
484
+ bundleDebug("create ts program");
844
485
  },
845
- async closeBundle() {
846
- if (!outputDirs || !project || isBundle)
486
+ async writeBundle() {
487
+ if (!outDirs || !program || bundled)
847
488
  return;
848
489
  logger.info(green(`
849
490
  ${logPrefix} Start generate declaration files...`));
850
- bundleDebug("start");
851
- isBundle = true;
852
- emittedFiles.clear();
853
- const startTime = Date.now();
854
- project.resolveSourceFileDependencies();
855
- bundleDebug("resolve");
856
- if (!skipDiagnostics) {
857
- const diagnostics = project.getPreEmitDiagnostics();
858
- if (diagnostics?.length) {
859
- logger.warn(project.formatDiagnosticsWithColorAndContext(diagnostics));
491
+ bundled = true;
492
+ const outDir = outDirs[0];
493
+ const emittedFiles = /* @__PURE__ */ new Map();
494
+ const filter = createFilter(include, exclude, { resolve: root });
495
+ const service = program.__vue.languageService;
496
+ const sourceFiles = program.getSourceFiles();
497
+ const outputFiles = sourceFiles.map((sourceFile) => {
498
+ if (!filter(sourceFile.fileName))
499
+ return [];
500
+ const output = [];
501
+ if (copyDtsFiles && dtsRE.test(sourceFile.fileName)) {
502
+ output.push({
503
+ path: sourceFile.fileName,
504
+ content: sourceFile.getFullText()
505
+ });
860
506
  }
861
- if (typeof afterDiagnostic === "function") {
862
- const result = afterDiagnostic(diagnostics);
863
- isPromise(result) && await result;
864
- }
865
- bundleDebug("diagnostics");
866
- }
867
- const outputDir = outputDirs[0];
868
- const dtsOutputFiles = Array.from(sourceDtsFiles).map((sourceFile) => ({
869
- path: sourceFile.getFilePath(),
870
- content: sourceFile.getFullText()
871
- }));
872
- const service = project.getLanguageService();
873
- const outputFiles = project.getSourceFiles().map(
874
- (sourceFile) => service.getEmitOutput(sourceFile, true).getOutputFiles().map((outputFile) => ({
875
- path: resolve(root, relative(outputDir, outputFile.compilerObject.name)),
876
- content: outputFile.getText()
877
- }))
878
- ).flat().concat(dtsOutputFiles);
879
- bundleDebug("emit");
507
+ return output.concat(
508
+ service.getEmitOutput(sourceFile.fileName, true).outputFiles.map((outputFile) => {
509
+ return {
510
+ path: resolve(root, relative(outDir, outputFile.name)),
511
+ content: outputFile.text
512
+ };
513
+ })
514
+ );
515
+ }).flat();
516
+ bundleDebug("emit output");
880
517
  entryRoot = entryRoot || queryPublicPath(outputFiles.map((file) => file.path));
881
518
  entryRoot = ensureAbsolute(entryRoot, root);
882
- await runParallel(os.cpus().length, outputFiles, async (outputFile) => {
883
- let filePath = outputFile.path;
884
- let content = outputFile.content;
885
- const isMapFile = filePath.endsWith(".map");
886
- if (!includedFiles.has(isMapFile ? filePath.slice(0, -4) : filePath) || clearPureImport && content === noneExport) {
887
- return;
888
- }
889
- if (!isMapFile && content && content !== noneExport) {
519
+ await runParallel(cpus().length, outputFiles, async ({ path, content }) => {
520
+ const isMapFile = path.endsWith(".map");
521
+ if (!isMapFile && content) {
890
522
  content = clearPureImport ? removePureImport(content) : content;
891
- content = transformAliasImport(filePath, content, aliases, aliasesExclude);
523
+ content = transformAliasImport(path, content, aliases, aliasesExclude);
892
524
  content = staticImport || rollupTypes ? transformDynamicImport(content) : content;
893
525
  }
894
- filePath = resolve(
895
- outputDir,
896
- relative(entryRoot, cleanVueFileName ? filePath.replace(".vue.d.ts", ".d.ts") : filePath)
526
+ path = resolve(
527
+ outDir,
528
+ relative(entryRoot, cleanVueFileName ? path.replace(".vue.d.ts", ".d.ts") : path)
897
529
  );
898
530
  content = cleanVueFileName ? content.replace(/['"](.+)\.vue['"]/g, '"$1"') : content;
899
531
  if (typeof beforeWriteFile === "function") {
900
- const result = beforeWriteFile(filePath, content);
532
+ const result = beforeWriteFile(path, content);
901
533
  if (result === false)
902
534
  return;
903
535
  if (result && isNativeObj(result)) {
904
- filePath = result.filePath || filePath;
536
+ path = result.filePath || path;
905
537
  content = result.content ?? content;
906
538
  }
907
539
  }
908
- filePath = normalizePath(filePath);
909
- await fs.mkdir(dirname(filePath), { recursive: true });
910
- await fs.writeFile(filePath, content, "utf-8");
911
- emittedFiles.set(filePath, content);
540
+ path = normalizePath(path);
541
+ const dir = dirname(path);
542
+ if (!existsSync(dir)) {
543
+ await mkdir(dir, { recursive: true });
544
+ }
545
+ await writeFile(path, content, "utf-8");
546
+ emittedFiles.set(path, content);
912
547
  });
913
- bundleDebug("output");
548
+ bundleDebug("write output");
914
549
  if (insertTypesEntry || rollupTypes) {
915
550
  const pkgPath = resolve(root, "package.json");
916
- const pkg = fs.existsSync(pkgPath) ? JSON.parse(await fs.readFile(pkgPath, "utf-8")) : {};
551
+ const pkg = existsSync(pkgPath) ? JSON.parse(await readFile(pkgPath, "utf-8")) : {};
917
552
  const entryNames = Object.keys(entries);
918
553
  const types = pkg.types || pkg.typings || pkg.publishConfig?.types || pkg.publishConfig?.typings || (pkg.exports?.["."] || pkg.exports?.["./"])?.types;
919
554
  const multiple = entryNames.length > 1;
920
- const typesPath = types ? resolve(root, types) : resolve(outputDir, indexName);
555
+ const typesPath = types ? resolve(root, types) : resolve(outDir, indexName);
921
556
  for (const name of entryNames) {
922
- let filePath = multiple ? resolve(outputDir, `${name.replace(tsRE, "")}.d.ts`) : typesPath;
923
- if (fs.existsSync(filePath))
557
+ let path = multiple ? resolve(outDir, `${name.replace(tsRE, "")}.d.ts`) : typesPath;
558
+ if (existsSync(path))
924
559
  continue;
925
560
  const index = resolve(
926
- outputDir,
561
+ outDir,
927
562
  relative(entryRoot, `${entries[name].replace(tsRE, "")}.d.ts`)
928
563
  );
929
- let fromPath = normalizePath(relative(dirname(filePath), index));
564
+ let fromPath = normalizePath(relative(dirname(path), index));
930
565
  fromPath = fromPath.replace(dtsRE, "");
931
566
  fromPath = fullRelativeRE.test(fromPath) ? fromPath : `./${fromPath}`;
932
567
  let content = `export * from '${fromPath}'
933
568
  `;
934
- if (fs.existsSync(index)) {
935
- const entryCodes = await fs.readFile(index, "utf-8");
569
+ if (existsSync(index)) {
570
+ const entryCodes = await readFile(index, "utf-8");
936
571
  if (entryCodes.includes("export default")) {
937
572
  content += `import ${libName} from '${fromPath}'
938
573
  export default ${libName}
@@ -941,32 +576,41 @@ export default ${libName}
941
576
  }
942
577
  let result;
943
578
  if (typeof beforeWriteFile === "function") {
944
- result = beforeWriteFile(filePath, content);
579
+ result = beforeWriteFile(path, content);
945
580
  if (result && isNativeObj(result)) {
946
- filePath = result.filePath ?? filePath;
581
+ path = result.filePath ?? path;
947
582
  content = result.content ?? content;
948
583
  }
949
584
  }
950
- filePath = normalizePath(filePath);
585
+ path = normalizePath(path);
951
586
  if (result !== false) {
952
- await fs.writeFile(filePath, content, "utf-8");
953
- emittedFiles.set(filePath, content);
587
+ await writeFile(path, content, "utf-8");
588
+ emittedFiles.set(path, content);
954
589
  }
955
590
  }
956
591
  bundleDebug("insert index");
957
592
  if (rollupTypes) {
958
593
  logger.info(green(`${logPrefix} Start rollup declaration files...`));
594
+ let libFolder = resolve(root, "node_modules/typescript");
595
+ if (!existsSync(libFolder)) {
596
+ if (root !== entryRoot) {
597
+ libFolder = resolve(entryRoot, "node_modules/typescript");
598
+ if (!existsSync(libFolder))
599
+ libFolder = void 0;
600
+ }
601
+ libFolder = void 0;
602
+ }
959
603
  const rollupFiles = /* @__PURE__ */ new Set();
960
604
  if (multiple) {
961
605
  for (const name of entryNames) {
962
- const path = resolve(outputDir, `${name.replace(tsRE, "")}.d.ts`);
606
+ const path = resolve(outDir, `${name.replace(tsRE, "")}.d.ts`);
963
607
  rollupDeclarationFiles({
964
608
  root,
965
- compilerOptions,
966
- outputDir,
609
+ compilerOptions: rawCompilerOptions,
610
+ outDir,
967
611
  entryPath: path,
968
612
  fileName: basename(path),
969
- libFolder: libFolderPath,
613
+ libFolder,
970
614
  bundledPackages
971
615
  });
972
616
  emittedFiles.delete(path);
@@ -975,48 +619,47 @@ export default ${libName}
975
619
  } else {
976
620
  rollupDeclarationFiles({
977
621
  root,
978
- compilerOptions,
979
- outputDir,
622
+ compilerOptions: rawCompilerOptions,
623
+ outDir,
980
624
  entryPath: typesPath,
981
625
  fileName: basename(typesPath),
982
- libFolder: libFolderPath,
626
+ libFolder,
983
627
  bundledPackages
984
628
  });
985
629
  emittedFiles.delete(typesPath);
986
630
  rollupFiles.add(typesPath);
987
631
  }
988
- await runParallel(os.cpus().length, Array.from(emittedFiles.keys()), (f) => fs.unlink(f));
989
- removeDirIfEmpty(outputDir);
632
+ await runParallel(cpus().length, Array.from(emittedFiles.keys()), (f) => unlink(f));
633
+ removeDirIfEmpty(outDir);
990
634
  emittedFiles.clear();
991
635
  for (const file of rollupFiles) {
992
- emittedFiles.set(file, await fs.readFile(file, "utf-8"));
636
+ emittedFiles.set(file, await readFile(file, "utf-8"));
993
637
  }
994
- bundleDebug("rollup");
638
+ bundleDebug("rollup output");
995
639
  }
996
640
  }
997
- if (outputDirs.length > 1) {
998
- const dirs = outputDirs.slice(1);
999
- await runParallel(
1000
- os.cpus().length,
1001
- Array.from(emittedFiles),
1002
- async ([wroteFile, content]) => {
1003
- const relativePath = relative(outputDir, wroteFile);
1004
- await Promise.all(
1005
- dirs.map(async (dir) => {
1006
- const filePath = resolve(dir, relativePath);
1007
- await fs.mkdir(dirname(filePath), { recursive: true });
1008
- await fs.writeFile(filePath, content, "utf-8");
1009
- })
1010
- );
1011
- }
1012
- );
641
+ if (outDirs.length > 1) {
642
+ const dirs = outDirs.slice(1);
643
+ await runParallel(cpus().length, Array.from(emittedFiles), async ([wroteFile, content]) => {
644
+ const relativePath = relative(outDir, wroteFile);
645
+ await Promise.all(
646
+ dirs.map(async (dir) => {
647
+ const path = resolve(dir, relativePath);
648
+ const dirPath = dirname(path);
649
+ if (!existsSync(dirPath)) {
650
+ await mkdir(dirPath, { recursive: true });
651
+ }
652
+ await writeFile(path, content, "utf-8");
653
+ })
654
+ );
655
+ });
1013
656
  }
1014
657
  if (typeof afterBuild === "function") {
1015
658
  const result = afterBuild();
1016
659
  isPromise(result) && await result;
1017
660
  }
1018
661
  bundleDebug("finish");
1019
- logger.info(green(`${logPrefix} Declaration files built in ${Date.now() - startTime}ms.
662
+ logger.info(green(`${logPrefix} Declaration files built.
1020
663
  `));
1021
664
  }
1022
665
  };