rolldown-plugin-dts 0.2.0 → 0.4.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
@@ -38,6 +38,13 @@ interface Options {
38
38
  */
39
39
  dtsInput?: boolean
40
40
 
41
+ /**
42
+ * When `true`, the plugin will only emit `.d.ts` files and remove all other chunks.
43
+ *
44
+ * This feature is particularly beneficial when you need to generate `d.ts` files for the CommonJS format as part of a separate build process.
45
+ */
46
+ emitDtsOnly?: boolean
47
+
41
48
  isolatedDeclaration?: Omit<IsolatedDeclarationsOptions, 'sourcemap'>
42
49
 
43
50
  /**
@@ -51,18 +58,12 @@ interface Options {
51
58
  */
52
59
  inputAlias?: Record<string, string>
53
60
 
54
- /**
55
- * Determines whether the module imported by `.d.ts` files should be treated as external or not.
56
- */
57
- external?: (
58
- id: string,
59
- importer: string,
60
- extraOptions: ResolveIdExtraOptions,
61
- ) => boolean | void
61
+ /** Resolve external types used in dts files from `node_modules` */
62
+ resolve?: boolean | (string | RegExp)[]
62
63
  }
63
64
  ````
64
65
 
65
- ## Caveats
66
+ ## ⚠️ Caveats
66
67
 
67
68
  - The plugin uses Oxc's `isolatedDeclarations` to generate `.d.ts` files,
68
69
  which means you need to set `isolatedDeclarations: true` in your `tsconfig.json` and ensure there are no errors.
package/dist/index.d.ts CHANGED
@@ -1,16 +1,15 @@
1
1
  import { IsolatedDeclarationsOptions } from "oxc-transform";
2
- import { FunctionPluginHooks, Plugin } from "rolldown";
2
+ import { Plugin } from "rolldown";
3
3
 
4
4
  //#region src/fake-js.d.ts
5
5
  declare function createFakeJsPlugin({ dtsInput }: Pick<Options, "dtsInput">): Plugin;
6
6
 
7
7
  //#endregion
8
8
  //#region src/generate.d.ts
9
- declare function createGeneratePlugin({ isolatedDeclaration, inputAlias, external }: Pick<Options, "external" | "isolatedDeclaration" | "inputAlias">): Plugin;
9
+ declare function createGeneratePlugin({ isolatedDeclaration, inputAlias, resolve, emitDtsOnly }: Pick<Options, "isolatedDeclaration" | "inputAlias" | "resolve" | "emitDtsOnly">): Plugin;
10
10
 
11
11
  //#endregion
12
12
  //#region src/index.d.ts
13
- type ResolveIdExtraOptions = Parameters<FunctionPluginHooks["resolveId"]>[2];
14
13
  interface Options {
15
14
  /**
16
15
  * When entries are `.d.ts` files (instead of `.ts` files), this option should be set to `true`.
@@ -18,6 +17,12 @@ interface Options {
18
17
  * If enabled, the plugin will skip generating a `.d.ts` file for the entry point.
19
18
  */
20
19
  dtsInput?: boolean;
20
+ /**
21
+ * When `true`, the plugin will only emit `.d.ts` files and remove all other chunks.
22
+ *
23
+ * This feature is particularly beneficial when you need to generate `d.ts` files for the CommonJS format as part of a separate build process.
24
+ */
25
+ emitDtsOnly?: boolean;
21
26
  isolatedDeclaration?: Omit<IsolatedDeclarationsOptions, "sourcemap">;
22
27
  /**
23
28
  * dts file name alias `{ [filename]: path }`
@@ -29,10 +34,8 @@ interface Options {
29
34
  * }
30
35
  */
31
36
  inputAlias?: Record<string, string>;
32
- /**
33
- * Determines whether the module imported by `.d.ts` files should be treated as external or not.
34
- */
35
- external?: (id: string, importer: string, extraOptions: ResolveIdExtraOptions) => boolean | void;
37
+ /** Resolve external types used in dts files from `node_modules` */
38
+ resolve?: boolean | (string | RegExp)[];
36
39
  }
37
40
  declare function dts(options?: Options): Plugin[];
38
41
 
package/dist/index.js CHANGED
@@ -1,6 +1,7 @@
1
1
  import { MagicStringAST } from "magic-string-ast";
2
2
  import { parseAsync } from "oxc-parser";
3
- import path, { basename } from "node:path";
3
+ import path, { basename, extname } from "node:path";
4
+ import { createResolver } from "dts-resolver";
4
5
  import { isolatedDeclaration } from "oxc-transform";
5
6
 
6
7
  //#region node_modules/.pnpm/estree-walker@3.0.3/node_modules/estree-walker/src/walker.js
@@ -234,6 +235,7 @@ function createFakeJsPlugin({ dtsInput }) {
234
235
  };
235
236
  } : void 0,
236
237
  outputOptions(options) {
238
+ if (options.format === "cjs" || options.format === "commonjs") throw new Error("[rolldown-plugin-dts] Cannot bundle dts files with `cjs` format.");
237
239
  return {
238
240
  ...options,
239
241
  entryFileNames: options.entryFileNames ?? (dtsInput ? "[name].ts" : void 0),
@@ -245,10 +247,7 @@ function createFakeJsPlugin({ dtsInput }) {
245
247
  };
246
248
  },
247
249
  transform: {
248
- filter: { id: {
249
- include: [RE_DTS],
250
- exclude: [RE_NODE_MODULES]
251
- } },
250
+ filter: { id: RE_DTS },
252
251
  async handler(code, id) {
253
252
  const { program, comments } = await parseAsync(id, code);
254
253
  const preserved = collectReferenceDirectives(comments);
@@ -436,10 +435,27 @@ function importNamespace(s, source, imported, getIdentifierIndex) {
436
435
 
437
436
  //#endregion
438
437
  //#region src/generate.ts
439
- function createGeneratePlugin({ isolatedDeclaration: isolatedDeclaration$1, inputAlias, external }) {
438
+ const meta = { dtsFile: true };
439
+ function createGeneratePlugin({ isolatedDeclaration: isolatedDeclaration$1, inputAlias, resolve = false, emitDtsOnly = false }) {
440
440
  const dtsMap = new Map();
441
+ const inputAliasMap = new Map(inputAlias && Object.entries(inputAlias));
442
+ const resolver = createResolver();
443
+ let inputOption;
441
444
  return {
442
445
  name: "rolldown-plugin-dts:generate",
446
+ options({ input }) {
447
+ if (isPlainObject(input)) inputOption = { ...input };
448
+ },
449
+ outputOptions(options) {
450
+ return {
451
+ ...options,
452
+ entryFileNames(chunk) {
453
+ const original = (typeof options.entryFileNames === "function" ? options.entryFileNames(chunk) : options.entryFileNames) || "[name].js";
454
+ if (chunk.name.endsWith(".d")) return original.replace(RE_JS, ".$1ts");
455
+ return original;
456
+ }
457
+ };
458
+ },
443
459
  transform: {
444
460
  order: "pre",
445
461
  filter: { id: {
@@ -450,42 +466,68 @@ function createGeneratePlugin({ isolatedDeclaration: isolatedDeclaration$1, inpu
450
466
  const { code: dtsCode, errors } = isolatedDeclaration(id, code, isolatedDeclaration$1);
451
467
  if (errors.length) return this.error(errors[0]);
452
468
  const dtsId = filename_ts_to_dts(id);
453
- dtsMap.set(dtsId, dtsCode);
469
+ dtsMap.set(dtsId, {
470
+ code: dtsCode,
471
+ src: id
472
+ });
454
473
  const mod = this.getModuleInfo(id);
455
474
  if (mod?.isEntry) {
456
- let fileName = basename(dtsId);
457
- if (inputAlias?.[fileName]) fileName = inputAlias[fileName];
475
+ let name = basename(dtsId, extname(dtsId));
476
+ if (inputAliasMap.has(name)) name = inputAliasMap.get(name);
477
+ else if (inputAliasMap.has(dtsId)) name = inputAliasMap.get(dtsId);
458
478
  this.emitFile({
459
479
  type: "chunk",
460
480
  id: dtsId,
461
- fileName
481
+ name
462
482
  });
483
+ if (emitDtsOnly) return "//";
463
484
  }
464
485
  }
465
486
  },
466
487
  async resolveId(id, importer, extraOptions) {
467
488
  if (dtsMap.has(id)) return {
468
489
  id,
469
- meta: { dtsFile: true }
490
+ meta
470
491
  };
471
- const importerMod = importer ? this.getModuleInfo(importer) : null;
472
- if (importerMod?.meta.dtsFile) {
473
- if (!isRelative(id) || external?.(id, importer, extraOptions) === true) return {
474
- id,
475
- external: true
476
- };
492
+ if (importer && this.getModuleInfo(importer)?.meta.dtsFile) {
493
+ if (!isRelative(id)) {
494
+ let shouldResolve;
495
+ if (typeof resolve === "boolean") shouldResolve = resolve;
496
+ else shouldResolve = resolve.some((pattern) => typeof pattern === "string" ? id === pattern : pattern.test(id));
497
+ if (shouldResolve) {
498
+ const resolution$1 = resolver(id, importer);
499
+ if (resolution$1) return {
500
+ id: resolution$1,
501
+ meta
502
+ };
503
+ } else return {
504
+ id,
505
+ external: true,
506
+ meta
507
+ };
508
+ }
477
509
  const resolution = await this.resolve(id, filename_dts_to(importer, "ts"));
478
510
  if (!resolution || resolution.external) return;
479
511
  const dtsId = filename_ts_to_dts(resolution.id);
480
512
  if (dtsMap.has(dtsId)) return {
481
513
  id: dtsId,
482
- meta: { dtsFile: true }
514
+ meta
483
515
  };
484
516
  await this.load(resolution);
485
517
  if (dtsMap.has(dtsId)) return {
486
518
  id: dtsId,
487
- meta: { dtsFile: true }
519
+ meta
488
520
  };
521
+ } else if (extraOptions.isEntry && inputOption) {
522
+ const resolution = await this.resolve(id, importer, extraOptions);
523
+ if (!resolution) return;
524
+ const dtsId = filename_ts_to_dts(resolution.id);
525
+ if (inputAliasMap.has(dtsId)) return resolution;
526
+ for (const [name, entry] of Object.entries(inputOption)) if (entry === id) {
527
+ inputAliasMap.set(dtsId, `${name}.d.ts`);
528
+ break;
529
+ }
530
+ return resolution;
489
531
  }
490
532
  },
491
533
  load: {
@@ -495,13 +537,21 @@ function createGeneratePlugin({ isolatedDeclaration: isolatedDeclaration$1, inpu
495
537
  } },
496
538
  handler(id) {
497
539
  if (dtsMap.has(id)) return {
498
- code: dtsMap.get(id),
540
+ code: dtsMap.get(id).code,
499
541
  moduleSideEffects: false
500
542
  };
501
543
  }
502
- }
544
+ },
545
+ generateBundle: emitDtsOnly ? (options, bundle) => {
546
+ for (const fileName of Object.keys(bundle)) if (!RE_DTS.test(fileName)) delete bundle[fileName];
547
+ } : void 0
503
548
  };
504
549
  }
550
+ function isPlainObject(data) {
551
+ if (typeof data !== "object" || data === null) return false;
552
+ const proto = Object.getPrototypeOf(data);
553
+ return proto === null || proto === Object.prototype;
554
+ }
505
555
 
506
556
  //#endregion
507
557
  //#region src/index.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rolldown-plugin-dts",
3
- "version": "0.2.0",
3
+ "version": "0.4.0",
4
4
  "description": "A Rolldown plugin to bundle dts files",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -27,7 +27,11 @@
27
27
  "publishConfig": {
28
28
  "access": "public"
29
29
  },
30
+ "peerDependencies": {
31
+ "rolldown": "^1.0.0-beta.7"
32
+ },
30
33
  "dependencies": {
34
+ "dts-resolver": "^0.1.0",
31
35
  "magic-string-ast": "^0.9.1",
32
36
  "oxc-parser": "^0.62.0",
33
37
  "oxc-transform": "^0.62.0"
@@ -43,7 +47,7 @@
43
47
  "eslint": "^9.24.0",
44
48
  "estree-walker": "^3.0.3",
45
49
  "prettier": "^3.5.3",
46
- "rolldown": "1.0.0-beta.7",
50
+ "rolldown": "^1.0.0-beta.7",
47
51
  "rollup-plugin-dts": "^6.2.1",
48
52
  "tsdown": "^0.8.0-beta.1",
49
53
  "tsx": "^4.19.3",