dtsroll 1.5.0 → 1.6.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 +108 -107
- package/dist/cli.mjs +26 -12
- package/dist/{index-DfxmCmBK.mjs → index-Du7Kzot4.mjs} +100 -40
- package/dist/index.d.ts +34 -1
- package/dist/index.mjs +1 -2
- package/dist/vite.d.ts +7 -0
- package/dist/vite.mjs +17 -10
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,152 +1,145 @@
|
|
|
1
1
|
<p align="center">
|
|
2
|
-
|
|
2
|
+
<img width="200" src="./.github/logo.webp">
|
|
3
3
|
</p>
|
|
4
|
+
<h2 align="center">dtsroll</h2>
|
|
4
5
|
|
|
5
|
-
|
|
6
|
-
dtsroll
|
|
7
|
-
</h2>
|
|
6
|
+
Are you publishing a TypeScript project where consumers encounter type-checking errors like:
|
|
8
7
|
|
|
9
|
-
|
|
8
|
+
```
|
|
9
|
+
Cannot find module 'some-package' or its corresponding type declarations.
|
|
10
|
+
```
|
|
10
11
|
|
|
11
|
-
|
|
12
|
+
When you compile with `tsc`, the emitted declaration files (`.d.ts` files) preserve imports exactly as written. So if your published types import from a `devDependency` or a private package (e.g. an internal monorepo package), those imports cannot be resolved by the consumer.
|
|
12
13
|
|
|
13
|
-
|
|
14
|
+
```ts
|
|
15
|
+
// dist/index.d.ts (generated by tsc)
|
|
16
|
+
import type { SomeType } from 'my-private-dependency' // ❌ consumers can't resolve this
|
|
14
17
|
|
|
15
|
-
|
|
18
|
+
export declare function myUtility(): SomeType
|
|
19
|
+
```
|
|
16
20
|
|
|
17
|
-
|
|
21
|
+
If you can't move the dependency to `dependencies`, or you just want its types pulled directly into your published declarations, _dtsroll_ is for you.
|
|
18
22
|
|
|
19
|
-
|
|
23
|
+
## What is dtsroll?
|
|
20
24
|
|
|
21
|
-
-
|
|
25
|
+
_dtsroll_ is a TypeScript declaration (`.d.ts`) file bundler. It's zero-config and reads your `package.json` to determine how your types should be bundled.
|
|
22
26
|
|
|
23
|
-
|
|
27
|
+
### What dtsroll does
|
|
24
28
|
|
|
25
|
-
|
|
26
|
-
<img width="600" src="./.github/screenshot.webp">
|
|
27
|
-
</p>
|
|
29
|
+
_dtsroll_ runs *after your build when `.d.ts` files have been emitted*, and works in-place to bundle them to their entry points.
|
|
28
30
|
|
|
31
|
+
Since packages declared in `devDependencies` are not installed for the consumer, _dtsroll_ assumes any imports referencing them should be bundled, as they would otherwise be unresolvable.
|
|
29
32
|
|
|
30
|
-
|
|
31
|
-
```
|
|
32
|
-
npm install --save-dev dtsroll
|
|
33
|
-
```
|
|
33
|
+
The result is a single, clean `.d.ts` output that works for consumers without extra installs.
|
|
34
34
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
2. Pass in the entry declaration file to _dtsroll_
|
|
42
|
-
|
|
43
|
-
```sh
|
|
44
|
-
dtsroll --dry-run dist/index.d.ts
|
|
45
|
-
```
|
|
35
|
+
```ts
|
|
36
|
+
// dist/index.d.ts (after dtsroll)
|
|
37
|
+
type SomeType = {
|
|
38
|
+
value: string
|
|
39
|
+
}
|
|
46
40
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
> - It will modify files you pass in, and files they import.
|
|
50
|
-
> - Only pass in backed up or generated files
|
|
51
|
-
> - Start with `--dry-run`
|
|
41
|
+
export declare function myUtility(): SomeType
|
|
42
|
+
```
|
|
52
43
|
|
|
53
|
-
|
|
44
|
+
### Features
|
|
54
45
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
46
|
+
- **Zero config** — Automatically finds entry points from `package.json`.
|
|
47
|
+
- **Fixes missing-type errors** — Inlines types from `devDependencies` so consumers don't need them installed.
|
|
48
|
+
- **Tree-shaken output** — Unused types are removed to keep files small.
|
|
49
|
+
- **In-place** — Designed to run directly on your `dist` folder after compilation.
|
|
58
50
|
|
|
59
|
-
|
|
51
|
+
<p align="center">
|
|
52
|
+
<img width="600" src="./.github/screenshot.webp">
|
|
53
|
+
</p>
|
|
60
54
|
|
|
61
|
-
|
|
55
|
+
## Install
|
|
62
56
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
{
|
|
66
|
-
"name": "my-package",
|
|
67
|
-
"exports": {
|
|
68
|
-
+ "types": "./dist/index.d.ts",
|
|
69
|
-
"default": "./dist/index.js"
|
|
70
|
-
},
|
|
71
|
-
"scripts": {
|
|
72
|
-
+ "build": "tsc && dtsroll"
|
|
73
|
-
}
|
|
74
|
-
}
|
|
57
|
+
```bash
|
|
58
|
+
npm install --save-dev dtsroll
|
|
75
59
|
```
|
|
76
60
|
|
|
77
|
-
|
|
61
|
+
## Quick start
|
|
78
62
|
|
|
79
|
-
|
|
63
|
+
### 1. Configure `package.json`
|
|
64
|
+
|
|
65
|
+
Point your `types` or `exports` to the final `.d.ts` file you want to publish.
|
|
66
|
+
|
|
67
|
+
```jsonc
|
|
68
|
+
{
|
|
69
|
+
"name": "my-package",
|
|
70
|
+
"exports": {
|
|
71
|
+
"types": "./dist/index.d.ts", // dtsroll targets this
|
|
72
|
+
"default": "./dist/index.js",
|
|
73
|
+
},
|
|
74
|
+
"scripts": {
|
|
75
|
+
"build": "tsc && dtsroll",
|
|
76
|
+
},
|
|
77
|
+
}
|
|
78
|
+
```
|
|
80
79
|
|
|
81
|
-
|
|
80
|
+
### 2. Build
|
|
82
81
|
|
|
83
|
-
|
|
82
|
+
```bash
|
|
83
|
+
npm run build
|
|
84
|
+
```
|
|
84
85
|
|
|
85
|
-
|
|
86
|
+
That's it.
|
|
86
87
|
|
|
87
|
-
|
|
88
|
-
-
|
|
88
|
+
> [!WARNING]
|
|
89
|
+
> _dtsroll_ modifies files in-place—bundled source files are removed and entry files are overwritten with bundled output.
|
|
90
|
+
> Use `--dry-run` first to see what it would change:
|
|
91
|
+
>
|
|
92
|
+
> ```bash
|
|
93
|
+
> dtsroll --dry-run
|
|
94
|
+
> ```
|
|
89
95
|
|
|
90
|
-
|
|
96
|
+
## Behavior
|
|
91
97
|
|
|
92
|
-
|
|
98
|
+
### Automatic configuration
|
|
93
99
|
|
|
94
|
-
|
|
100
|
+
By default, _dtsroll_ reads your `package.json` to determine which imports should be bundled and which should remain external. The recommended setup is to run _dtsroll_ without any configuration and let it infer the correct behavior based on your dependency declarations.
|
|
95
101
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
102
|
+
| Dependency type | Action | Reason |
|
|
103
|
+
| ---------------------- | ----------- | ----------------------------- |
|
|
104
|
+
| `devDependencies` | Bundle | Consumers don't install these |
|
|
105
|
+
| `dependencies` | Externalize | Consumers already have them |
|
|
106
|
+
| `optionalDependencies` | Externalize | Consumers already have them |
|
|
107
|
+
| `peerDependencies` | Externalize | Provided by the consumer |
|
|
100
108
|
|
|
101
|
-
|
|
109
|
+
If you have a `@types/*` package in `devDependencies` but the corresponding runtime package in `dependencies`, _dtsroll_ will recommend moving the types package to `dependencies`, as this can otherwise result in missing types for consumers.
|
|
102
110
|
|
|
103
|
-
###
|
|
104
|
-
Display usage instructions.
|
|
111
|
+
### Manual configuration
|
|
105
112
|
|
|
106
|
-
|
|
107
|
-
Simulate the bundling process without modifying the disk and logs what would happen.
|
|
113
|
+
If your project doesn't have a `package.json` file, you can still manually specify the input files (which entry files to collapse the `imports` into), and which packages to externalize.
|
|
108
114
|
|
|
109
|
-
###
|
|
110
|
-
If there is no `package.json` file, you can specify package names to exclude from the bundle.
|
|
115
|
+
### Subpath imports
|
|
111
116
|
|
|
112
|
-
> [!
|
|
113
|
-
>
|
|
117
|
+
> [!WARNING]
|
|
118
|
+
> Currently, _dtsroll_ mistakenly resolves and bundles [subpath imports](https://nodejs.org/api/packages.html#subpath-imports). Subpath imports are intended to be dynamic aliases controlled by the consumer. In a future breaking release, _dtsroll_ will likely externalize them to preserve this behavior.
|
|
114
119
|
|
|
115
|
-
|
|
116
|
-
Provide resolution conditions to target specific entry points in dependencies, similar to Node’s [`--conditions`](https://nodejs.org/api/cli.html#-c-condition---conditionscondition).
|
|
120
|
+
## Usage
|
|
117
121
|
|
|
118
|
-
|
|
119
|
-
```ts
|
|
120
|
-
import { dtsroll } from 'dtsroll'
|
|
122
|
+
_dtsroll_ can be used in several ways.
|
|
121
123
|
|
|
122
|
-
|
|
124
|
+
### CLI usage
|
|
123
125
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
*/
|
|
128
|
-
cwd?: string
|
|
129
|
-
|
|
130
|
-
/**
|
|
131
|
-
* Defaults to auto-detecting d.ts files from package.json
|
|
132
|
-
*/
|
|
133
|
-
inputs?: string[]
|
|
126
|
+
```bash
|
|
127
|
+
dtsroll [flags] [...entry .d.ts files]
|
|
128
|
+
```
|
|
134
129
|
|
|
135
|
-
|
|
136
|
-
* Only used if there's no package.json
|
|
137
|
-
* Defaults to auto-detecting dependencies from package.json
|
|
138
|
-
*/
|
|
139
|
-
external?: string[]
|
|
130
|
+
If no entry files are provided, _dtsroll_ reads `package.json` to determine them.
|
|
140
131
|
|
|
141
|
-
|
|
132
|
+
#### Flags
|
|
142
133
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
134
|
+
| Flag | Alias | Description |
|
|
135
|
+
| -------------- | ----- | ------------------------------------------------- |
|
|
136
|
+
| `--dry-run` | `-d` | Show what would be bundled without writing files |
|
|
137
|
+
| `--conditions` | `-C` | Resolution conditions for [subpath exports](https://nodejs.org/api/packages.html#subpath-exports) (e.g. `production`) |
|
|
138
|
+
| `--external` | `-e` | *(Only when no `package.json`)* Packages to externalize |
|
|
146
139
|
|
|
147
|
-
|
|
140
|
+
### Vite plugin
|
|
148
141
|
|
|
149
|
-
|
|
142
|
+
If you use `vite-plugin-dts`, _dtsroll_ will automatically bundle the emitted types immediately after generation:
|
|
150
143
|
|
|
151
144
|
```ts
|
|
152
145
|
import { defineConfig } from 'vitest/config'
|
|
@@ -154,16 +147,24 @@ import dts from 'vite-plugin-dts'
|
|
|
154
147
|
import { dtsroll } from 'dtsroll/vite'
|
|
155
148
|
|
|
156
149
|
export default defineConfig({
|
|
157
|
-
// ...
|
|
158
150
|
plugins: [
|
|
159
|
-
// ...
|
|
160
151
|
dts(),
|
|
161
152
|
dtsroll()
|
|
162
153
|
]
|
|
163
154
|
})
|
|
164
155
|
```
|
|
165
156
|
|
|
157
|
+
### Node API
|
|
158
|
+
|
|
159
|
+
```ts
|
|
160
|
+
import { dtsroll } from 'dtsroll'
|
|
161
|
+
|
|
162
|
+
await dtsroll({
|
|
163
|
+
cwd: process.cwd(),
|
|
164
|
+
dryRun: false
|
|
165
|
+
})
|
|
166
|
+
```
|
|
167
|
+
|
|
166
168
|
## Related
|
|
167
169
|
|
|
168
|
-
|
|
169
|
-
For package bundling (along with dts bundling), check out [pkgroll](https://github.com/privatenumber/pkgroll).
|
|
170
|
+
- [pkgroll](https://github.com/privatenumber/pkgroll) — Zero-config JS + DTS bundler
|
package/dist/cli.mjs
CHANGED
|
@@ -1,18 +1,17 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { cli } from 'cleye';
|
|
3
|
-
import { b as bgYellow, a as black, d as dtsroll, l as logOutput } from './index-
|
|
3
|
+
import { b as bgYellow, a as black, d as dtsroll, l as logOutput, D as DtsrollBuildError } from './index-Du7Kzot4.mjs';
|
|
4
4
|
import 'node:path';
|
|
5
5
|
import 'node:fs/promises';
|
|
6
6
|
import 'rollup';
|
|
7
7
|
import 'rollup-plugin-dts';
|
|
8
8
|
import '@rollup/plugin-node-resolve';
|
|
9
|
-
import 'node:fs';
|
|
10
9
|
import 'empathic/find';
|
|
11
10
|
import 'resolve-pkg-maps';
|
|
12
11
|
import 'byte-size';
|
|
13
12
|
|
|
14
13
|
var name = "dtsroll";
|
|
15
|
-
var version = "1.
|
|
14
|
+
var version = "1.6.0";
|
|
16
15
|
var description = "Bundle dts files";
|
|
17
16
|
|
|
18
17
|
const argv = cli({
|
|
@@ -21,6 +20,7 @@ const argv = cli({
|
|
|
21
20
|
help: {
|
|
22
21
|
description
|
|
23
22
|
},
|
|
23
|
+
strictFlags: true,
|
|
24
24
|
parameters: ["[input files...]"],
|
|
25
25
|
flags: {
|
|
26
26
|
conditions: {
|
|
@@ -37,32 +37,46 @@ const argv = cli({
|
|
|
37
37
|
type: [String],
|
|
38
38
|
alias: "e",
|
|
39
39
|
description: "Dependency to externalize"
|
|
40
|
+
},
|
|
41
|
+
sourcemap: {
|
|
42
|
+
type: Boolean,
|
|
43
|
+
alias: "s",
|
|
44
|
+
description: "Generate sourcemaps"
|
|
40
45
|
}
|
|
41
|
-
// sourcemap: {
|
|
42
|
-
// type: Boolean,
|
|
43
|
-
// description: 'Generate sourcemaps',
|
|
44
|
-
// },
|
|
45
46
|
}
|
|
46
47
|
});
|
|
47
48
|
const { flags } = argv;
|
|
48
|
-
|
|
49
|
-
if (dryMode) {
|
|
49
|
+
if (flags.dryRun) {
|
|
50
50
|
console.log(bgYellow(black(" Dry run - No files will be written ")));
|
|
51
51
|
}
|
|
52
52
|
dtsroll({
|
|
53
53
|
inputs: argv._.inputFiles,
|
|
54
54
|
external: flags.external,
|
|
55
55
|
conditions: flags.conditions,
|
|
56
|
-
dryRun: flags.dryRun
|
|
56
|
+
dryRun: flags.dryRun,
|
|
57
|
+
sourcemap: flags.sourcemap
|
|
57
58
|
}).then(
|
|
58
59
|
(output) => {
|
|
59
60
|
if ("error" in output) {
|
|
60
61
|
process.exitCode = 1;
|
|
61
62
|
}
|
|
62
63
|
logOutput(output);
|
|
63
|
-
}
|
|
64
|
+
}
|
|
65
|
+
).catch(
|
|
64
66
|
(error) => {
|
|
65
|
-
|
|
67
|
+
let errorMessage = "\nFailed to build";
|
|
68
|
+
if (error instanceof DtsrollBuildError) {
|
|
69
|
+
errorMessage += `
|
|
70
|
+
File: ${error.id}`;
|
|
71
|
+
if (error.importChain.length > 1) {
|
|
72
|
+
errorMessage += "\n\n Import chain:\n ";
|
|
73
|
+
errorMessage += error.importChain.join("\n \u2192 ");
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
errorMessage += `
|
|
77
|
+
|
|
78
|
+
${error instanceof Error ? error.message : String(error)}`;
|
|
79
|
+
console.error(errorMessage);
|
|
66
80
|
process.exitCode = 1;
|
|
67
81
|
}
|
|
68
82
|
);
|
|
@@ -3,7 +3,6 @@ import fs from 'node:fs/promises';
|
|
|
3
3
|
import { rollup } from 'rollup';
|
|
4
4
|
import { dts } from 'rollup-plugin-dts';
|
|
5
5
|
import nodeResolve from '@rollup/plugin-node-resolve';
|
|
6
|
-
import fs$1 from 'node:fs';
|
|
7
6
|
import { up } from 'empathic/find';
|
|
8
7
|
import { resolveImports } from 'resolve-pkg-maps';
|
|
9
8
|
import byteSize from 'byte-size';
|
|
@@ -72,7 +71,13 @@ const bgYellow = kolorist(43, 49);
|
|
|
72
71
|
const cwd = process.cwd();
|
|
73
72
|
|
|
74
73
|
const isPath = (filePath) => filePath[0] === "." || path.isAbsolute(filePath);
|
|
75
|
-
const normalizePath = (filepath) => filepath.replaceAll("\\", "/");
|
|
74
|
+
const normalizePath$1 = (filepath) => filepath.replaceAll("\\", "/");
|
|
75
|
+
const getDisplayPath = (fullPath) => {
|
|
76
|
+
const relativePath = path.relative(cwd, fullPath);
|
|
77
|
+
return normalizePath$1(
|
|
78
|
+
relativePath.length < fullPath.length ? relativePath : fullPath
|
|
79
|
+
);
|
|
80
|
+
};
|
|
76
81
|
|
|
77
82
|
const warningSignUnicode = "\u26A0";
|
|
78
83
|
const warningPrefix = yellow("Warning:");
|
|
@@ -84,10 +89,7 @@ const logOutput = (dtsOutput) => {
|
|
|
84
89
|
\u{1F4E5} Entry points${isCliInput ? "" : " in package.json"}`));
|
|
85
90
|
console.log(
|
|
86
91
|
inputs.map(([inputFile, inputSource, error]) => {
|
|
87
|
-
const
|
|
88
|
-
const logPath2 = normalizePath(
|
|
89
|
-
relativeInputFile.length < inputFile.length ? relativeInputFile : inputFile
|
|
90
|
-
);
|
|
92
|
+
const logPath2 = getDisplayPath(inputFile);
|
|
91
93
|
if (error) {
|
|
92
94
|
return ` ${lightYellow(`${warningSignUnicode} ${logPath2} ${dim(error)}`)}`;
|
|
93
95
|
}
|
|
@@ -107,10 +109,7 @@ const logOutput = (dtsOutput) => {
|
|
|
107
109
|
size,
|
|
108
110
|
externals
|
|
109
111
|
} = dtsOutput;
|
|
110
|
-
const
|
|
111
|
-
const logPath = `${normalizePath(
|
|
112
|
-
outputDirectoryRelative.length < outputDirectory.length ? outputDirectoryRelative : outputDirectory
|
|
113
|
-
)}/`;
|
|
112
|
+
const logPath = `${getDisplayPath(outputDirectory)}/`;
|
|
114
113
|
const logChunk = ({
|
|
115
114
|
file,
|
|
116
115
|
indent,
|
|
@@ -124,10 +123,7 @@ const logOutput = (dtsOutput) => {
|
|
|
124
123
|
${moduleIds.sort().map((moduleId, index) => {
|
|
125
124
|
const isLast = index === moduleIds.length - 1;
|
|
126
125
|
const prefix = `${indent} ${isLast ? "\u2514\u2500 " : "\u251C\u2500 "}`;
|
|
127
|
-
const
|
|
128
|
-
const logModuleId = normalizePath(
|
|
129
|
-
relativeModuleId.length < moduleId.length ? relativeModuleId : moduleId
|
|
130
|
-
);
|
|
126
|
+
const logModuleId = getDisplayPath(moduleId);
|
|
131
127
|
const bareSpecifier = moduleToPackage[moduleId];
|
|
132
128
|
if (bareSpecifier) {
|
|
133
129
|
return `${prefix}${dim(`${magenta(bareSpecifier)} (${logModuleId})`)}`;
|
|
@@ -177,6 +173,17 @@ ${moduleIds.sort().map((moduleId, index) => {
|
|
|
177
173
|
}
|
|
178
174
|
};
|
|
179
175
|
|
|
176
|
+
class DtsrollBuildError extends Error {
|
|
177
|
+
id;
|
|
178
|
+
importChain;
|
|
179
|
+
constructor(message, id, importChain) {
|
|
180
|
+
super(message);
|
|
181
|
+
this.name = "DtsrollBuildError";
|
|
182
|
+
this.id = id;
|
|
183
|
+
this.importChain = importChain;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
180
187
|
const dtsExtensions = [".d.ts", ".d.cts", ".d.mts"];
|
|
181
188
|
const isDts = (fileName) => dtsExtensions.some((extension) => fileName.endsWith(extension));
|
|
182
189
|
|
|
@@ -269,6 +276,7 @@ const getPackageName = (id) => {
|
|
|
269
276
|
return id.slice(0, indexOfSlash);
|
|
270
277
|
};
|
|
271
278
|
|
|
279
|
+
const normalizePath = (filePath) => filePath.replaceAll("\\", "/");
|
|
272
280
|
const getAllFiles = async (directoryPath, dontShortenPath) => {
|
|
273
281
|
const directoryFiles = await fs.readdir(directoryPath, { withFileTypes: true });
|
|
274
282
|
const fileTree = await Promise.all(
|
|
@@ -276,9 +284,9 @@ const getAllFiles = async (directoryPath, dontShortenPath) => {
|
|
|
276
284
|
const filePath = path.join(directoryPath, entry.name);
|
|
277
285
|
if (entry.isDirectory()) {
|
|
278
286
|
const files = await getAllFiles(filePath, true);
|
|
279
|
-
return dontShortenPath ? files : files.map((file) => `./${path.relative(directoryPath, file)}`);
|
|
287
|
+
return dontShortenPath ? files : files.map((file) => `./${normalizePath(path.relative(directoryPath, file))}`);
|
|
280
288
|
}
|
|
281
|
-
return dontShortenPath ? filePath : `./${path.relative(directoryPath, filePath)}`;
|
|
289
|
+
return dontShortenPath ? filePath : `./${normalizePath(path.relative(directoryPath, filePath))}`;
|
|
282
290
|
})
|
|
283
291
|
);
|
|
284
292
|
return fileTree.flat();
|
|
@@ -473,6 +481,39 @@ const createExternalizePlugin = (configuredExternals) => {
|
|
|
473
481
|
};
|
|
474
482
|
};
|
|
475
483
|
|
|
484
|
+
const createImportChainPlugin = () => {
|
|
485
|
+
const importerMap = /* @__PURE__ */ new Map();
|
|
486
|
+
const plugin = {
|
|
487
|
+
name: "import-chain-tracker",
|
|
488
|
+
buildStart: () => {
|
|
489
|
+
importerMap.clear();
|
|
490
|
+
},
|
|
491
|
+
async resolveId(source, importer) {
|
|
492
|
+
if (!importer) {
|
|
493
|
+
return null;
|
|
494
|
+
}
|
|
495
|
+
const resolved = await this.resolve(source, importer, { skipSelf: true });
|
|
496
|
+
if (resolved && !resolved.external && !importerMap.has(resolved.id)) {
|
|
497
|
+
importerMap.set(resolved.id, importer);
|
|
498
|
+
}
|
|
499
|
+
return null;
|
|
500
|
+
}
|
|
501
|
+
};
|
|
502
|
+
const getImportChain = (errorFileId) => {
|
|
503
|
+
const chain = [];
|
|
504
|
+
let current = errorFileId;
|
|
505
|
+
while (current) {
|
|
506
|
+
chain.unshift(current);
|
|
507
|
+
current = importerMap.get(current);
|
|
508
|
+
}
|
|
509
|
+
return chain;
|
|
510
|
+
};
|
|
511
|
+
return {
|
|
512
|
+
plugin,
|
|
513
|
+
getImportChain
|
|
514
|
+
};
|
|
515
|
+
};
|
|
516
|
+
|
|
476
517
|
const nodeModules = `${path.sep}node_modules${path.sep}`;
|
|
477
518
|
const removeBundledModulesPlugin = (outputDirectory, sizeRef) => {
|
|
478
519
|
let deleteFiles = [];
|
|
@@ -490,14 +531,17 @@ const removeBundledModulesPlugin = (outputDirectory, sizeRef) => {
|
|
|
490
531
|
async generateBundle(options, bundle) {
|
|
491
532
|
const modules = Object.values(bundle);
|
|
492
533
|
const bundledFiles = Array.from(new Set(modules.flatMap(({ moduleIds }) => moduleIds)));
|
|
493
|
-
|
|
494
|
-
|
|
534
|
+
let totalSize = 0;
|
|
535
|
+
for (const moduleId of bundledFiles) {
|
|
536
|
+
const moduleInfo = this.getModuleInfo(moduleId);
|
|
537
|
+
const size = moduleInfo?.meta?.size;
|
|
538
|
+
if (typeof size === "number") {
|
|
539
|
+
totalSize += size;
|
|
540
|
+
}
|
|
541
|
+
}
|
|
495
542
|
sizeRef.value = totalSize;
|
|
496
543
|
const outputFiles = new Set(modules.map(({ fileName }) => path.join(options.dir, fileName)));
|
|
497
|
-
deleteFiles = bundledFiles.filter((moduleId) => (
|
|
498
|
-
// To avoid deleting files from symlinked dependencies
|
|
499
|
-
moduleId.startsWith(outputDirectory) && !moduleId.includes(nodeModules) && !outputFiles.has(moduleId)
|
|
500
|
-
));
|
|
544
|
+
deleteFiles = bundledFiles.filter((moduleId) => moduleId && moduleId.startsWith(outputDirectory) && !moduleId.includes(nodeModules) && !outputFiles.has(moduleId));
|
|
501
545
|
},
|
|
502
546
|
writeBundle: async () => {
|
|
503
547
|
await Promise.all(
|
|
@@ -508,7 +552,7 @@ const removeBundledModulesPlugin = (outputDirectory, sizeRef) => {
|
|
|
508
552
|
};
|
|
509
553
|
|
|
510
554
|
const packageJsonCache = /* @__PURE__ */ new Map();
|
|
511
|
-
const findPackageJsonUp = (cwd) => {
|
|
555
|
+
const findPackageJsonUp = async (cwd) => {
|
|
512
556
|
const packageJsonPath = up("package.json", { cwd });
|
|
513
557
|
if (!packageJsonPath) {
|
|
514
558
|
return void 0;
|
|
@@ -517,7 +561,7 @@ const findPackageJsonUp = (cwd) => {
|
|
|
517
561
|
let packageJson = packageJsonCache.get(packageRoot);
|
|
518
562
|
if (!packageJson) {
|
|
519
563
|
try {
|
|
520
|
-
const content = fs
|
|
564
|
+
const content = await fs.readFile(packageJsonPath, "utf8");
|
|
521
565
|
packageJson = JSON.parse(content);
|
|
522
566
|
packageJsonCache.set(packageRoot, packageJson);
|
|
523
567
|
} catch {
|
|
@@ -537,7 +581,7 @@ const resolveSubpathImportsPlugin = () => ({
|
|
|
537
581
|
if (id[0] !== "#" || !importer) {
|
|
538
582
|
return null;
|
|
539
583
|
}
|
|
540
|
-
const result = findPackageJsonUp(path.dirname(importer));
|
|
584
|
+
const result = await findPackageJsonUp(path.dirname(importer));
|
|
541
585
|
if (!result) {
|
|
542
586
|
return null;
|
|
543
587
|
}
|
|
@@ -565,22 +609,24 @@ const createInputMap = (input, outputDirectory) => Object.fromEntries(
|
|
|
565
609
|
inputFile
|
|
566
610
|
])
|
|
567
611
|
);
|
|
568
|
-
const build = async (input, outputDirectory, externals, mode, conditions) => {
|
|
612
|
+
const build = async (input, outputDirectory, externals, mode, conditions, sourcemap) => {
|
|
569
613
|
const {
|
|
570
614
|
externalizePlugin,
|
|
571
615
|
externalized,
|
|
572
616
|
getPackageEntryPoint
|
|
573
617
|
} = createExternalizePlugin(externals);
|
|
618
|
+
const { plugin: importChainPlugin, getImportChain } = createImportChainPlugin();
|
|
574
619
|
const sizeRef = {};
|
|
575
620
|
const rollupConfig = {
|
|
576
621
|
input: createInputMap(input, outputDirectory),
|
|
577
622
|
output: {
|
|
578
|
-
|
|
623
|
+
sourcemap,
|
|
579
624
|
dir: outputDirectory,
|
|
580
625
|
entryFileNames: "[name]",
|
|
581
626
|
chunkFileNames: "_dtsroll-chunks/[hash]-[name].ts"
|
|
582
627
|
},
|
|
583
628
|
plugins: [
|
|
629
|
+
importChainPlugin,
|
|
584
630
|
externalizePlugin,
|
|
585
631
|
removeBundledModulesPlugin(outputDirectory, sizeRef),
|
|
586
632
|
resolveSubpathImportsPlugin(),
|
|
@@ -600,15 +646,26 @@ const build = async (input, outputDirectory, externals, mode, conditions) => {
|
|
|
600
646
|
})
|
|
601
647
|
]
|
|
602
648
|
};
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
649
|
+
try {
|
|
650
|
+
const rollupBuild = await rollup(rollupConfig);
|
|
651
|
+
const built = await rollupBuild[mode](rollupConfig.output);
|
|
652
|
+
await rollupBuild.close();
|
|
653
|
+
return {
|
|
654
|
+
built,
|
|
655
|
+
externalized,
|
|
656
|
+
getPackageEntryPoint,
|
|
657
|
+
sourceSize: sizeRef.value ?? 0
|
|
658
|
+
};
|
|
659
|
+
} catch (error) {
|
|
660
|
+
if (error instanceof Error && "id" in error && typeof error.id === "string") {
|
|
661
|
+
throw new DtsrollBuildError(
|
|
662
|
+
error.message,
|
|
663
|
+
error.id,
|
|
664
|
+
getImportChain(error.id)
|
|
665
|
+
);
|
|
666
|
+
}
|
|
667
|
+
throw error;
|
|
668
|
+
}
|
|
612
669
|
};
|
|
613
670
|
|
|
614
671
|
const dtsroll = async ({
|
|
@@ -616,7 +673,8 @@ const dtsroll = async ({
|
|
|
616
673
|
inputs,
|
|
617
674
|
external,
|
|
618
675
|
conditions,
|
|
619
|
-
dryRun
|
|
676
|
+
dryRun,
|
|
677
|
+
sourcemap
|
|
620
678
|
} = {}) => {
|
|
621
679
|
const pkgJson = await getPackageJson(cwd);
|
|
622
680
|
const externals = pkgJson ? pkgJson.getExternals() : /* @__PURE__ */ new Map();
|
|
@@ -651,13 +709,15 @@ const dtsroll = async ({
|
|
|
651
709
|
outputDirectory,
|
|
652
710
|
externals,
|
|
653
711
|
dryRun ? "generate" : "write",
|
|
654
|
-
conditions
|
|
712
|
+
conditions,
|
|
713
|
+
sourcemap
|
|
655
714
|
);
|
|
656
715
|
let outputSize = 0;
|
|
657
716
|
const outputEntries = [];
|
|
658
717
|
const outputChunks = [];
|
|
659
718
|
const moduleImports = /* @__PURE__ */ new Set();
|
|
660
|
-
|
|
719
|
+
const chunks = built.output.filter((file) => file.type === "chunk");
|
|
720
|
+
for (const file of chunks) {
|
|
661
721
|
const size = Buffer.byteLength(file.code);
|
|
662
722
|
outputSize += size;
|
|
663
723
|
const moduleToPackage = Object.fromEntries(
|
|
@@ -702,4 +762,4 @@ const dtsroll = async ({
|
|
|
702
762
|
};
|
|
703
763
|
};
|
|
704
764
|
|
|
705
|
-
export { black as a, bgYellow as b, dtsroll as d, logOutput as l };
|
|
765
|
+
export { DtsrollBuildError as D, black as a, bgYellow as b, dtsroll as d, logOutput as l };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,19 +1,36 @@
|
|
|
1
1
|
import { OutputChunk } from 'rollup';
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* Extended output chunk with additional metadata.
|
|
5
|
+
*/
|
|
3
6
|
type Output = OutputChunk & {
|
|
7
|
+
/** Size of the output file in bytes. */
|
|
4
8
|
size: number;
|
|
9
|
+
/** Map of module IDs to their package names. */
|
|
5
10
|
moduleToPackage: Record<string, string | undefined>;
|
|
6
11
|
};
|
|
12
|
+
/**
|
|
13
|
+
* List of externalized packages with metadata.
|
|
14
|
+
* Each entry is [packageName, reason, warning?].
|
|
15
|
+
*/
|
|
7
16
|
type Externals = [
|
|
8
17
|
packageName: string,
|
|
9
18
|
reason?: string,
|
|
10
19
|
warning?: string
|
|
11
20
|
][];
|
|
21
|
+
/**
|
|
22
|
+
* Validated input file with source info and optional error.
|
|
23
|
+
* Tuple format: [inputPath, inputSource, error?].
|
|
24
|
+
*/
|
|
12
25
|
type ValidatedInput = [
|
|
13
26
|
inputPath: string,
|
|
14
27
|
inputSource: string | undefined,
|
|
15
28
|
error?: string
|
|
16
29
|
];
|
|
30
|
+
/**
|
|
31
|
+
* Output from the dtsroll build process.
|
|
32
|
+
* Returns either an error state or successful build results.
|
|
33
|
+
*/
|
|
17
34
|
type DtsrollOutput = {
|
|
18
35
|
inputs: ValidatedInput[];
|
|
19
36
|
error: string;
|
|
@@ -31,14 +48,30 @@ type DtsrollOutput = {
|
|
|
31
48
|
externals: Externals;
|
|
32
49
|
};
|
|
33
50
|
|
|
51
|
+
/**
|
|
52
|
+
* Configuration options for dtsroll.
|
|
53
|
+
*/
|
|
34
54
|
type Options = {
|
|
55
|
+
/** Working directory. Defaults to process.cwd(). */
|
|
35
56
|
cwd?: string;
|
|
57
|
+
/** Input .d.ts files to bundle. If not provided, auto-detects from package.json. */
|
|
36
58
|
inputs?: string[];
|
|
59
|
+
/** Packages to externalize (only used when no package.json is present). */
|
|
37
60
|
external?: string[];
|
|
61
|
+
/** Export conditions for module resolution. */
|
|
38
62
|
conditions?: string[];
|
|
63
|
+
/** If true, generates output without writing files. */
|
|
39
64
|
dryRun?: boolean;
|
|
65
|
+
/** If true, generates source maps (.d.ts.map files). */
|
|
66
|
+
sourcemap?: boolean;
|
|
40
67
|
};
|
|
41
|
-
|
|
68
|
+
/**
|
|
69
|
+
* Bundle TypeScript declaration files using Rollup.
|
|
70
|
+
*
|
|
71
|
+
* @param options - Configuration options
|
|
72
|
+
* @returns Build output including bundled files, sizes, and externalized packages
|
|
73
|
+
*/
|
|
74
|
+
declare const dtsroll: ({ cwd, inputs, external, conditions, dryRun, sourcemap, }?: Options) => Promise<DtsrollOutput>;
|
|
42
75
|
|
|
43
76
|
export { dtsroll };
|
|
44
77
|
export type { DtsrollOutput, Options };
|
package/dist/index.mjs
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import 'node:path';
|
|
3
|
-
export { d as dtsroll } from './index-
|
|
3
|
+
export { d as dtsroll } from './index-Du7Kzot4.mjs';
|
|
4
4
|
import 'node:fs/promises';
|
|
5
5
|
import 'rollup';
|
|
6
6
|
import 'rollup-plugin-dts';
|
|
7
7
|
import '@rollup/plugin-node-resolve';
|
|
8
|
-
import 'node:fs';
|
|
9
8
|
import 'empathic/find';
|
|
10
9
|
import 'resolve-pkg-maps';
|
|
11
10
|
import 'byte-size';
|
package/dist/vite.d.ts
CHANGED
|
@@ -2,6 +2,13 @@ import { Plugin } from 'vite';
|
|
|
2
2
|
import { Options } from './index.js';
|
|
3
3
|
import 'rollup';
|
|
4
4
|
|
|
5
|
+
/**
|
|
6
|
+
* Vite plugin for bundling TypeScript declaration files.
|
|
7
|
+
* Runs after vite-plugin-dts in the writeBundle hook.
|
|
8
|
+
*
|
|
9
|
+
* @param options - Configuration options (same as dtsroll function)
|
|
10
|
+
* @returns Vite plugin instance
|
|
11
|
+
*/
|
|
5
12
|
declare const dtsrollPlugin: (options?: Options) => Plugin;
|
|
6
13
|
|
|
7
14
|
export { dtsrollPlugin as dtsroll };
|
package/dist/vite.mjs
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { d as dtsroll, l as logOutput } from './index-
|
|
2
|
+
import { d as dtsroll, l as logOutput } from './index-Du7Kzot4.mjs';
|
|
3
3
|
import 'node:path';
|
|
4
4
|
import 'node:fs/promises';
|
|
5
5
|
import 'rollup';
|
|
6
6
|
import 'rollup-plugin-dts';
|
|
7
7
|
import '@rollup/plugin-node-resolve';
|
|
8
|
-
import 'node:fs';
|
|
9
8
|
import 'empathic/find';
|
|
10
9
|
import 'resolve-pkg-maps';
|
|
11
10
|
import 'byte-size';
|
|
@@ -29,14 +28,22 @@ const dtsrollPlugin = (options) => {
|
|
|
29
28
|
if (built) {
|
|
30
29
|
return;
|
|
31
30
|
}
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
31
|
+
try {
|
|
32
|
+
const output = await dtsroll({
|
|
33
|
+
cwd,
|
|
34
|
+
...options
|
|
35
|
+
});
|
|
36
|
+
built = true;
|
|
37
|
+
if (!noLog) {
|
|
38
|
+
logOutput(output);
|
|
39
|
+
console.log();
|
|
40
|
+
}
|
|
41
|
+
} catch (error) {
|
|
42
|
+
built = true;
|
|
43
|
+
throw new Error(
|
|
44
|
+
`dtsroll failed: ${error instanceof Error ? error.message : String(error)}`,
|
|
45
|
+
{ cause: error }
|
|
46
|
+
);
|
|
40
47
|
}
|
|
41
48
|
}
|
|
42
49
|
}
|