pkgprn 0.3.1 → 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 +51 -9
- package/index.d.ts +1 -0
- package/index.d.ts.map +1 -1
- package/index.js +15 -0
- package/package.json +4 -3
- package/prune.js +52 -1
package/README.md
CHANGED
|
@@ -58,18 +58,20 @@ Additional optional features can be enabled via flags:
|
|
|
58
58
|
|
|
59
59
|
- **Flatten** dist directories into the package root.
|
|
60
60
|
- **Remove sourcemaps** and their `//# sourceMappingURL=` references.
|
|
61
|
+
- **Strip comments** from JavaScript files, with automatic sourcemap line-mapping adjustment.
|
|
61
62
|
|
|
62
63
|
## Options
|
|
63
64
|
|
|
64
|
-
| Flag | Type | Default | Description
|
|
65
|
-
| --------------------- | ------------------- | --------- |
|
|
66
|
-
| `--profile` | `string` | `library` | Script-retention profile (`library` or `app`).
|
|
67
|
-
| `--flatten` | `string \| boolean` | `false` | Flatten dist directories to the package root. Pass without a value to auto-detect, or provide comma-separated directory names.
|
|
68
|
-
| `--remove-sourcemaps` | `boolean` | `false` | Delete `.map` files and strip `sourceMappingURL` comments from source files.
|
|
69
|
-
| `--
|
|
70
|
-
| `--
|
|
71
|
-
| `--
|
|
72
|
-
| `--
|
|
65
|
+
| Flag | Type | Default | Description |
|
|
66
|
+
| --------------------- | ------------------- | --------- | --------------------------------------------------------------------------------------------------------------------------------- |
|
|
67
|
+
| `--profile` | `string` | `library` | Script-retention profile (`library` or `app`). |
|
|
68
|
+
| `--flatten` | `string \| boolean` | `false` | Flatten dist directories to the package root. Pass without a value to auto-detect, or provide comma-separated directory names. |
|
|
69
|
+
| `--remove-sourcemaps` | `boolean` | `false` | Delete `.map` files and strip `sourceMappingURL` comments from source files. |
|
|
70
|
+
| `--strip-comments` | `string \| boolean` | `false` | Strip comments from JS files. Pass without a value to strip all, or provide comma-separated types: `jsdoc`, `license`, `regular`. |
|
|
71
|
+
| `--optimize-files` | `boolean` | `true` | Optimize the `files` array by collapsing entries. |
|
|
72
|
+
| `--cleanup-files` | `boolean` | `true` | Remove files not listed in the `files` array. |
|
|
73
|
+
| `--version` | | | Show version number. |
|
|
74
|
+
| `--help` | | | Show help message. |
|
|
73
75
|
|
|
74
76
|
## Profiles
|
|
75
77
|
|
|
@@ -124,6 +126,32 @@ pkgprn --flatten dist,lib
|
|
|
124
126
|
7. Updates the `files` array.
|
|
125
127
|
8. Cleans up any leftover export-map stub directories that only contain a `package.json`.
|
|
126
128
|
|
|
129
|
+
## Comment Stripping
|
|
130
|
+
|
|
131
|
+
The `--strip-comments` flag removes comments from `.js`, `.mjs`, and `.cjs` files. You can target specific comment types or strip them all at once.
|
|
132
|
+
|
|
133
|
+
### Usage
|
|
134
|
+
|
|
135
|
+
```sh
|
|
136
|
+
pkgprn --strip-comments # strip all comments
|
|
137
|
+
pkgprn --strip-comments jsdoc # strip only JSDoc comments
|
|
138
|
+
pkgprn --strip-comments license,regular # strip license and regular comments
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
### Comment types
|
|
142
|
+
|
|
143
|
+
| Type | Description |
|
|
144
|
+
| --------- | -------------------------------------------------- |
|
|
145
|
+
| `jsdoc` | `/** … */` documentation comments |
|
|
146
|
+
| `license` | Comments containing "license", "copyright", or "©" |
|
|
147
|
+
| `regular` | All other `//` and `/* … */` comments |
|
|
148
|
+
|
|
149
|
+
Passing `--strip-comments` without a value (or with `all`) strips every type.
|
|
150
|
+
|
|
151
|
+
### Sourcemap adjustment
|
|
152
|
+
|
|
153
|
+
When comments are stripped, line numbers in the affected files change. If any `.d.ts.map` files reference a stripped JS file in their `sources`, `pkgprn` automatically rewrites the sourcemap `mappings` so that line numbers stay correct. This ensures that declaration-map "Go to Definition" navigation continues to point to the right lines after comment removal.
|
|
154
|
+
|
|
127
155
|
## Examples
|
|
128
156
|
|
|
129
157
|
### Basic library
|
|
@@ -156,6 +184,19 @@ After packing, `build` and `test` are removed; `devDependencies` and `packageMan
|
|
|
156
184
|
|
|
157
185
|
After packing, `dist/index.js` becomes `index.js`, `main` points to `index.js`, and the `dist` directory is gone.
|
|
158
186
|
|
|
187
|
+
### Library with comment stripping
|
|
188
|
+
|
|
189
|
+
```json
|
|
190
|
+
{
|
|
191
|
+
"scripts": {
|
|
192
|
+
"build": "tsc",
|
|
193
|
+
"prepack": "pkgprn --strip-comments jsdoc"
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
After packing, all JSDoc comments are removed from JS files and any `.d.ts.map` sourcemaps are adjusted to reflect the new line numbers.
|
|
199
|
+
|
|
159
200
|
### Application with sourcemap removal
|
|
160
201
|
|
|
161
202
|
```sh
|
|
@@ -185,6 +226,7 @@ await prunePkg(
|
|
|
185
226
|
profile: "library",
|
|
186
227
|
flatten: false,
|
|
187
228
|
removeSourcemaps: false,
|
|
229
|
+
stripComments: false, // or "all", "jsdoc", "license,regular", etc.
|
|
188
230
|
optimizeFiles: true,
|
|
189
231
|
cleanupFiles: true,
|
|
190
232
|
},
|
package/index.d.ts
CHANGED
package/index.d.ts.map
CHANGED
package/index.js
CHANGED
|
@@ -43,6 +43,11 @@ try {
|
|
|
43
43
|
description: 'remove sourcemaps',
|
|
44
44
|
default: false,
|
|
45
45
|
},
|
|
46
|
+
stripComments: {
|
|
47
|
+
type: StripCommentsParam,
|
|
48
|
+
description: 'strip comments: all (default), jsdoc, license, regular (comma-separated)',
|
|
49
|
+
default: false,
|
|
50
|
+
},
|
|
46
51
|
optimizeFiles: {
|
|
47
52
|
type: Boolean,
|
|
48
53
|
description: 'optimize files array',
|
|
@@ -99,6 +104,16 @@ async function writePackage(pkg) {
|
|
|
99
104
|
await writeFile('./package.json', `${JSON.stringify(pkg, null, 2)}\n`);
|
|
100
105
|
}
|
|
101
106
|
|
|
107
|
+
/**
|
|
108
|
+
* @param {string | false} value
|
|
109
|
+
*/
|
|
110
|
+
function StripCommentsParam(value) {
|
|
111
|
+
if (value === '') {
|
|
112
|
+
return 'all';
|
|
113
|
+
}
|
|
114
|
+
return value;
|
|
115
|
+
}
|
|
116
|
+
|
|
102
117
|
/**
|
|
103
118
|
* @param {string | false} value
|
|
104
119
|
*/
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pkgprn",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"author": "Konstantin Shutkin",
|
|
6
6
|
"bin": "./index.js",
|
|
@@ -31,8 +31,9 @@
|
|
|
31
31
|
},
|
|
32
32
|
"main": "prune.js",
|
|
33
33
|
"dependencies": {
|
|
34
|
+
"@jridgewell/sourcemap-codec": "^1.5.5",
|
|
35
|
+
"@niceties/logger": "^1.1.13",
|
|
34
36
|
"cleye": "2.2.1",
|
|
35
|
-
"jsonata": "^2.1.0"
|
|
36
|
-
"@niceties/logger": "^1.1.13"
|
|
37
|
+
"jsonata": "^2.1.0"
|
|
37
38
|
}
|
|
38
39
|
}
|
package/prune.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { access, mkdir, readdir, readFile, rename, rm, stat, writeFile } from 'node:fs/promises';
|
|
2
2
|
import path from 'node:path';
|
|
3
3
|
|
|
4
|
+
import { adjustSourcemapLineMappings, isStrippableFile, parseCommentTypes, stripCommentsWithLineMap } from './strip-comments.js';
|
|
5
|
+
|
|
4
6
|
/**
|
|
5
7
|
* Files always included by npm regardless of the `files` array.
|
|
6
8
|
* README & LICENSE/LICENCE are matched case-insensitively by basename (without extension).
|
|
@@ -55,6 +57,7 @@ const hardIgnored = new Set(['.git', '.npmrc', 'node_modules', 'package-lock.jso
|
|
|
55
57
|
* @property {string} profile
|
|
56
58
|
* @property {string|boolean} flatten
|
|
57
59
|
* @property {boolean} removeSourcemaps
|
|
60
|
+
* @property {string|boolean} stripComments
|
|
58
61
|
* @property {boolean} optimizeFiles
|
|
59
62
|
* @property {boolean} cleanupFiles
|
|
60
63
|
*/
|
|
@@ -117,6 +120,54 @@ export async function prunePkg(pkg, options, logger) {
|
|
|
117
120
|
}
|
|
118
121
|
}
|
|
119
122
|
|
|
123
|
+
if (options.stripComments) {
|
|
124
|
+
const typesToStrip = parseCommentTypes(/** @type {string | true} */ (options.stripComments));
|
|
125
|
+
logger.update('stripping comments...');
|
|
126
|
+
const allFiles = await walkDir('.', ['node_modules']);
|
|
127
|
+
const jsFiles = allFiles.filter(isStrippableFile);
|
|
128
|
+
const dtsMapFiles = allFiles.filter(f => f.endsWith('.d.ts.map'));
|
|
129
|
+
|
|
130
|
+
// Strip comments from JS files and collect line maps keyed by file path.
|
|
131
|
+
/** @type {Map<string, Int32Array>} */
|
|
132
|
+
const lineMaps = new Map();
|
|
133
|
+
for (const file of jsFiles) {
|
|
134
|
+
const content = await readFile(file, 'utf8');
|
|
135
|
+
const { result: stripped, lineMap } = stripCommentsWithLineMap(content, typesToStrip);
|
|
136
|
+
if (lineMap) {
|
|
137
|
+
await writeFile(file, stripped, 'utf8');
|
|
138
|
+
lineMaps.set(path.normalize(file), lineMap);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// Adjust .d.ts.map files that reference any of the stripped JS files.
|
|
143
|
+
if (lineMaps.size > 0 && dtsMapFiles.length > 0) {
|
|
144
|
+
for (const mapFile of dtsMapFiles) {
|
|
145
|
+
const mapContent = await readFile(mapFile, 'utf8');
|
|
146
|
+
let map;
|
|
147
|
+
try {
|
|
148
|
+
map = JSON.parse(mapContent);
|
|
149
|
+
} catch {
|
|
150
|
+
continue;
|
|
151
|
+
}
|
|
152
|
+
if (map.version !== 3 || !Array.isArray(map.sources)) continue;
|
|
153
|
+
|
|
154
|
+
const mapDir = path.dirname(mapFile) || '.';
|
|
155
|
+
let adjusted = false;
|
|
156
|
+
for (let si = 0; si < map.sources.length; si++) {
|
|
157
|
+
const resolved = path.normalize(path.join(mapDir, map.sourceRoot || '', map.sources[si]));
|
|
158
|
+
const lineMap = lineMaps.get(resolved);
|
|
159
|
+
if (lineMap) {
|
|
160
|
+
adjustSourcemapLineMappings(map, si, lineMap);
|
|
161
|
+
adjusted = true;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
if (adjusted) {
|
|
165
|
+
await writeFile(mapFile, `${JSON.stringify(map, null, '\t')}\n`, 'utf8');
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
120
171
|
if (pkg.files && Array.isArray(pkg.files) && options.optimizeFiles) {
|
|
121
172
|
const filterFiles = getAlwaysIncludedFiles(pkg);
|
|
122
173
|
|
|
@@ -532,7 +583,7 @@ async function adjustSourcemapPaths(newMapPath, oldMapPath, oldToNew) {
|
|
|
532
583
|
delete map.sourceRoot;
|
|
533
584
|
}
|
|
534
585
|
|
|
535
|
-
await writeFile(newMapPath, JSON.stringify(map, null, 2)
|
|
586
|
+
await writeFile(newMapPath, `${JSON.stringify(map, null, 2)}\n`, 'utf8');
|
|
536
587
|
}
|
|
537
588
|
|
|
538
589
|
/**
|