source-map-explorer 2.3.1 → 2.5.0
Sign up to get free protection for your applications and to get access to all the features.
- package/README.md +19 -7
- package/{dist → bin}/cli.d.ts +1 -1
- package/{dist → bin}/cli.js +59 -93
- package/bin/cli.js.map +1 -0
- package/{dist → lib}/api.d.ts +1 -7
- package/lib/api.js +134 -0
- package/lib/api.js.map +1 -0
- package/{dist → lib}/app-error.d.ts +1 -1
- package/{dist → lib}/app-error.js +14 -34
- package/lib/app-error.js.map +1 -0
- package/{dist → lib}/coverage.d.ts +1 -10
- package/{dist → lib}/coverage.js +28 -125
- package/lib/coverage.js.map +1 -0
- package/{dist → lib}/explore.d.ts +1 -4
- package/lib/explore.js +227 -0
- package/lib/explore.js.map +1 -0
- package/{dist → lib}/helpers.d.ts +2 -16
- package/{dist → lib}/helpers.js +36 -68
- package/lib/helpers.js.map +1 -0
- package/{dist → lib}/html.d.ts +6 -7
- package/lib/html.js +191 -0
- package/lib/html.js.map +1 -0
- package/lib/index.d.ts +4 -0
- package/lib/index.js +31 -0
- package/lib/index.js.map +1 -0
- package/{dist → lib}/output.d.ts +1 -1
- package/{dist → lib}/output.js +22 -53
- package/lib/output.js.map +1 -0
- package/{dist → lib}/tree-viz.ejs +0 -0
- package/lib/types.d.ts +121 -0
- package/{dist → lib}/vendor/webtreemap.css +0 -0
- package/{dist → lib}/vendor/webtreemap.js +0 -0
- package/package.json +72 -72
- package/dist/api.js +0 -168
- package/dist/explore.js +0 -258
- package/dist/html.js +0 -213
- package/dist/index.d.ts +0 -92
- package/dist/index.js +0 -38
package/README.md
CHANGED
@@ -126,11 +126,15 @@ source-map-explorer foo.min.js --tsv result.tsv
|
|
126
126
|
|
127
127
|
These are regular expressions.
|
128
128
|
|
129
|
-
* `--no-root`: By default, source-map-explorer finds common prefixes between all source files and eliminates them, since they add complexity to the visualization with no real benefit. But if you want to disable this behavior, set the `--no-root` flag.
|
129
|
+
* `--no-root`: By default, `source-map-explorer` finds common prefixes between all source files and eliminates them, since they add complexity to the visualization with no real benefit. But if you want to disable this behavior, set the `--no-root` flag.
|
130
|
+
|
131
|
+
* `--no-border-checks`: Disable invalid mapping column/line checks. By default, when a source map references column/line with bigger index than available in the source `source-map-explorers` throws an error indicating that specified source map might be wrong for the source.
|
130
132
|
|
131
133
|
* `--coverage`: If the path to a valid a chrome code coverage JSON export is supplied, the tree map will be colorized according to which percentage of the modules code was executed
|
132
134
|
|
133
|
-
* `--gzip`:
|
135
|
+
* `--gzip`: Calculate gzip size. It also sets `onlyMapped` flag
|
136
|
+
|
137
|
+
* `--sort`: Sort filenames
|
134
138
|
|
135
139
|
<details>
|
136
140
|
<summary>Examples</summary>
|
@@ -143,7 +147,7 @@ source-map-explorer -h
|
|
143
147
|
```
|
144
148
|
Analyze and debug space usage through source maps.
|
145
149
|
Usage:
|
146
|
-
source-map-explorer script.js [script.js.map] [--json [result.json] | --html [result.html] | --tsv [result.csv]] [-m | --only-mapped] [--exclude-source-map] [--gzip] [--replace=BEFORE_1 BEFORE_2 --with=AFTER_1 AFTER_2] [--no-root] [--coverage coverage.json] [--version] [--help | -h]
|
150
|
+
source-map-explorer script.js [script.js.map] [--json [result.json] | --html [result.html] | --tsv [result.csv]] [-m | --only-mapped] [--exclude-source-map] [--no-border-checks] [--gzip] [--sort] [--replace=BEFORE_1 BEFORE_2 --with=AFTER_1 AFTER_2] [--no-root] [--coverage coverage.json] [--version] [--help | -h]
|
147
151
|
|
148
152
|
Output:
|
149
153
|
--json If filename specified save output as JSON to specified file otherwise output to stdout. [string]
|
@@ -160,9 +164,11 @@ Options:
|
|
160
164
|
--only-mapped, -m Exclude "unmapped" bytes from the output. This will result in total counts less than the file size [boolean]
|
161
165
|
--exclude-source-map Exclude source map comment size from output [boolean]
|
162
166
|
--no-root To simplify the visualization, source-map-explorer will remove any prefix shared by all sources. If you wish to disable this behavior, set --no-root. [boolean]
|
167
|
+
--no-border-checks Disable invalid mapping column/line checks. [boolean]
|
163
168
|
--coverage If the path to a valid a chrome code coverage JSON export is supplied, the tree map will be colorized according to which percentage of the modules code was executed
|
164
169
|
[string]
|
165
170
|
--gzip Calculate gzip size. It also sets onlyMapped flag [boolean]
|
171
|
+
--sort Sort filenames [boolean]
|
166
172
|
-h, --help Show help [boolean]
|
167
173
|
|
168
174
|
Examples:
|
@@ -294,10 +300,10 @@ source-map-explorer script.js --tsv --no-root
|
|
294
300
|
### On error
|
295
301
|
Errors will be displayed only if no output flags specified
|
296
302
|
```
|
297
|
-
source-map-explore with-unmapped.js no-map.js
|
303
|
+
source-map-explore with-unmapped.js no-map-comment.js
|
298
304
|
```
|
299
305
|
```
|
300
|
-
no-map.js
|
306
|
+
no-map-comment.js
|
301
307
|
Unable to find a source map.
|
302
308
|
See https://github.com/danvk/source-map-explorer/blob/master/README.md#generating-source-maps
|
303
309
|
with-unmapped.js
|
@@ -326,6 +332,7 @@ with-unmapped.js
|
|
326
332
|
* `format`: [string] - `'json'`, `'tsv'` or `'html'`
|
327
333
|
* `filename`: [string] - Filename to save output to
|
328
334
|
* `noRoot`: [boolean] (default `false`) - See `--no-root` option above for details
|
335
|
+
* `noBorderChecks`: [boolean] - Disable invalid mapping column/line checks. See `--no-border-checks` above.
|
329
336
|
* `replaceMap`: <[Object]<{ [from: [string]]: [string] }>> - Mapping for replacement, see `--replace`, `--with` options above for details.
|
330
337
|
* `coverage`: [string] - If the path to a valid a chrome code coverage JSON export is supplied, the tree map will be colorized according to which percentage of the modules code was executed
|
331
338
|
* `gzip`: [boolean] - Calculate gzip size. It also sets `onlyMapped` flag
|
@@ -555,9 +562,14 @@ source-map-explorer path/to/foo.min.js{,.map}
|
|
555
562
|
|
556
563
|
### Other source map tools
|
557
564
|
|
558
|
-
[source-map-visualization](https://sokra.github.io/source-map-visualization)
|
565
|
+
- [source-map-visualization](https://sokra.github.io/source-map-visualization)
|
566
|
+
|
567
|
+
- [bundle-wizard](https://github.com/aholachek/bundle-wizard) - Easier analysis of webapp entry points (uses source-map-explorer under the hood)
|
568
|
+
|
569
|
+
### Learn about source maps
|
559
570
|
|
560
|
-
[
|
571
|
+
- [Standard](https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit)
|
572
|
+
- [Anatomy of source maps](https://www.bugsnag.com/blog/source-maps)
|
561
573
|
|
562
574
|
[demo]: https://cdn.rawgit.com/danvk/source-map-explorer/08b0e130cb9345f9061760bf8a8d9136ea60b457/demo.html
|
563
575
|
[another demo]: https://cdn.rawgit.com/danvk/source-map-explorer/08b0e130cb9345f9061760bf8a8d9136ea60b457/demo-bug.html
|
package/{dist → bin}/cli.d.ts
RENAMED
@@ -1,5 +1,5 @@
|
|
1
1
|
#!/usr/bin/env node
|
2
|
-
import { ErrorContext } from '
|
2
|
+
import type { ErrorContext } from '../lib/app-error';
|
3
3
|
export declare function logError(message: string | ErrorContext, error?: Error): void;
|
4
4
|
export declare function logWarn(message: string): void;
|
5
5
|
export declare function logInfo(message: string): void;
|
package/{dist → bin}/cli.js
RENAMED
@@ -1,41 +1,28 @@
|
|
1
1
|
#!/usr/bin/env node
|
2
2
|
'use strict';
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
}
|
7
|
-
|
8
|
-
exports
|
9
|
-
exports.logInfo =
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
var _chalk = _interopRequireDefault(require('chalk'));
|
20
|
-
|
21
|
-
var _lodash = require('lodash');
|
22
|
-
|
23
|
-
var _api = require('./api');
|
24
|
-
|
25
|
-
var _appError = require('./app-error');
|
26
|
-
|
27
|
-
function _interopRequireDefault(obj) {
|
28
|
-
return obj && obj.__esModule ? obj : { default: obj };
|
29
|
-
}
|
30
|
-
|
3
|
+
var __importDefault =
|
4
|
+
(this && this.__importDefault) ||
|
5
|
+
function (mod) {
|
6
|
+
return mod && mod.__esModule ? mod : { default: mod };
|
7
|
+
};
|
8
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
9
|
+
exports.logInfo = exports.logWarn = exports.logError = void 0;
|
10
|
+
const yargs_1 = __importDefault(require('yargs'));
|
11
|
+
const fs_1 = __importDefault(require('fs'));
|
12
|
+
const temp_1 = __importDefault(require('temp'));
|
13
|
+
const open_1 = __importDefault(require('open'));
|
14
|
+
const chalk_1 = __importDefault(require('chalk'));
|
15
|
+
const lodash_1 = require('lodash');
|
16
|
+
const api_1 = require('../lib/api');
|
17
|
+
const app_error_1 = require('../lib/app-error');
|
31
18
|
function parseArguments() {
|
32
|
-
const argv =
|
19
|
+
const argv = yargs_1.default
|
33
20
|
.strict()
|
34
21
|
.scriptName('source-map-explorer')
|
35
22
|
.usage('Analyze and debug space usage through source maps.')
|
36
23
|
.usage('Usage:')
|
37
24
|
.usage(
|
38
|
-
'$0 script.js [script.js.map] [--json [result.json] | --html [result.html] | --tsv [result.csv]] [-m | --only-mapped] [--exclude-source-map] [--gzip] [--replace=BEFORE_1 BEFORE_2 --with=AFTER_1 AFTER_2] [--no-root] [--coverage coverage.json] [--version] [--help | -h]'
|
25
|
+
'$0 script.js [script.js.map] [--json [result.json] | --html [result.html] | --tsv [result.csv]] [-m | --only-mapped] [--exclude-source-map] [--no-border-checks] [--gzip] [--sort] [--replace=BEFORE_1 BEFORE_2 --with=AFTER_1 AFTER_2] [--no-root] [--coverage coverage.json] [--version] [--help | -h]'
|
39
26
|
)
|
40
27
|
.example('$0 script.js script.js.map', 'Explore bundle')
|
41
28
|
.example('$0 script.js', 'Explore bundle with inline source map')
|
@@ -90,6 +77,10 @@ function parseArguments() {
|
|
90
77
|
description: 'See --replace.',
|
91
78
|
implies: 'replace',
|
92
79
|
},
|
80
|
+
'no-border-checks': {
|
81
|
+
type: 'boolean',
|
82
|
+
description: 'Disable invalid mapping column/line checks.',
|
83
|
+
},
|
93
84
|
coverage: {
|
94
85
|
type: 'string',
|
95
86
|
normalize: true,
|
@@ -101,53 +92,50 @@ function parseArguments() {
|
|
101
92
|
description: 'Calculate gzip size. It also sets onlyMapped flag',
|
102
93
|
conflicts: ['only-mapped'],
|
103
94
|
},
|
95
|
+
sort: {
|
96
|
+
type: 'boolean',
|
97
|
+
description: 'Sort filenames',
|
98
|
+
},
|
104
99
|
})
|
105
100
|
.group(['json', 'tsv', 'html'], 'Output:')
|
106
101
|
.group(['replace', 'with'], 'Replace:')
|
107
102
|
.help('h')
|
108
103
|
.alias('h', 'help')
|
109
104
|
.showHelpOnFail(false, 'Specify --help for available options')
|
110
|
-
.wrap(null)
|
105
|
+
.wrap(null)
|
111
106
|
.parserConfiguration({
|
112
|
-
'boolean-negation': false,
|
107
|
+
'boolean-negation': false,
|
113
108
|
})
|
114
|
-
.check(argv => {
|
109
|
+
.check((argv) => {
|
115
110
|
if (argv.replace && argv.with && argv.replace.length !== argv.with.length) {
|
116
111
|
throw new Error('--replace flags must be paired with --with flags');
|
117
112
|
}
|
118
|
-
|
119
113
|
return true;
|
120
114
|
})
|
121
|
-
.parse();
|
122
|
-
|
115
|
+
.parse();
|
123
116
|
const quoteRegex = /'/g;
|
124
|
-
argv._ = argv._.map(path => path.replace(quoteRegex, ''));
|
117
|
+
argv._ = argv._.map((path) => path.replace(quoteRegex, ''));
|
125
118
|
return argv;
|
126
119
|
}
|
127
|
-
|
128
120
|
function logError(message, error) {
|
129
|
-
if (!
|
130
|
-
message =
|
121
|
+
if (!lodash_1.isString(message)) {
|
122
|
+
message = app_error_1.getErrorMessage(message);
|
131
123
|
}
|
132
|
-
|
133
124
|
if (error) {
|
134
|
-
console.error(
|
125
|
+
console.error(chalk_1.default.red(message), error);
|
135
126
|
} else {
|
136
|
-
console.error(
|
127
|
+
console.error(chalk_1.default.red(message));
|
137
128
|
}
|
138
129
|
}
|
139
|
-
|
130
|
+
exports.logError = logError;
|
140
131
|
function logWarn(message) {
|
141
|
-
console.warn(
|
132
|
+
console.warn(chalk_1.default.yellow(message));
|
142
133
|
}
|
143
|
-
|
134
|
+
exports.logWarn = logWarn;
|
144
135
|
function logInfo(message) {
|
145
|
-
console.log(
|
136
|
+
console.log(chalk_1.default.green(message));
|
146
137
|
}
|
147
|
-
|
148
|
-
* Create options object for `explore` method
|
149
|
-
*/
|
150
|
-
|
138
|
+
exports.logInfo = logInfo;
|
151
139
|
function getExploreOptions(argv) {
|
152
140
|
const {
|
153
141
|
json,
|
@@ -158,83 +146,60 @@ function getExploreOptions(argv) {
|
|
158
146
|
onlyMapped,
|
159
147
|
excludeSourceMap: excludeSourceMapComment,
|
160
148
|
noRoot,
|
149
|
+
noBorderChecks,
|
161
150
|
coverage,
|
162
151
|
gzip,
|
152
|
+
sort,
|
163
153
|
} = argv;
|
164
154
|
let replaceMap;
|
165
|
-
|
166
155
|
if (replaceItems && withItems) {
|
167
156
|
replaceMap = replaceItems.reduce((result, item, index) => {
|
168
157
|
result[item] = withItems[index];
|
169
158
|
return result;
|
170
159
|
}, {});
|
171
160
|
}
|
172
|
-
|
173
161
|
return {
|
174
162
|
output: {
|
175
|
-
|
176
|
-
format: (0, _lodash.isString)(json) ? 'json' : (0, _lodash.isString)(tsv) ? 'tsv' : 'html',
|
163
|
+
format: lodash_1.isString(json) ? 'json' : lodash_1.isString(tsv) ? 'tsv' : 'html',
|
177
164
|
filename: json || tsv || html,
|
178
165
|
},
|
179
166
|
replaceMap,
|
180
167
|
onlyMapped,
|
181
168
|
excludeSourceMapComment,
|
182
169
|
noRoot,
|
170
|
+
noBorderChecks,
|
183
171
|
coverage,
|
184
172
|
gzip,
|
173
|
+
sort,
|
185
174
|
};
|
186
175
|
}
|
187
|
-
/**
|
188
|
-
* Write HTML content to a temporary file and open the file in a browser
|
189
|
-
*/
|
190
|
-
|
191
176
|
async function writeHtmlToTempFile(html) {
|
192
177
|
if (!html) {
|
193
178
|
return;
|
194
179
|
}
|
195
|
-
|
196
180
|
try {
|
197
|
-
const tempFile =
|
198
|
-
|
199
|
-
|
200
|
-
});
|
201
|
-
|
202
|
-
_fs.default.writeFileSync(tempFile, html);
|
203
|
-
|
204
|
-
const childProcess = await (0, _open.default)(tempFile);
|
205
|
-
|
181
|
+
const tempFile = temp_1.default.path({ prefix: 'sme-result-', suffix: '.html' });
|
182
|
+
fs_1.default.writeFileSync(tempFile, html);
|
183
|
+
const childProcess = await open_1.default(tempFile);
|
206
184
|
if (childProcess.stderr) {
|
207
|
-
|
208
|
-
|
209
|
-
logError({
|
210
|
-
code: 'CannotOpenTempFile',
|
211
|
-
tempFile,
|
212
|
-
error,
|
213
|
-
});
|
185
|
+
childProcess.stderr.once('data', (error) => {
|
186
|
+
logError({ code: 'CannotOpenTempFile', tempFile, error });
|
214
187
|
});
|
215
188
|
}
|
216
189
|
} catch (error) {
|
217
|
-
throw new
|
218
|
-
{
|
219
|
-
code: 'CannotCreateTempFile',
|
220
|
-
},
|
221
|
-
error
|
222
|
-
);
|
190
|
+
throw new app_error_1.AppError({ code: 'CannotCreateTempFile' }, error);
|
223
191
|
}
|
224
192
|
}
|
225
|
-
|
226
193
|
function outputErrors({ errors }) {
|
227
194
|
if (errors.length === 0) {
|
228
195
|
return;
|
229
|
-
}
|
230
|
-
|
231
|
-
const groupedErrors = (0, _lodash.groupBy)(errors, 'bundleName');
|
196
|
+
}
|
197
|
+
const groupedErrors = lodash_1.groupBy(errors, 'bundleName');
|
232
198
|
Object.entries(groupedErrors).forEach(([bundleName, errors]) => {
|
233
199
|
console.group(bundleName);
|
234
200
|
const hasManyErrors = errors.length > 1;
|
235
201
|
errors.forEach((error, index) => {
|
236
202
|
const message = `${hasManyErrors ? `${index + 1}. ` : ''}${error.message}`;
|
237
|
-
|
238
203
|
if (error.isWarning) {
|
239
204
|
logWarn(message);
|
240
205
|
} else {
|
@@ -244,16 +209,15 @@ function outputErrors({ errors }) {
|
|
244
209
|
console.groupEnd();
|
245
210
|
});
|
246
211
|
}
|
247
|
-
|
248
212
|
if (require.main === module) {
|
249
213
|
const argv = parseArguments();
|
250
|
-
const isOutputFormatSpecified = [argv.json, argv.tsv, argv.html].some(
|
214
|
+
const isOutputFormatSpecified = [argv.json, argv.tsv, argv.html].some(lodash_1.isString);
|
251
215
|
const options = getExploreOptions(argv);
|
252
|
-
|
253
|
-
.
|
216
|
+
api_1
|
217
|
+
.explore(argv._, options)
|
218
|
+
.then((result) => {
|
254
219
|
if (isOutputFormatSpecified && options.output) {
|
255
220
|
const filename = options.output.filename;
|
256
|
-
|
257
221
|
if (filename) {
|
258
222
|
logInfo(`Output saved to ${filename}`);
|
259
223
|
outputErrors(result);
|
@@ -266,11 +230,13 @@ if (require.main === module) {
|
|
266
230
|
});
|
267
231
|
}
|
268
232
|
})
|
269
|
-
.catch(error => {
|
233
|
+
.catch((error) => {
|
270
234
|
if (error.errors) {
|
271
235
|
outputErrors(error);
|
272
236
|
} else {
|
273
237
|
logError('Failed to explore', error);
|
274
238
|
}
|
239
|
+
process.exitCode = 1;
|
275
240
|
});
|
276
241
|
}
|
242
|
+
//# sourceMappingURL=cli.js.map
|
package/bin/cli.js.map
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli/cli.ts"],"names":[],"mappings":"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","sourcesContent":["#!/usr/bin/env node\n\nimport yargs from 'yargs';\nimport fs from 'fs';\nimport temp from 'temp';\nimport open from 'open';\nimport chalk from 'chalk';\nimport { groupBy, isString } from 'lodash';\n\nimport { explore } from '../lib/api';\nimport { AppError, getErrorMessage } from '../lib/app-error';\n\nimport type { ErrorContext } from '../lib/app-error';\nimport type { ExploreOptions, ReplaceMap, ExploreResult } from '../lib/types';\n\n/** Parsed CLI arguments */\ninterface Arguments {\n _: string[];\n json?: string;\n tsv?: string;\n html?: string;\n onlyMapped?: boolean;\n excludeSourceMap?: boolean;\n noRoot?: boolean;\n replace?: string[];\n with?: string[];\n noBorderChecks?: boolean;\n coverage?: string;\n gzip?: boolean;\n sort?: boolean;\n}\n\nfunction parseArguments(): Arguments {\n const argv = yargs\n .strict()\n .scriptName('source-map-explorer')\n .usage('Analyze and debug space usage through source maps.')\n .usage('Usage:')\n .usage(\n '$0 script.js [script.js.map] [--json [result.json] | --html [result.html] | --tsv [result.csv]] [-m | --only-mapped] [--exclude-source-map] [--no-border-checks] [--gzip] [--sort] [--replace=BEFORE_1 BEFORE_2 --with=AFTER_1 AFTER_2] [--no-root] [--coverage coverage.json] [--version] [--help | -h]'\n )\n .example('$0 script.js script.js.map', 'Explore bundle')\n .example('$0 script.js', 'Explore bundle with inline source map')\n .example('$0 dist/js/*.*', 'Explore all bundles inside dist/js folder')\n .example('$0 script.js --tsv', 'Explore and output result as TSV to stdout')\n .example('$0 script.js --json result.json', 'Explore and save result as JSON to the file')\n .demandCommand(1, 'At least one js file must be specified')\n .options({\n json: {\n type: 'string',\n description:\n 'If filename specified save output as JSON to specified file otherwise output to stdout.',\n conflicts: ['tsv', 'html'],\n },\n tsv: {\n type: 'string',\n description:\n 'If filename specified save output as TSV to specified file otherwise output to stdout.',\n conflicts: ['json', 'html'],\n },\n html: {\n type: 'string',\n description:\n 'If filename specified save output as HTML to specified file otherwise output to stdout rather than opening a browser.',\n conflicts: ['json', 'tsv'],\n },\n\n 'only-mapped': {\n alias: 'm',\n type: 'boolean',\n description:\n 'Exclude \"unmapped\" bytes from the output. This will result in total counts less than the file size',\n },\n\n 'exclude-source-map': {\n type: 'boolean',\n description: 'Exclude source map comment size from output',\n },\n\n 'no-root': {\n type: 'boolean',\n description:\n 'To simplify the visualization, source-map-explorer will remove any prefix shared by all sources. If you wish to disable this behavior, set --no-root.',\n },\n\n replace: {\n type: 'string',\n array: true,\n description:\n 'Apply a simple find/replace on source file names. This can be used to fix some oddities with paths that appear in the source map generation process. Accepts regular expressions.',\n implies: 'with',\n },\n with: {\n type: 'string',\n array: true,\n description: 'See --replace.',\n implies: 'replace',\n },\n\n 'no-border-checks': {\n type: 'boolean',\n description: 'Disable invalid mapping column/line checks.',\n },\n\n coverage: {\n type: 'string',\n normalize: true,\n description:\n 'If the path to a valid a chrome code coverage JSON export is supplied, the tree map will be colorized according to which percentage of the modules code was executed',\n },\n\n gzip: {\n type: 'boolean',\n description: 'Calculate gzip size. It also sets onlyMapped flag',\n conflicts: ['only-mapped'],\n },\n\n sort: {\n type: 'boolean',\n description: 'Sort filenames',\n },\n })\n .group(['json', 'tsv', 'html'], 'Output:')\n .group(['replace', 'with'], 'Replace:')\n .help('h')\n .alias('h', 'help')\n .showHelpOnFail(false, 'Specify --help for available options')\n .wrap(null) // Do not limit line length\n .parserConfiguration({\n 'boolean-negation': false, // Allow --no-root\n })\n .check((argv) => {\n if (argv.replace && argv.with && argv.replace.length !== argv.with.length) {\n throw new Error('--replace flags must be paired with --with flags');\n }\n\n return true;\n })\n .parse();\n\n // Trim extra quotes\n const quoteRegex = /'/g;\n\n argv._ = argv._.map((path) => path.replace(quoteRegex, ''));\n\n return argv;\n}\n\nexport function logError(message: string | ErrorContext, error?: Error): void {\n if (!isString(message)) {\n message = getErrorMessage(message);\n }\n\n if (error) {\n console.error(chalk.red(message), error);\n } else {\n console.error(chalk.red(message));\n }\n}\n\nexport function logWarn(message: string): void {\n console.warn(chalk.yellow(message));\n}\n\nexport function logInfo(message: string): void {\n console.log(chalk.green(message));\n}\n\n/**\n * Create options object for `explore` method\n */\nfunction getExploreOptions(argv: Arguments): ExploreOptions {\n const {\n json,\n tsv,\n html,\n replace: replaceItems,\n with: withItems,\n onlyMapped,\n excludeSourceMap: excludeSourceMapComment,\n noRoot,\n noBorderChecks,\n coverage,\n gzip,\n sort,\n } = argv;\n\n let replaceMap: ReplaceMap | undefined;\n\n if (replaceItems && withItems) {\n replaceMap = replaceItems.reduce<ReplaceMap>((result, item, index) => {\n result[item] = withItems[index];\n\n return result;\n }, {});\n }\n\n return {\n output: {\n // By default CLI needs result in HTML in order to create a temporary file\n format: isString(json) ? 'json' : isString(tsv) ? 'tsv' : 'html',\n filename: json || tsv || html,\n },\n replaceMap,\n onlyMapped,\n excludeSourceMapComment,\n noRoot,\n noBorderChecks,\n coverage,\n gzip,\n sort,\n };\n}\n\n/**\n * Write HTML content to a temporary file and open the file in a browser\n */\nasync function writeHtmlToTempFile(html?: string): Promise<void> {\n if (!html) {\n return;\n }\n\n try {\n const tempFile = temp.path({ prefix: 'sme-result-', suffix: '.html' });\n\n fs.writeFileSync(tempFile, html);\n\n const childProcess = await open(tempFile);\n\n if (childProcess.stderr) {\n // Catch error output from child process\n childProcess.stderr.once('data', (error: Buffer) => {\n logError({ code: 'CannotOpenTempFile', tempFile, error });\n });\n }\n } catch (error) {\n throw new AppError({ code: 'CannotCreateTempFile' }, error);\n }\n}\n\nfunction outputErrors({ errors }: ExploreResult): void {\n if (errors.length === 0) {\n return;\n }\n\n // Group errors by bundle name\n const groupedErrors = groupBy(errors, 'bundleName');\n\n Object.entries(groupedErrors).forEach(([bundleName, errors]) => {\n console.group(bundleName);\n\n const hasManyErrors = errors.length > 1;\n\n errors.forEach((error, index) => {\n const message = `${hasManyErrors ? `${index + 1}. ` : ''}${error.message}`;\n\n if (error.isWarning) {\n logWarn(message);\n } else {\n logError(message);\n }\n });\n\n console.groupEnd();\n });\n}\n\nif (require.main === module) {\n const argv = parseArguments();\n\n const isOutputFormatSpecified = [argv.json, argv.tsv, argv.html].some(isString);\n\n const options = getExploreOptions(argv);\n\n explore(argv._, options)\n .then((result) => {\n if (isOutputFormatSpecified && options.output) {\n const filename = options.output.filename;\n\n if (filename) {\n logInfo(`Output saved to ${filename}`);\n outputErrors(result);\n } else {\n console.log(result.output);\n }\n } else {\n writeHtmlToTempFile(result.output).then(() => {\n outputErrors(result);\n });\n }\n })\n .catch((error) => {\n if (error.errors) {\n outputErrors(error);\n } else {\n logError('Failed to explore', error);\n }\n\n process.exitCode = 1;\n });\n}\n"]}
|
package/{dist → lib}/api.d.ts
RENAMED
@@ -1,10 +1,4 @@
|
|
1
|
-
import { BundlesAndFileTokens, ExploreOptions, ExploreResult
|
2
|
-
/**
|
3
|
-
* Analyze bundle(s)
|
4
|
-
*/
|
1
|
+
import type { Bundle, BundlesAndFileTokens, ExploreOptions, ExploreResult } from './types';
|
5
2
|
export declare function explore(bundlesAndFileTokens: BundlesAndFileTokens, options?: ExploreOptions): Promise<ExploreResult>;
|
6
|
-
/**
|
7
|
-
* Expand list of file tokens into a list of bundles
|
8
|
-
*/
|
9
3
|
export declare function getBundles(fileTokens: string[]): Bundle[];
|
10
4
|
export declare function getBundleName(bundle: Bundle): string;
|
package/lib/api.js
ADDED
@@ -0,0 +1,134 @@
|
|
1
|
+
'use strict';
|
2
|
+
var __importDefault =
|
3
|
+
(this && this.__importDefault) ||
|
4
|
+
function (mod) {
|
5
|
+
return mod && mod.__esModule ? mod : { default: mod };
|
6
|
+
};
|
7
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
8
|
+
exports.getBundleName = exports.getBundles = exports.explore = void 0;
|
9
|
+
const glob_1 = __importDefault(require('glob'));
|
10
|
+
const lodash_1 = require('lodash');
|
11
|
+
const explore_1 = require('./explore');
|
12
|
+
const app_error_1 = require('./app-error');
|
13
|
+
const output_1 = require('./output');
|
14
|
+
const coverage_1 = require('./coverage');
|
15
|
+
function adjustOptions(options) {
|
16
|
+
if (options.gzip) {
|
17
|
+
options.onlyMapped = true;
|
18
|
+
}
|
19
|
+
return options;
|
20
|
+
}
|
21
|
+
async function explore(bundlesAndFileTokens, options = {}) {
|
22
|
+
bundlesAndFileTokens = Array.isArray(bundlesAndFileTokens)
|
23
|
+
? bundlesAndFileTokens
|
24
|
+
: [bundlesAndFileTokens];
|
25
|
+
if (bundlesAndFileTokens.length === 0) {
|
26
|
+
throw new app_error_1.AppError({ code: 'NoBundles' });
|
27
|
+
}
|
28
|
+
adjustOptions(options);
|
29
|
+
const [fileTokens, bundles] = lodash_1.partition(bundlesAndFileTokens, lodash_1.isString);
|
30
|
+
bundles.push(...getBundles(fileTokens));
|
31
|
+
coverage_1.addCoverageRanges(bundles, options.coverage);
|
32
|
+
const results = await Promise.all(
|
33
|
+
bundles.map((bundle) =>
|
34
|
+
explore_1.exploreBundle(bundle, options).catch((error) => onExploreError(bundle, error))
|
35
|
+
)
|
36
|
+
);
|
37
|
+
const exploreResult = getExploreResult(results, options);
|
38
|
+
if (exploreResult.bundles.length === 0) {
|
39
|
+
return Promise.reject(exploreResult);
|
40
|
+
}
|
41
|
+
output_1.saveOutputToFile(exploreResult, options);
|
42
|
+
return exploreResult;
|
43
|
+
}
|
44
|
+
exports.explore = explore;
|
45
|
+
function getBundles(fileTokens) {
|
46
|
+
const filenames = lodash_1.flatMap(fileTokens, (filePath) =>
|
47
|
+
glob_1.default.hasMagic(filePath) ? expandGlob(filePath) : filePath
|
48
|
+
);
|
49
|
+
const [mapFilenames, codeFilenames] = lodash_1.partition(filenames, (filename) =>
|
50
|
+
filename.endsWith('.map')
|
51
|
+
);
|
52
|
+
return codeFilenames.map((code) => ({
|
53
|
+
code,
|
54
|
+
map: mapFilenames.find((filename) => filename === `${code}.map`),
|
55
|
+
}));
|
56
|
+
}
|
57
|
+
exports.getBundles = getBundles;
|
58
|
+
function expandGlob(pattern) {
|
59
|
+
if (pattern.endsWith('.js')) {
|
60
|
+
pattern = `${pattern}?(.map)`;
|
61
|
+
}
|
62
|
+
return glob_1.default.sync(pattern);
|
63
|
+
}
|
64
|
+
function getBundleName(bundle) {
|
65
|
+
return Buffer.isBuffer(bundle.code) ? 'Buffer' : bundle.code;
|
66
|
+
}
|
67
|
+
exports.getBundleName = getBundleName;
|
68
|
+
function onExploreError(bundle, error) {
|
69
|
+
return {
|
70
|
+
bundleName: getBundleName(bundle),
|
71
|
+
code: error.code || 'Unknown',
|
72
|
+
message: error.message,
|
73
|
+
error,
|
74
|
+
};
|
75
|
+
}
|
76
|
+
function sortFilenames(bundles) {
|
77
|
+
return bundles.map((bundle) => ({
|
78
|
+
...bundle,
|
79
|
+
files: lodash_1.fromPairs(lodash_1.sortBy(lodash_1.toPairs(bundle.files), 0)),
|
80
|
+
}));
|
81
|
+
}
|
82
|
+
function getExploreResult(results, options) {
|
83
|
+
const [bundles, errors] = lodash_1.partition(results, (result) => 'files' in result);
|
84
|
+
let sortedBundles = lodash_1.sortBy(bundles, (bundle) => bundle.bundleName);
|
85
|
+
if (options.sort) {
|
86
|
+
sortedBundles = sortFilenames(sortedBundles);
|
87
|
+
}
|
88
|
+
errors.push(...getPostExploreErrors(bundles));
|
89
|
+
return {
|
90
|
+
bundles: sortedBundles,
|
91
|
+
errors,
|
92
|
+
...(bundles.length > 0 && { output: output_1.formatOutput(sortedBundles, options) }),
|
93
|
+
};
|
94
|
+
}
|
95
|
+
function getPostExploreErrors(exploreBundleResults) {
|
96
|
+
const errors = [];
|
97
|
+
const isSingleBundle = exploreBundleResults.length === 1;
|
98
|
+
for (const result of exploreBundleResults) {
|
99
|
+
const { bundleName, files, totalBytes } = result;
|
100
|
+
if (isSingleBundle) {
|
101
|
+
const filenames = Object.keys(files).filter(
|
102
|
+
(filename) => !explore_1.SPECIAL_FILENAMES.includes(filename)
|
103
|
+
);
|
104
|
+
if (filenames.length === 1) {
|
105
|
+
errors.push({
|
106
|
+
bundleName,
|
107
|
+
isWarning: true,
|
108
|
+
code: 'OneSourceSourceMap',
|
109
|
+
message: app_error_1.getErrorMessage({
|
110
|
+
code: 'OneSourceSourceMap',
|
111
|
+
filename: filenames[0],
|
112
|
+
}),
|
113
|
+
});
|
114
|
+
}
|
115
|
+
}
|
116
|
+
if (files[explore_1.UNMAPPED_KEY] !== undefined) {
|
117
|
+
const { size: unmappedBytes } = files[explore_1.UNMAPPED_KEY];
|
118
|
+
if (unmappedBytes) {
|
119
|
+
errors.push({
|
120
|
+
bundleName,
|
121
|
+
isWarning: true,
|
122
|
+
code: 'UnmappedBytes',
|
123
|
+
message: app_error_1.getErrorMessage({
|
124
|
+
code: 'UnmappedBytes',
|
125
|
+
unmappedBytes,
|
126
|
+
totalBytes,
|
127
|
+
}),
|
128
|
+
});
|
129
|
+
}
|
130
|
+
}
|
131
|
+
}
|
132
|
+
return errors;
|
133
|
+
}
|
134
|
+
//# sourceMappingURL=api.js.map
|
package/lib/api.js.map
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"api.js","sourceRoot":"","sources":["../src/lib/api.ts"],"names":[],"mappings":"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","sourcesContent":["import glob from 'glob';\nimport { partition, flatMap, isString, toPairs, fromPairs, sortBy } from 'lodash';\n\nimport { exploreBundle, UNMAPPED_KEY, SPECIAL_FILENAMES } from './explore';\nimport { AppError, getErrorMessage } from './app-error';\nimport { formatOutput, saveOutputToFile } from './output';\nimport { addCoverageRanges } from './coverage';\n\nimport type {\n Bundle,\n BundlesAndFileTokens,\n ExploreBundleResult,\n ExploreErrorResult,\n ExploreOptions,\n ExploreResult,\n} from './types';\n\nfunction adjustOptions(options: ExploreOptions): ExploreOptions {\n /* Unmapped bytes cannot be calculate because it's impossible to get total size by summing files'\n sizes when calculating gzip size for a file. */\n if (options.gzip) {\n options.onlyMapped = true;\n }\n\n return options;\n}\n\n/**\n * Analyze bundle(s)\n */\nexport async function explore(\n bundlesAndFileTokens: BundlesAndFileTokens,\n options: ExploreOptions = {}\n): Promise<ExploreResult> {\n bundlesAndFileTokens = Array.isArray(bundlesAndFileTokens)\n ? bundlesAndFileTokens\n : [bundlesAndFileTokens];\n\n if (bundlesAndFileTokens.length === 0) {\n throw new AppError({ code: 'NoBundles' });\n }\n\n adjustOptions(options);\n\n // Separate bundles from file tokens\n const [fileTokens, bundles] = partition(bundlesAndFileTokens, isString);\n\n // Get bundles from file tokens\n bundles.push(...getBundles(fileTokens));\n\n addCoverageRanges(bundles, options.coverage);\n\n const results = await Promise.all(\n bundles.map((bundle) =>\n exploreBundle(bundle, options).catch<ExploreErrorResult>((error) =>\n onExploreError(bundle, error)\n )\n )\n );\n\n const exploreResult = getExploreResult(results, options);\n\n // Reject if none of results is successful\n if (exploreResult.bundles.length === 0) {\n return Promise.reject(exploreResult);\n }\n\n saveOutputToFile(exploreResult, options);\n\n return exploreResult;\n}\n\n/**\n * Expand list of file tokens into a list of bundles\n */\nexport function getBundles(fileTokens: string[]): Bundle[] {\n const filenames = flatMap(fileTokens, (filePath) =>\n glob.hasMagic(filePath) ? expandGlob(filePath) : filePath\n );\n\n const [mapFilenames, codeFilenames] = partition(filenames, (filename) =>\n filename.endsWith('.map')\n );\n\n return codeFilenames.map<Bundle>((code) => ({\n code,\n map: mapFilenames.find((filename) => filename === `${code}.map`),\n }));\n}\n\nfunction expandGlob(pattern: string): string[] {\n // Make sure pattern match `.map` files as well\n if (pattern.endsWith('.js')) {\n pattern = `${pattern}?(.map)`;\n }\n\n return glob.sync(pattern);\n}\n\nexport function getBundleName(bundle: Bundle): string {\n return Buffer.isBuffer(bundle.code) ? 'Buffer' : bundle.code;\n}\n\n/**\n * Handle error during bundle processing\n */\nfunction onExploreError(bundle: Bundle, error: NodeJS.ErrnoException): ExploreErrorResult {\n return {\n bundleName: getBundleName(bundle),\n code: error.code || 'Unknown',\n message: error.message,\n error,\n };\n}\n\nfunction sortFilenames(bundles: ExploreBundleResult[]): ExploreBundleResult[] {\n return bundles.map((bundle) => ({\n ...bundle,\n files: fromPairs(sortBy(toPairs(bundle.files), 0)),\n }));\n}\n\nfunction getExploreResult(\n results: (ExploreBundleResult | ExploreErrorResult)[],\n options: ExploreOptions\n): ExploreResult {\n const [bundles, errors] = partition(\n results,\n (result): result is ExploreBundleResult => 'files' in result\n );\n\n let sortedBundles = sortBy(bundles, (bundle) => bundle.bundleName);\n\n if (options.sort) {\n sortedBundles = sortFilenames(sortedBundles);\n }\n\n errors.push(...getPostExploreErrors(bundles));\n\n return {\n bundles: sortedBundles,\n errors,\n ...(bundles.length > 0 && { output: formatOutput(sortedBundles, options) }),\n };\n}\n\nfunction getPostExploreErrors(exploreBundleResults: ExploreBundleResult[]): ExploreErrorResult[] {\n const errors: ExploreErrorResult[] = [];\n\n const isSingleBundle = exploreBundleResults.length === 1;\n\n for (const result of exploreBundleResults) {\n const { bundleName, files, totalBytes } = result;\n\n // Check if source map contains only one file - this make result useless when exploring single bundle\n if (isSingleBundle) {\n const filenames = Object.keys(files).filter(\n (filename) => !SPECIAL_FILENAMES.includes(filename)\n );\n\n if (filenames.length === 1) {\n errors.push({\n bundleName,\n isWarning: true,\n code: 'OneSourceSourceMap',\n message: getErrorMessage({ code: 'OneSourceSourceMap', filename: filenames[0] }),\n });\n }\n }\n\n if (files[UNMAPPED_KEY] !== undefined) {\n const { size: unmappedBytes } = files[UNMAPPED_KEY];\n\n if (unmappedBytes) {\n errors.push({\n bundleName,\n isWarning: true,\n code: 'UnmappedBytes',\n message: getErrorMessage({ code: 'UnmappedBytes', unmappedBytes, totalBytes }),\n });\n }\n }\n }\n\n return errors;\n}\n"]}
|