vite-plugin-dts 3.1.1 → 3.2.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/README.md CHANGED
@@ -97,11 +97,14 @@ export interface Resolver {
97
97
  supports: (id: string) => void | boolean,
98
98
  /**
99
99
  * Transform source to declaration files
100
+ *
101
+ * Note that the path of the returns should base on `outDir`, or relative path to `root`
100
102
  */
101
103
  transform: (payload: {
102
104
  id: string,
103
105
  code: string,
104
106
  root: string,
107
+ outDir: string,
105
108
  host: ts.CompilerHost,
106
109
  program: ts.Program,
107
110
  service: ts.LanguageService
@@ -166,6 +169,16 @@ export interface PluginOptions {
166
169
  */
167
170
  resolvers?: Resolver[],
168
171
 
172
+ /**
173
+ * Parsing `paths` of tsconfig.json to aliases
174
+ *
175
+ * Note that these aliases only use for declaration files
176
+ *
177
+ * @default true
178
+ * @remarks Only use first replacement of each path
179
+ */
180
+ pathsToAliases?: boolean,
181
+
169
182
  /**
170
183
  * Set which paths should be excluded when transforming aliases
171
184
  *
package/README.zh-CN.md CHANGED
@@ -97,11 +97,14 @@ export interface Resolver {
97
97
  supports: (id: string) => void | boolean,
98
98
  /**
99
99
  * 将源文件转换为类型文件
100
+ *
101
+ * 注意,返回的文件的路径应该基于 `outDir`,或者相对于 `root`
100
102
  */
101
103
  transform: (payload: {
102
104
  id: string,
103
105
  code: string,
104
106
  root: string,
107
+ outDir: string,
105
108
  host: ts.CompilerHost,
106
109
  program: ts.Program,
107
110
  service: ts.LanguageService
@@ -166,6 +169,16 @@ export interface PluginOptions {
166
169
  */
167
170
  resolvers?: Resolver[],
168
171
 
172
+ /**
173
+ * 解析 tsconfig.json 的 `paths` 作为别名
174
+ *
175
+ * 注意,这些别名仅用在类型文件中使用
176
+ *
177
+ * @default true
178
+ * @remarks 只使用每个路径的第一个替换
179
+ */
180
+ pathsToAliases?: boolean,
181
+
169
182
  /**
170
183
  * 设置在转换别名时哪些路径需要排除
171
184
  *
package/dist/index.cjs CHANGED
@@ -114,6 +114,30 @@ function rollupDeclarationFiles({
114
114
  );
115
115
  }
116
116
 
117
+ const jsonRE = /\.json$/;
118
+ function JsonResolver() {
119
+ return {
120
+ name: "json",
121
+ supports(id) {
122
+ return jsonRE.test(id);
123
+ },
124
+ transform({ id, root, program }) {
125
+ const sourceFile = program.getSourceFile(id);
126
+ if (!sourceFile)
127
+ return [];
128
+ return [
129
+ {
130
+ path: node_path.relative(root, `${id}.d.ts`),
131
+ content: `declare const _default: ${sourceFile.text};
132
+
133
+ export default _default;
134
+ `
135
+ }
136
+ ];
137
+ }
138
+ };
139
+ }
140
+
117
141
  const svelteRE = /\.svelte$/;
118
142
  function SvelteResolver() {
119
143
  return {
@@ -121,17 +145,46 @@ function SvelteResolver() {
121
145
  supports(id) {
122
146
  return svelteRE.test(id);
123
147
  },
124
- transform({ id }) {
148
+ transform({ id, root }) {
125
149
  return [
126
150
  {
127
- path: `${id}.d.ts`,
128
- content: "export { SvelteComponentTyped as default } from 'svelte';"
151
+ path: node_path.relative(root, `${id}.d.ts`),
152
+ content: "export { SvelteComponentTyped as default } from 'svelte';\n"
129
153
  }
130
154
  ];
131
155
  }
132
156
  };
133
157
  }
134
158
 
159
+ const vueRE = /\.vue$/;
160
+ function VueResolver() {
161
+ return {
162
+ name: "vue",
163
+ supports(id) {
164
+ return vueRE.test(id);
165
+ },
166
+ transform({ id, program, service }) {
167
+ const sourceFile = program.getSourceFile(id) || program.getSourceFile(id + ".ts") || program.getSourceFile(id + ".js") || program.getSourceFile(id + ".tsx") || program.getSourceFile(id + ".jsx");
168
+ if (!sourceFile)
169
+ return [];
170
+ return service.getEmitOutput(sourceFile.fileName, true).outputFiles.map((file) => {
171
+ return {
172
+ path: file.name,
173
+ content: file.text
174
+ };
175
+ });
176
+ }
177
+ };
178
+ }
179
+
180
+ function parseResolvers(resolvers) {
181
+ const nameMap = /* @__PURE__ */ new Map();
182
+ for (const resolver of resolvers) {
183
+ resolver.name && nameMap.set(resolver.name, resolver);
184
+ }
185
+ return Array.from(nameMap.values());
186
+ }
187
+
135
188
  const windowsSlashRE = /\\+/g;
136
189
  function slash(p) {
137
190
  return p.replace(windowsSlashRE, "/");
@@ -232,38 +285,6 @@ function removeDirIfEmpty(dir) {
232
285
  return onlyHasDir;
233
286
  }
234
287
 
235
- const vueRE = /\.vue$/;
236
- function VueResolver() {
237
- return {
238
- name: "vue",
239
- supports(id) {
240
- return vueRE.test(id);
241
- },
242
- transform({ id, root, program, service }) {
243
- let sourceFile = program.getSourceFile(id);
244
- if (!sourceFile && vueRE.test(id)) {
245
- sourceFile = program.getSourceFile(id + ".ts") || program.getSourceFile(id + ".js") || program.getSourceFile(id + ".tsx") || program.getSourceFile(id + ".jsx");
246
- }
247
- if (!sourceFile)
248
- return [];
249
- return service.getEmitOutput(sourceFile.fileName, true).outputFiles.map((file) => {
250
- return {
251
- path: resolve(root, file.name),
252
- content: file.text
253
- };
254
- });
255
- }
256
- };
257
- }
258
-
259
- function parseResolvers(resolvers) {
260
- const nameMap = /* @__PURE__ */ new Map();
261
- for (const resolver of resolvers) {
262
- resolver.name && nameMap.set(resolver.name, resolver);
263
- }
264
- return Array.from(nameMap.values());
265
- }
266
-
267
288
  const globSuffixRE = /^((?:.*\.[^.]+)|(?:\*+))$/;
268
289
  function normalizeGlob(path) {
269
290
  if (/[\\/]$/.test(path)) {
@@ -396,6 +417,7 @@ function dtsPlugin(options = {}) {
396
417
  insertTypesEntry = false,
397
418
  rollupTypes = false,
398
419
  bundledPackages = [],
420
+ pathsToAliases = true,
399
421
  aliasesExclude = [],
400
422
  copyDtsFiles = false,
401
423
  strictOutput = true,
@@ -422,7 +444,12 @@ function dtsPlugin(options = {}) {
422
444
  let filter;
423
445
  let bundled = false;
424
446
  let timeRecord = 0;
425
- const resolvers = parseResolvers([VueResolver(), SvelteResolver(), ...options.resolvers || []]);
447
+ const resolvers = parseResolvers([
448
+ JsonResolver(),
449
+ VueResolver(),
450
+ SvelteResolver(),
451
+ ...options.resolvers || []
452
+ ]);
426
453
  const rootFiles = /* @__PURE__ */ new Set();
427
454
  const outputFiles = /* @__PURE__ */ new Map();
428
455
  return {
@@ -441,7 +468,7 @@ function dtsPlugin(options = {}) {
441
468
  if (aliasesExclude.length > 0) {
442
469
  aliases = aliases.filter(
443
470
  ({ find }) => !aliasesExclude.some(
444
- (alias) => alias && (isRegExp(find) ? find.toString() === alias.toString() : isRegExp(alias) ? find.match(alias)?.[0] : find === alias)
471
+ (aliasExclude) => aliasExclude && (isRegExp(find) ? find.toString() === aliasExclude.toString() : isRegExp(aliasExclude) ? find.match(aliasExclude)?.[0] : find === aliasExclude)
445
472
  )
446
473
  );
447
474
  }
@@ -520,12 +547,28 @@ ${kolorist.cyan(
520
547
  if (!outDirs) {
521
548
  outDirs = options.outDir ? ensureArray(options.outDir).map((d) => ensureAbsolute(d, root)) : [ensureAbsolute(content?.raw.compilerOptions?.outDir || "dist", root)];
522
549
  }
550
+ const { baseUrl, paths } = compilerOptions;
551
+ if (pathsToAliases && baseUrl && paths) {
552
+ const basePath = ensureAbsolute(baseUrl, configPath ? node_path.dirname(configPath) : root);
553
+ const existsFinds = new Set(
554
+ aliases.map((alias) => alias.find).filter((find) => typeof find === "string")
555
+ );
556
+ for (const [findWithAsterisk, replacements] of Object.entries(paths)) {
557
+ const find = findWithAsterisk.replace("/*", "");
558
+ if (!replacements.length || existsFinds.has(find))
559
+ continue;
560
+ aliases.push({
561
+ find,
562
+ replacement: ensureAbsolute(replacements[0].replace("/*", ""), basePath)
563
+ });
564
+ }
565
+ }
523
566
  include = ensureArray(options.include ?? content?.raw.include ?? "**/*").map(normalizeGlob);
524
567
  exclude = ensureArray(options.exclude ?? content?.raw.exclude ?? "node_modules/**").map(
525
568
  normalizeGlob
526
569
  );
527
570
  filter = pluginutils.createFilter(include, exclude, { resolve: root });
528
- const rootNames = Object.values(entries).concat(content?.fileNames.filter(filter) || []).map(normalizePath);
571
+ const rootNames = Object.values(entries).map((entry) => ensureAbsolute(entry, root)).concat(content?.fileNames.filter(filter) || []).map(normalizePath);
529
572
  host = ts__default.createCompilerHost(compilerOptions, true);
530
573
  program = vueTsc.createProgram({ host, rootNames, options: compilerOptions });
531
574
  libName = libName || "_default";
@@ -561,6 +604,7 @@ ${kolorist.cyan(
561
604
  return;
562
605
  }
563
606
  const startTime = Date.now();
607
+ const outDir = outDirs[0];
564
608
  const service = program.__vue.languageService;
565
609
  rootFiles.delete(id);
566
610
  if (resolver) {
@@ -568,18 +612,25 @@ ${kolorist.cyan(
568
612
  id,
569
613
  code,
570
614
  root: publicRoot,
615
+ outDir,
571
616
  host,
572
617
  program,
573
618
  service
574
619
  });
575
620
  for (const { path, content } of result) {
576
- outputFiles.set(ensureAbsolute(path, publicRoot), content);
621
+ outputFiles.set(
622
+ resolve(publicRoot, node_path.relative(outDir, ensureAbsolute(path, outDir))),
623
+ content
624
+ );
577
625
  }
578
626
  } else {
579
627
  const sourceFile = program.getSourceFile(id);
580
628
  if (sourceFile) {
581
629
  for (const outputFile of service.getEmitOutput(sourceFile.fileName, true).outputFiles) {
582
- outputFiles.set(resolve(publicRoot, outputFile.name), outputFile.text);
630
+ outputFiles.set(
631
+ resolve(publicRoot, node_path.relative(outDir, ensureAbsolute(outputFile.name, outDir))),
632
+ outputFile.text
633
+ );
583
634
  }
584
635
  }
585
636
  }
@@ -634,7 +685,10 @@ ${logPrefix} Start generate declaration files...`));
634
685
  }
635
686
  if (rootFiles.has(sourceFile.fileName)) {
636
687
  for (const outputFile of service.getEmitOutput(sourceFile.fileName, true).outputFiles) {
637
- outputFiles.set(resolve(publicRoot, outputFile.name), outputFile.text);
688
+ outputFiles.set(
689
+ resolve(publicRoot, node_path.relative(outDir, ensureAbsolute(outputFile.name, outDir))),
690
+ outputFile.text
691
+ );
638
692
  }
639
693
  rootFiles.delete(sourceFile.fileName);
640
694
  }
package/dist/index.d.ts CHANGED
@@ -16,11 +16,14 @@ interface Resolver {
16
16
  supports: (id: string) => void | boolean;
17
17
  /**
18
18
  * Transform source to declaration files
19
+ *
20
+ * Note that the path of the returns should base on `outDir`, or relative path to `root`
19
21
  */
20
22
  transform: (payload: {
21
23
  id: string;
22
24
  code: string;
23
25
  root: string;
26
+ outDir: string;
24
27
  host: ts.CompilerHost;
25
28
  program: ts.Program;
26
29
  service: ts.LanguageService;
@@ -80,6 +83,15 @@ interface PluginOptions {
80
83
  * @default []
81
84
  */
82
85
  resolvers?: Resolver[];
86
+ /**
87
+ * Parsing `paths` of tsconfig.json to aliases
88
+ *
89
+ * Note that these aliases only use for declaration files
90
+ *
91
+ * @default true
92
+ * @remarks Only use first replacement of each path
93
+ */
94
+ pathsToAliases?: boolean;
83
95
  /**
84
96
  * Set which paths should be excluded when transforming aliases
85
97
  *
package/dist/index.mjs CHANGED
@@ -5,7 +5,7 @@ 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 { resolve as resolve$1, posix, isAbsolute, dirname, normalize, sep, relative, basename } from 'node:path';
8
+ import { resolve as resolve$1, relative, posix, isAbsolute, dirname, normalize, sep, basename } from 'node:path';
9
9
  import { existsSync, readdirSync, lstatSync, rmdirSync } from 'node:fs';
10
10
  import { readFile, mkdir, writeFile, unlink } from 'node:fs/promises';
11
11
  import { cpus } from 'node:os';
@@ -114,6 +114,30 @@ function rollupDeclarationFiles({
114
114
  );
115
115
  }
116
116
 
117
+ const jsonRE = /\.json$/;
118
+ function JsonResolver() {
119
+ return {
120
+ name: "json",
121
+ supports(id) {
122
+ return jsonRE.test(id);
123
+ },
124
+ transform({ id, root, program }) {
125
+ const sourceFile = program.getSourceFile(id);
126
+ if (!sourceFile)
127
+ return [];
128
+ return [
129
+ {
130
+ path: relative(root, `${id}.d.ts`),
131
+ content: `declare const _default: ${sourceFile.text};
132
+
133
+ export default _default;
134
+ `
135
+ }
136
+ ];
137
+ }
138
+ };
139
+ }
140
+
117
141
  const svelteRE = /\.svelte$/;
118
142
  function SvelteResolver() {
119
143
  return {
@@ -121,17 +145,46 @@ function SvelteResolver() {
121
145
  supports(id) {
122
146
  return svelteRE.test(id);
123
147
  },
124
- transform({ id }) {
148
+ transform({ id, root }) {
125
149
  return [
126
150
  {
127
- path: `${id}.d.ts`,
128
- content: "export { SvelteComponentTyped as default } from 'svelte';"
151
+ path: relative(root, `${id}.d.ts`),
152
+ content: "export { SvelteComponentTyped as default } from 'svelte';\n"
129
153
  }
130
154
  ];
131
155
  }
132
156
  };
133
157
  }
134
158
 
159
+ const vueRE = /\.vue$/;
160
+ function VueResolver() {
161
+ return {
162
+ name: "vue",
163
+ supports(id) {
164
+ return vueRE.test(id);
165
+ },
166
+ transform({ id, program, service }) {
167
+ const sourceFile = program.getSourceFile(id) || program.getSourceFile(id + ".ts") || program.getSourceFile(id + ".js") || program.getSourceFile(id + ".tsx") || program.getSourceFile(id + ".jsx");
168
+ if (!sourceFile)
169
+ return [];
170
+ return service.getEmitOutput(sourceFile.fileName, true).outputFiles.map((file) => {
171
+ return {
172
+ path: file.name,
173
+ content: file.text
174
+ };
175
+ });
176
+ }
177
+ };
178
+ }
179
+
180
+ function parseResolvers(resolvers) {
181
+ const nameMap = /* @__PURE__ */ new Map();
182
+ for (const resolver of resolvers) {
183
+ resolver.name && nameMap.set(resolver.name, resolver);
184
+ }
185
+ return Array.from(nameMap.values());
186
+ }
187
+
135
188
  const windowsSlashRE = /\\+/g;
136
189
  function slash(p) {
137
190
  return p.replace(windowsSlashRE, "/");
@@ -232,38 +285,6 @@ function removeDirIfEmpty(dir) {
232
285
  return onlyHasDir;
233
286
  }
234
287
 
235
- const vueRE = /\.vue$/;
236
- function VueResolver() {
237
- return {
238
- name: "vue",
239
- supports(id) {
240
- return vueRE.test(id);
241
- },
242
- transform({ id, root, program, service }) {
243
- let sourceFile = program.getSourceFile(id);
244
- if (!sourceFile && vueRE.test(id)) {
245
- sourceFile = program.getSourceFile(id + ".ts") || program.getSourceFile(id + ".js") || program.getSourceFile(id + ".tsx") || program.getSourceFile(id + ".jsx");
246
- }
247
- if (!sourceFile)
248
- return [];
249
- return service.getEmitOutput(sourceFile.fileName, true).outputFiles.map((file) => {
250
- return {
251
- path: resolve(root, file.name),
252
- content: file.text
253
- };
254
- });
255
- }
256
- };
257
- }
258
-
259
- function parseResolvers(resolvers) {
260
- const nameMap = /* @__PURE__ */ new Map();
261
- for (const resolver of resolvers) {
262
- resolver.name && nameMap.set(resolver.name, resolver);
263
- }
264
- return Array.from(nameMap.values());
265
- }
266
-
267
288
  const globSuffixRE = /^((?:.*\.[^.]+)|(?:\*+))$/;
268
289
  function normalizeGlob(path) {
269
290
  if (/[\\/]$/.test(path)) {
@@ -396,6 +417,7 @@ function dtsPlugin(options = {}) {
396
417
  insertTypesEntry = false,
397
418
  rollupTypes = false,
398
419
  bundledPackages = [],
420
+ pathsToAliases = true,
399
421
  aliasesExclude = [],
400
422
  copyDtsFiles = false,
401
423
  strictOutput = true,
@@ -422,7 +444,12 @@ function dtsPlugin(options = {}) {
422
444
  let filter;
423
445
  let bundled = false;
424
446
  let timeRecord = 0;
425
- const resolvers = parseResolvers([VueResolver(), SvelteResolver(), ...options.resolvers || []]);
447
+ const resolvers = parseResolvers([
448
+ JsonResolver(),
449
+ VueResolver(),
450
+ SvelteResolver(),
451
+ ...options.resolvers || []
452
+ ]);
426
453
  const rootFiles = /* @__PURE__ */ new Set();
427
454
  const outputFiles = /* @__PURE__ */ new Map();
428
455
  return {
@@ -441,7 +468,7 @@ function dtsPlugin(options = {}) {
441
468
  if (aliasesExclude.length > 0) {
442
469
  aliases = aliases.filter(
443
470
  ({ find }) => !aliasesExclude.some(
444
- (alias) => alias && (isRegExp(find) ? find.toString() === alias.toString() : isRegExp(alias) ? find.match(alias)?.[0] : find === alias)
471
+ (aliasExclude) => aliasExclude && (isRegExp(find) ? find.toString() === aliasExclude.toString() : isRegExp(aliasExclude) ? find.match(aliasExclude)?.[0] : find === aliasExclude)
445
472
  )
446
473
  );
447
474
  }
@@ -520,12 +547,28 @@ ${cyan(
520
547
  if (!outDirs) {
521
548
  outDirs = options.outDir ? ensureArray(options.outDir).map((d) => ensureAbsolute(d, root)) : [ensureAbsolute(content?.raw.compilerOptions?.outDir || "dist", root)];
522
549
  }
550
+ const { baseUrl, paths } = compilerOptions;
551
+ if (pathsToAliases && baseUrl && paths) {
552
+ const basePath = ensureAbsolute(baseUrl, configPath ? dirname(configPath) : root);
553
+ const existsFinds = new Set(
554
+ aliases.map((alias) => alias.find).filter((find) => typeof find === "string")
555
+ );
556
+ for (const [findWithAsterisk, replacements] of Object.entries(paths)) {
557
+ const find = findWithAsterisk.replace("/*", "");
558
+ if (!replacements.length || existsFinds.has(find))
559
+ continue;
560
+ aliases.push({
561
+ find,
562
+ replacement: ensureAbsolute(replacements[0].replace("/*", ""), basePath)
563
+ });
564
+ }
565
+ }
523
566
  include = ensureArray(options.include ?? content?.raw.include ?? "**/*").map(normalizeGlob);
524
567
  exclude = ensureArray(options.exclude ?? content?.raw.exclude ?? "node_modules/**").map(
525
568
  normalizeGlob
526
569
  );
527
570
  filter = createFilter(include, exclude, { resolve: root });
528
- const rootNames = Object.values(entries).concat(content?.fileNames.filter(filter) || []).map(normalizePath);
571
+ const rootNames = Object.values(entries).map((entry) => ensureAbsolute(entry, root)).concat(content?.fileNames.filter(filter) || []).map(normalizePath);
529
572
  host = ts.createCompilerHost(compilerOptions, true);
530
573
  program = createProgram({ host, rootNames, options: compilerOptions });
531
574
  libName = libName || "_default";
@@ -561,6 +604,7 @@ ${cyan(
561
604
  return;
562
605
  }
563
606
  const startTime = Date.now();
607
+ const outDir = outDirs[0];
564
608
  const service = program.__vue.languageService;
565
609
  rootFiles.delete(id);
566
610
  if (resolver) {
@@ -568,18 +612,25 @@ ${cyan(
568
612
  id,
569
613
  code,
570
614
  root: publicRoot,
615
+ outDir,
571
616
  host,
572
617
  program,
573
618
  service
574
619
  });
575
620
  for (const { path, content } of result) {
576
- outputFiles.set(ensureAbsolute(path, publicRoot), content);
621
+ outputFiles.set(
622
+ resolve(publicRoot, relative(outDir, ensureAbsolute(path, outDir))),
623
+ content
624
+ );
577
625
  }
578
626
  } else {
579
627
  const sourceFile = program.getSourceFile(id);
580
628
  if (sourceFile) {
581
629
  for (const outputFile of service.getEmitOutput(sourceFile.fileName, true).outputFiles) {
582
- outputFiles.set(resolve(publicRoot, outputFile.name), outputFile.text);
630
+ outputFiles.set(
631
+ resolve(publicRoot, relative(outDir, ensureAbsolute(outputFile.name, outDir))),
632
+ outputFile.text
633
+ );
583
634
  }
584
635
  }
585
636
  }
@@ -634,7 +685,10 @@ ${logPrefix} Start generate declaration files...`));
634
685
  }
635
686
  if (rootFiles.has(sourceFile.fileName)) {
636
687
  for (const outputFile of service.getEmitOutput(sourceFile.fileName, true).outputFiles) {
637
- outputFiles.set(resolve(publicRoot, outputFile.name), outputFile.text);
688
+ outputFiles.set(
689
+ resolve(publicRoot, relative(outDir, ensureAbsolute(outputFile.name, outDir))),
690
+ outputFile.text
691
+ );
638
692
  }
639
693
  rootFiles.delete(sourceFile.fileName);
640
694
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vite-plugin-dts",
3
- "version": "3.1.1",
3
+ "version": "3.2.0",
4
4
  "type": "module",
5
5
  "license": "MIT",
6
6
  "author": "qmhc",