source-map-explorer 2.5.0 → 2.5.1
Sign up to get free protection for your applications and to get access to all the features.
- package/bin/cli.js +3 -1
- package/bin/cli.js.map +1 -1
- package/lib/html.js +6 -5
- package/lib/html.js.map +1 -1
- package/package.json +27 -27
package/bin/cli.js
CHANGED
@@ -183,7 +183,9 @@ async function writeHtmlToTempFile(html) {
|
|
183
183
|
const childProcess = await open_1.default(tempFile);
|
184
184
|
if (childProcess.stderr) {
|
185
185
|
childProcess.stderr.once('data', (error) => {
|
186
|
-
|
186
|
+
if (error.toString().trim() !== '#< CLIXML') {
|
187
|
+
logError({ code: 'CannotOpenTempFile', tempFile, error });
|
188
|
+
}
|
187
189
|
});
|
188
190
|
}
|
189
191
|
} catch (error) {
|
package/bin/cli.js.map
CHANGED
@@ -1 +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"]}
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli/cli.ts"],"names":[],"mappings":";;;;;;;AAEA,kDAA0B;AAC1B,4CAAoB;AACpB,gDAAwB;AACxB,gDAAwB;AACxB,kDAA0B;AAC1B,mCAA2C;AAE3C,oCAAqC;AACrC,gDAA6D;AAsB7D,SAAS,cAAc;IACrB,MAAM,IAAI,GAAG,eAAK;SACf,MAAM,EAAE;SACR,UAAU,CAAC,qBAAqB,CAAC;SACjC,KAAK,CAAC,oDAAoD,CAAC;SAC3D,KAAK,CAAC,QAAQ,CAAC;SACf,KAAK,CACJ,0SAA0S,CAC3S;SACA,OAAO,CAAC,4BAA4B,EAAE,gBAAgB,CAAC;SACvD,OAAO,CAAC,cAAc,EAAE,uCAAuC,CAAC;SAChE,OAAO,CAAC,gBAAgB,EAAE,2CAA2C,CAAC;SACtE,OAAO,CAAC,oBAAoB,EAAE,4CAA4C,CAAC;SAC3E,OAAO,CAAC,iCAAiC,EAAE,6CAA6C,CAAC;SACzF,aAAa,CAAC,CAAC,EAAE,wCAAwC,CAAC;SAC1D,OAAO,CAAC;QACP,IAAI,EAAE;YACJ,IAAI,EAAE,QAAQ;YACd,WAAW,EACT,yFAAyF;YAC3F,SAAS,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC;SAC3B;QACD,GAAG,EAAE;YACH,IAAI,EAAE,QAAQ;YACd,WAAW,EACT,wFAAwF;YAC1F,SAAS,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC;SAC5B;QACD,IAAI,EAAE;YACJ,IAAI,EAAE,QAAQ;YACd,WAAW,EACT,uHAAuH;YACzH,SAAS,EAAE,CAAC,MAAM,EAAE,KAAK,CAAC;SAC3B;QAED,aAAa,EAAE;YACb,KAAK,EAAE,GAAG;YACV,IAAI,EAAE,SAAS;YACf,WAAW,EACT,oGAAoG;SACvG;QAED,oBAAoB,EAAE;YACpB,IAAI,EAAE,SAAS;YACf,WAAW,EAAE,6CAA6C;SAC3D;QAED,SAAS,EAAE;YACT,IAAI,EAAE,SAAS;YACf,WAAW,EACT,uJAAuJ;SAC1J;QAED,OAAO,EAAE;YACP,IAAI,EAAE,QAAQ;YACd,KAAK,EAAE,IAAI;YACX,WAAW,EACT,mLAAmL;YACrL,OAAO,EAAE,MAAM;SAChB;QACD,IAAI,EAAE;YACJ,IAAI,EAAE,QAAQ;YACd,KAAK,EAAE,IAAI;YACX,WAAW,EAAE,gBAAgB;YAC7B,OAAO,EAAE,SAAS;SACnB;QAED,kBAAkB,EAAE;YAClB,IAAI,EAAE,SAAS;YACf,WAAW,EAAE,6CAA6C;SAC3D;QAED,QAAQ,EAAE;YACR,IAAI,EAAE,QAAQ;YACd,SAAS,EAAE,IAAI;YACf,WAAW,EACT,sKAAsK;SACzK;QAED,IAAI,EAAE;YACJ,IAAI,EAAE,SAAS;YACf,WAAW,EAAE,mDAAmD;YAChE,SAAS,EAAE,CAAC,aAAa,CAAC;SAC3B;QAED,IAAI,EAAE;YACJ,IAAI,EAAE,SAAS;YACf,WAAW,EAAE,gBAAgB;SAC9B;KACF,CAAC;SACD,KAAK,CAAC,CAAC,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,EAAE,SAAS,CAAC;SACzC,KAAK,CAAC,CAAC,SAAS,EAAE,MAAM,CAAC,EAAE,UAAU,CAAC;SACtC,IAAI,CAAC,GAAG,CAAC;SACT,KAAK,CAAC,GAAG,EAAE,MAAM,CAAC;SAClB,cAAc,CAAC,KAAK,EAAE,sCAAsC,CAAC;SAC7D,IAAI,CAAC,IAAI,CAAC;SACV,mBAAmB,CAAC;QACnB,kBAAkB,EAAE,KAAK;KAC1B,CAAC;SACD,KAAK,CAAC,CAAC,IAAI,EAAE,EAAE;QACd,IAAI,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,KAAK,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE;YACzE,MAAM,IAAI,KAAK,CAAC,kDAAkD,CAAC,CAAC;SACrE;QAED,OAAO,IAAI,CAAC;IACd,CAAC,CAAC;SACD,KAAK,EAAE,CAAC;IAGX,MAAM,UAAU,GAAG,IAAI,CAAC;IAExB,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC,CAAC;IAE5D,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAgB,QAAQ,CAAC,OAA8B,EAAE,KAAa;IACpE,IAAI,CAAC,iBAAQ,CAAC,OAAO,CAAC,EAAE;QACtB,OAAO,GAAG,2BAAe,CAAC,OAAO,CAAC,CAAC;KACpC;IAED,IAAI,KAAK,EAAE;QACT,OAAO,CAAC,KAAK,CAAC,eAAK,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,KAAK,CAAC,CAAC;KAC1C;SAAM;QACL,OAAO,CAAC,KAAK,CAAC,eAAK,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC;KACnC;AACH,CAAC;AAVD,4BAUC;AAED,SAAgB,OAAO,CAAC,OAAe;IACrC,OAAO,CAAC,IAAI,CAAC,eAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC;AACtC,CAAC;AAFD,0BAEC;AAED,SAAgB,OAAO,CAAC,OAAe;IACrC,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;AACpC,CAAC;AAFD,0BAEC;AAKD,SAAS,iBAAiB,CAAC,IAAe;IACxC,MAAM,EACJ,IAAI,EACJ,GAAG,EACH,IAAI,EACJ,OAAO,EAAE,YAAY,EACrB,IAAI,EAAE,SAAS,EACf,UAAU,EACV,gBAAgB,EAAE,uBAAuB,EACzC,MAAM,EACN,cAAc,EACd,QAAQ,EACR,IAAI,EACJ,IAAI,GACL,GAAG,IAAI,CAAC;IAET,IAAI,UAAkC,CAAC;IAEvC,IAAI,YAAY,IAAI,SAAS,EAAE;QAC7B,UAAU,GAAG,YAAY,CAAC,MAAM,CAAa,CAAC,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE;YACnE,MAAM,CAAC,IAAI,CAAC,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC;YAEhC,OAAO,MAAM,CAAC;QAChB,CAAC,EAAE,EAAE,CAAC,CAAC;KACR;IAED,OAAO;QACL,MAAM,EAAE;YAEN,MAAM,EAAE,iBAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,iBAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM;YAChE,QAAQ,EAAE,IAAI,IAAI,GAAG,IAAI,IAAI;SAC9B;QACD,UAAU;QACV,UAAU;QACV,uBAAuB;QACvB,MAAM;QACN,cAAc;QACd,QAAQ;QACR,IAAI;QACJ,IAAI;KACL,CAAC;AACJ,CAAC;AAKD,KAAK,UAAU,mBAAmB,CAAC,IAAa;IAC9C,IAAI,CAAC,IAAI,EAAE;QACT,OAAO;KACR;IAED,IAAI;QACF,MAAM,QAAQ,GAAG,cAAI,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC;QAEvE,YAAE,CAAC,aAAa,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;QAEjC,MAAM,YAAY,GAAG,MAAM,cAAI,CAAC,QAAQ,CAAC,CAAC;QAE1C,IAAI,YAAY,CAAC,MAAM,EAAE;YAEvB,YAAY,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,KAAa,EAAE,EAAE;gBAEjD,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,KAAK,WAAW,EAAE;oBAC3C,QAAQ,CAAC,EAAE,IAAI,EAAE,oBAAoB,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC;iBAC3D;YACH,CAAC,CAAC,CAAC;SACJ;KACF;IAAC,OAAO,KAAK,EAAE;QACd,MAAM,IAAI,oBAAQ,CAAC,EAAE,IAAI,EAAE,sBAAsB,EAAE,EAAE,KAAK,CAAC,CAAC;KAC7D;AACH,CAAC;AAED,SAAS,YAAY,CAAC,EAAE,MAAM,EAAiB;IAC7C,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE;QACvB,OAAO;KACR;IAGD,MAAM,aAAa,GAAG,gBAAO,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;IAEpD,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,UAAU,EAAE,MAAM,CAAC,EAAE,EAAE;QAC7D,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;QAE1B,MAAM,aAAa,GAAG,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC;QAExC,MAAM,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE;YAC9B,MAAM,OAAO,GAAG,GAAG,aAAa,CAAC,CAAC,CAAC,GAAG,KAAK,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,GAAG,KAAK,CAAC,OAAO,EAAE,CAAC;YAE3E,IAAI,KAAK,CAAC,SAAS,EAAE;gBACnB,OAAO,CAAC,OAAO,CAAC,CAAC;aAClB;iBAAM;gBACL,QAAQ,CAAC,OAAO,CAAC,CAAC;aACnB;QACH,CAAC,CAAC,CAAC;QAEH,OAAO,CAAC,QAAQ,EAAE,CAAC;IACrB,CAAC,CAAC,CAAC;AACL,CAAC;AAED,IAAI,OAAO,CAAC,IAAI,KAAK,MAAM,EAAE;IAC3B,MAAM,IAAI,GAAG,cAAc,EAAE,CAAC;IAE9B,MAAM,uBAAuB,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,iBAAQ,CAAC,CAAC;IAEhF,MAAM,OAAO,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC;IAExC,aAAO,CAAC,IAAI,CAAC,CAAC,EAAE,OAAO,CAAC;SACrB,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE;QACf,IAAI,uBAAuB,IAAI,OAAO,CAAC,MAAM,EAAE;YAC7C,MAAM,QAAQ,GAAG,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC;YAEzC,IAAI,QAAQ,EAAE;gBACZ,OAAO,CAAC,mBAAmB,QAAQ,EAAE,CAAC,CAAC;gBACvC,YAAY,CAAC,MAAM,CAAC,CAAC;aACtB;iBAAM;gBACL,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;aAC5B;SACF;aAAM;YACL,mBAAmB,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE;gBAC3C,YAAY,CAAC,MAAM,CAAC,CAAC;YACvB,CAAC,CAAC,CAAC;SACJ;IACH,CAAC,CAAC;SACD,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;QACf,IAAI,KAAK,CAAC,MAAM,EAAE;YAChB,YAAY,CAAC,KAAK,CAAC,CAAC;SACrB;aAAM;YACL,QAAQ,CAAC,mBAAmB,EAAE,KAAK,CAAC,CAAC;SACtC;QAED,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;IACvB,CAAC,CAAC,CAAC;CACN","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 // TODO: Figure out why `#< CLIXML` ends up in stderr. Maybe we should simply ignore it\n if (error.toString().trim() !== '#< CLIXML') {\n logError({ code: 'CannotOpenTempFile', tempFile, error });\n }\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/lib/html.js
CHANGED
@@ -85,15 +85,16 @@ exports.makeMergedTreeDataMap = makeMergedTreeDataMap;
|
|
85
85
|
function getNodePath(parts, depthIndex) {
|
86
86
|
return parts.slice(0, depthIndex + 1).join('/');
|
87
87
|
}
|
88
|
-
const
|
89
|
-
const
|
88
|
+
const WEBPACK_4_FILENAME_PREFIX = 'webpack:///';
|
89
|
+
const WEBPACK_5_FILENAME_PREFIX = 'webpack://';
|
90
|
+
const WEBPACK_4_FILENAME_PREFIX_LENGTH = WEBPACK_4_FILENAME_PREFIX.length;
|
90
91
|
function splitFilename(file) {
|
91
|
-
const webpackPrefixIndex = file.indexOf(
|
92
|
+
const webpackPrefixIndex = file.indexOf(WEBPACK_4_FILENAME_PREFIX);
|
92
93
|
if (webpackPrefixIndex !== -1) {
|
93
94
|
return [
|
94
95
|
...file.substring(0, webpackPrefixIndex).split('/'),
|
95
|
-
|
96
|
-
...file.substring(webpackPrefixIndex +
|
96
|
+
WEBPACK_4_FILENAME_PREFIX,
|
97
|
+
...file.substring(webpackPrefixIndex + WEBPACK_4_FILENAME_PREFIX_LENGTH).split('/'),
|
97
98
|
].filter(Boolean);
|
98
99
|
}
|
99
100
|
return file.split('/');
|
package/lib/html.js.map
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"html.js","sourceRoot":"","sources":["../src/lib/html.ts"],"names":[],"mappings":"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","sourcesContent":["import btoa from 'btoa';\nimport ejs from 'ejs';\nimport fs from 'fs';\nimport path from 'path';\nimport escapeHtml from 'escape-html';\nimport { cloneDeep } from 'lodash';\n\nimport { formatBytes, getCommonPathPrefix, getFileContent, formatPercent } from './helpers';\nimport { getColorByPercent } from './coverage';\n\nimport type { ExploreOptions, ExploreBundleResult, FileData, FileDataMap } from './types';\n\nconst COMBINED_BUNDLE_NAME = '[combined]';\n\n/**\n * Get webtreemap data to update map on bundle select\n */\nfunction getTreeDataMap(exploreResults: ExploreBundleResult[]): { [id: number]: WebTreeData } {\n let treeData = exploreResults.map<WebTreeData>((data) => ({\n name: data.bundleName,\n data: getWebTreeMapData(data.files),\n }));\n\n if (treeData.length > 1) {\n treeData = [makeMergedTreeDataMap(cloneDeep(treeData)), ...treeData];\n }\n\n for (const webTreeData of treeData) {\n addSizeToTitle(webTreeData.data, webTreeData.data.data['$area']);\n }\n\n return { ...treeData };\n}\n\n/**\n * Generate HTML file content for specified files\n */\nexport function generateHtml(\n exploreResults: ExploreBundleResult[],\n options: ExploreOptions\n): string {\n const assets = {\n webtreemapJs: btoa(fs.readFileSync(require.resolve('./vendor/webtreemap.js'))),\n webtreemapCss: btoa(fs.readFileSync(require.resolve('./vendor/webtreemap.css'))),\n };\n\n const treeDataMap = getTreeDataMap(exploreResults);\n\n // Get bundles info to generate select element\n const bundles = exploreResults.map((data) => ({\n name: data.bundleName,\n size: formatBytes(data.totalBytes),\n }));\n\n // Create a combined bundle if applicable\n if (exploreResults.length > 1) {\n bundles.unshift({\n name: COMBINED_BUNDLE_NAME,\n size: formatBytes(exploreResults.reduce((total, result) => total + result.totalBytes, 0)),\n });\n }\n\n const template = getFileContent(path.join(__dirname, 'tree-viz.ejs'));\n\n return ejs.render(template, {\n options,\n bundles,\n treeDataMap,\n webtreemapJs: assets.webtreemapJs,\n webtreemapCss: assets.webtreemapCss,\n });\n}\n\n/**\n * Create a combined tree data where each of the inputs is a separate node under the root\n */\nexport function makeMergedTreeDataMap(treeData: WebTreeData[]): WebTreeData {\n const data: WebTreeMapNode = newNode('/');\n\n data.children = [];\n\n for (const result of treeData) {\n const childTree = result.data;\n\n childTree.name = result.name;\n\n data.data['$area'] += childTree.data['$area'];\n data.children.push(childTree);\n }\n\n const commonPrefix = getCommonPathPrefix(data.children.map((node) => node.name));\n const commonPrefixLength = commonPrefix.length;\n\n if (commonPrefixLength > 0) {\n for (const node of data.children) {\n node.name = node.name.slice(commonPrefixLength);\n }\n }\n\n return {\n name: COMBINED_BUNDLE_NAME,\n data,\n };\n}\n\ntype TreeNodesMap = { [source: string]: string[] };\n\nfunction getNodePath(parts: string[], depthIndex: number): string {\n return parts.slice(0, depthIndex + 1).join('/');\n}\n\nconst WEBPACK_FILENAME_PREFIX = 'webpack:///';\nconst WEBPACK_FILENAME_PREFIX_LENGTH = WEBPACK_FILENAME_PREFIX.length;\n\nfunction splitFilename(file: string): string[] {\n const webpackPrefixIndex = file.indexOf(WEBPACK_FILENAME_PREFIX);\n\n // Treat webpack file prefix as a filename part\n if (webpackPrefixIndex !== -1) {\n return [\n ...file.substring(0, webpackPrefixIndex).split('/'),\n WEBPACK_FILENAME_PREFIX,\n ...file.substring(webpackPrefixIndex + WEBPACK_FILENAME_PREFIX_LENGTH).split('/'),\n ].filter(Boolean);\n }\n\n return file.split('/');\n}\n\nfunction getTreeNodesMap(fileDataMap: FileDataMap): TreeNodesMap {\n let partsSourceTuples = Object.keys(fileDataMap).map<[string[], string]>((file) => [\n splitFilename(file),\n file,\n ]);\n\n const maxDepth = Math.max(...partsSourceTuples.map(([parts]) => parts.length));\n\n for (let depthIndex = 0; depthIndex < maxDepth; depthIndex += 1) {\n partsSourceTuples = partsSourceTuples.map(([parts, file], currentNodeIndex) => {\n if (parts[depthIndex]) {\n const nodePath = getNodePath(parts, depthIndex);\n\n const hasSameRootPaths = partsSourceTuples.some(([pathParts], index) => {\n if (index === currentNodeIndex) {\n return false;\n }\n if (!pathParts[depthIndex]) {\n return false;\n }\n\n return getNodePath(pathParts, depthIndex) === nodePath;\n });\n\n if (!hasSameRootPaths) {\n // Collapse non-contributing path parts\n return [[...parts.slice(0, depthIndex), parts.slice(depthIndex).join('/')], file];\n }\n }\n\n return [parts, file];\n });\n }\n\n return partsSourceTuples.reduce((result, [parts, file]) => {\n result[file] = parts;\n\n return result;\n }, {});\n}\n\ninterface WebTreeMapNode {\n name: string;\n data: {\n $area: number;\n coveredSize?: number;\n backgroundColor?: string;\n };\n children?: WebTreeMapNode[];\n}\n\nexport interface WebTreeData {\n name: string;\n data: WebTreeMapNode;\n}\n\n/**\n * Convert file size map to webtreemap data\n */\nexport function getWebTreeMapData(files: FileDataMap): WebTreeMapNode {\n const treeNodesMap = getTreeNodesMap(files);\n const treeData = newNode('/');\n\n for (const source in files) {\n addNode(treeNodesMap[source], files[source], treeData);\n }\n\n return treeData;\n}\n\nfunction newNode(name: string): WebTreeMapNode {\n return {\n name: escapeHtml(name),\n data: {\n $area: 0,\n },\n };\n}\n\nfunction setNodeData(node: WebTreeMapNode, fileData: FileData): void {\n const size = node.data['$area'] + fileData.size;\n\n if (fileData.coveredSize !== undefined) {\n const coveredSize = (node.data.coveredSize || 0) + fileData.coveredSize;\n\n node.data.coveredSize = coveredSize;\n node.data.backgroundColor = getColorByPercent(coveredSize / size);\n }\n\n node.data['$area'] = size;\n}\n\nfunction addNode(parts: string[], fileData: FileData, treeData: WebTreeMapNode): void {\n // No need to create nodes with zero size (e.g. '[unmapped]')\n if (fileData.size === 0) {\n return;\n }\n\n let node = treeData;\n\n setNodeData(node, fileData);\n\n parts.forEach((part) => {\n if (!node.children) {\n node.children = [];\n }\n\n let child = node.children.find((child) => child.name === part);\n\n if (!child) {\n child = newNode(part);\n node.children.push(child);\n }\n\n node = child;\n\n setNodeData(child, fileData);\n });\n}\n\nfunction addSizeToTitle(node: WebTreeMapNode, total: number): void {\n const { $area: size, coveredSize } = node.data;\n\n const titleParts = [node.name, formatBytes(size), `${formatPercent(size, total, 1)}%`];\n\n // Add coverage label to leaf nodes only\n if (coveredSize !== undefined && node.children === undefined) {\n titleParts.push(`Coverage: ${formatPercent(coveredSize, size, 1)}%`);\n }\n\n node.name = titleParts.join(' • ');\n\n if (node.children) {\n node.children.forEach((child) => {\n addSizeToTitle(child, total);\n });\n }\n}\n"]}
|
1
|
+
{"version":3,"file":"html.js","sourceRoot":"","sources":["../src/lib/html.ts"],"names":[],"mappings":"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","sourcesContent":["import btoa from 'btoa';\nimport ejs from 'ejs';\nimport fs from 'fs';\nimport path from 'path';\nimport escapeHtml from 'escape-html';\nimport { cloneDeep } from 'lodash';\n\nimport { formatBytes, getCommonPathPrefix, getFileContent, formatPercent } from './helpers';\nimport { getColorByPercent } from './coverage';\n\nimport type { ExploreOptions, ExploreBundleResult, FileData, FileDataMap } from './types';\n\nconst COMBINED_BUNDLE_NAME = '[combined]';\n\n/**\n * Get webtreemap data to update map on bundle select\n */\nfunction getTreeDataMap(exploreResults: ExploreBundleResult[]): { [id: number]: WebTreeData } {\n let treeData = exploreResults.map<WebTreeData>((data) => ({\n name: data.bundleName,\n data: getWebTreeMapData(data.files),\n }));\n\n if (treeData.length > 1) {\n treeData = [makeMergedTreeDataMap(cloneDeep(treeData)), ...treeData];\n }\n\n for (const webTreeData of treeData) {\n addSizeToTitle(webTreeData.data, webTreeData.data.data['$area']);\n }\n\n return { ...treeData };\n}\n\n/**\n * Generate HTML file content for specified files\n */\nexport function generateHtml(\n exploreResults: ExploreBundleResult[],\n options: ExploreOptions\n): string {\n const assets = {\n webtreemapJs: btoa(fs.readFileSync(require.resolve('./vendor/webtreemap.js'))),\n webtreemapCss: btoa(fs.readFileSync(require.resolve('./vendor/webtreemap.css'))),\n };\n\n const treeDataMap = getTreeDataMap(exploreResults);\n\n // Get bundles info to generate select element\n const bundles = exploreResults.map((data) => ({\n name: data.bundleName,\n size: formatBytes(data.totalBytes),\n }));\n\n // Create a combined bundle if applicable\n if (exploreResults.length > 1) {\n bundles.unshift({\n name: COMBINED_BUNDLE_NAME,\n size: formatBytes(exploreResults.reduce((total, result) => total + result.totalBytes, 0)),\n });\n }\n\n const template = getFileContent(path.join(__dirname, 'tree-viz.ejs'));\n\n return ejs.render(template, {\n options,\n bundles,\n treeDataMap,\n webtreemapJs: assets.webtreemapJs,\n webtreemapCss: assets.webtreemapCss,\n });\n}\n\n/**\n * Create a combined tree data where each of the inputs is a separate node under the root\n */\nexport function makeMergedTreeDataMap(treeData: WebTreeData[]): WebTreeData {\n const data: WebTreeMapNode = newNode('/');\n\n data.children = [];\n\n for (const result of treeData) {\n const childTree = result.data;\n\n childTree.name = result.name;\n\n data.data['$area'] += childTree.data['$area'];\n data.children.push(childTree);\n }\n\n const commonPrefix = getCommonPathPrefix(data.children.map((node) => node.name));\n const commonPrefixLength = commonPrefix.length;\n\n if (commonPrefixLength > 0) {\n for (const node of data.children) {\n node.name = node.name.slice(commonPrefixLength);\n }\n }\n\n return {\n name: COMBINED_BUNDLE_NAME,\n data,\n };\n}\n\ntype TreeNodesMap = { [source: string]: string[] };\n\nfunction getNodePath(parts: string[], depthIndex: number): string {\n return parts.slice(0, depthIndex + 1).join('/');\n}\n\nconst WEBPACK_4_FILENAME_PREFIX = 'webpack:///';\nconst WEBPACK_5_FILENAME_PREFIX = 'webpack://';\nconst WEBPACK_4_FILENAME_PREFIX_LENGTH = WEBPACK_4_FILENAME_PREFIX.length;\n\nfunction splitFilename(file: string): string[] {\n const webpackPrefixIndex = file.indexOf(WEBPACK_4_FILENAME_PREFIX);\n\n // Treat webpack file prefix as a filename part\n if (webpackPrefixIndex !== -1) {\n return [\n ...file.substring(0, webpackPrefixIndex).split('/'),\n WEBPACK_4_FILENAME_PREFIX,\n ...file.substring(webpackPrefixIndex + WEBPACK_4_FILENAME_PREFIX_LENGTH).split('/'),\n ].filter(Boolean);\n }\n\n return file.split('/');\n}\n\nfunction getTreeNodesMap(fileDataMap: FileDataMap): TreeNodesMap {\n let partsSourceTuples = Object.keys(fileDataMap).map<[string[], string]>((file) => [\n splitFilename(file),\n file,\n ]);\n\n const maxDepth = Math.max(...partsSourceTuples.map(([parts]) => parts.length));\n\n for (let depthIndex = 0; depthIndex < maxDepth; depthIndex += 1) {\n partsSourceTuples = partsSourceTuples.map(([parts, file], currentNodeIndex) => {\n if (parts[depthIndex]) {\n const nodePath = getNodePath(parts, depthIndex);\n\n const hasSameRootPaths = partsSourceTuples.some(([pathParts], index) => {\n if (index === currentNodeIndex) {\n return false;\n }\n if (!pathParts[depthIndex]) {\n return false;\n }\n\n return getNodePath(pathParts, depthIndex) === nodePath;\n });\n\n if (!hasSameRootPaths) {\n // Collapse non-contributing path parts\n return [[...parts.slice(0, depthIndex), parts.slice(depthIndex).join('/')], file];\n }\n }\n\n return [parts, file];\n });\n }\n\n return partsSourceTuples.reduce((result, [parts, file]) => {\n result[file] = parts;\n\n return result;\n }, {});\n}\n\ninterface WebTreeMapNode {\n name: string;\n data: {\n $area: number;\n coveredSize?: number;\n backgroundColor?: string;\n };\n children?: WebTreeMapNode[];\n}\n\nexport interface WebTreeData {\n name: string;\n data: WebTreeMapNode;\n}\n\n/**\n * Convert file size map to webtreemap data\n */\nexport function getWebTreeMapData(files: FileDataMap): WebTreeMapNode {\n const treeNodesMap = getTreeNodesMap(files);\n const treeData = newNode('/');\n\n for (const source in files) {\n addNode(treeNodesMap[source], files[source], treeData);\n }\n\n return treeData;\n}\n\nfunction newNode(name: string): WebTreeMapNode {\n return {\n name: escapeHtml(name),\n data: {\n $area: 0,\n },\n };\n}\n\nfunction setNodeData(node: WebTreeMapNode, fileData: FileData): void {\n const size = node.data['$area'] + fileData.size;\n\n if (fileData.coveredSize !== undefined) {\n const coveredSize = (node.data.coveredSize || 0) + fileData.coveredSize;\n\n node.data.coveredSize = coveredSize;\n node.data.backgroundColor = getColorByPercent(coveredSize / size);\n }\n\n node.data['$area'] = size;\n}\n\nfunction addNode(parts: string[], fileData: FileData, treeData: WebTreeMapNode): void {\n // No need to create nodes with zero size (e.g. '[unmapped]')\n if (fileData.size === 0) {\n return;\n }\n\n let node = treeData;\n\n setNodeData(node, fileData);\n\n parts.forEach((part) => {\n if (!node.children) {\n node.children = [];\n }\n\n let child = node.children.find((child) => child.name === part);\n\n if (!child) {\n child = newNode(part);\n node.children.push(child);\n }\n\n node = child;\n\n setNodeData(child, fileData);\n });\n}\n\nfunction addSizeToTitle(node: WebTreeMapNode, total: number): void {\n const { $area: size, coveredSize } = node.data;\n\n const titleParts = [node.name, formatBytes(size), `${formatPercent(size, total, 1)}%`];\n\n // Add coverage label to leaf nodes only\n if (coveredSize !== undefined && node.children === undefined) {\n titleParts.push(`Coverage: ${formatPercent(coveredSize, size, 1)}%`);\n }\n\n node.name = titleParts.join(' • ');\n\n if (node.children) {\n node.children.forEach((child) => {\n addSizeToTitle(child, total);\n });\n }\n}\n"]}
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "source-map-explorer",
|
3
|
-
"version": "2.5.
|
3
|
+
"version": "2.5.1",
|
4
4
|
"description": "Analyze and debug space usage through source maps",
|
5
5
|
"main": "lib/index.js",
|
6
6
|
"bin": {
|
@@ -75,63 +75,63 @@
|
|
75
75
|
"ejs": "^3.1.5",
|
76
76
|
"escape-html": "^1.0.3",
|
77
77
|
"glob": "^7.1.6",
|
78
|
-
"gzip-size": "^
|
78
|
+
"gzip-size": "^6.0.0",
|
79
79
|
"lodash": "^4.17.20",
|
80
|
-
"open": "^7.
|
80
|
+
"open": "^7.3.0",
|
81
81
|
"source-map": "^0.7.3",
|
82
|
-
"temp": "^0.9.
|
83
|
-
"yargs": "^
|
82
|
+
"temp": "^0.9.4",
|
83
|
+
"yargs": "^16.1.1"
|
84
84
|
},
|
85
85
|
"devDependencies": {
|
86
|
-
"@babel/core": "^7.
|
87
|
-
"@babel/preset-env": "^7.
|
86
|
+
"@babel/core": "^7.12.9",
|
87
|
+
"@babel/preset-env": "^7.12.7",
|
88
88
|
"@istanbuljs/nyc-config-typescript": "^1.0.1",
|
89
89
|
"@smpx/snap-shot-it": "^6.6.1",
|
90
90
|
"@types/browserify": "^12.0.36",
|
91
91
|
"@types/btoa": "^1.2.3",
|
92
|
-
"@types/chai": "^4.2.
|
92
|
+
"@types/chai": "^4.2.14",
|
93
93
|
"@types/chai-as-promised": "^7.1.3",
|
94
94
|
"@types/concat-stream": "^1.6.0",
|
95
95
|
"@types/convert-source-map": "^1.5.1",
|
96
96
|
"@types/cross-spawn": "^6.0.2",
|
97
|
-
"@types/ejs": "^3.0.
|
97
|
+
"@types/ejs": "^3.0.5",
|
98
98
|
"@types/escape-html": "1.0.0",
|
99
99
|
"@types/glob": "^7.1.3",
|
100
|
-
"@types/lodash": "^4.14.
|
101
|
-
"@types/mocha": "^8.0.
|
100
|
+
"@types/lodash": "^4.14.165",
|
101
|
+
"@types/mocha": "^8.0.4",
|
102
102
|
"@types/node": "^14.x",
|
103
103
|
"@types/rimraf": "^3.0.0",
|
104
104
|
"@types/temp": "^0.8.34",
|
105
|
-
"@types/yargs": "^15.0.
|
106
|
-
"@typescript-eslint/eslint-plugin": "^
|
107
|
-
"@typescript-eslint/parser": "^
|
105
|
+
"@types/yargs": "^15.0.10",
|
106
|
+
"@typescript-eslint/eslint-plugin": "^4.8.2",
|
107
|
+
"@typescript-eslint/parser": "^4.8.2",
|
108
108
|
"babelify": "^10.0.0",
|
109
|
-
"browserify": "^
|
109
|
+
"browserify": "^17.0.0",
|
110
110
|
"chai": "^4.2.0",
|
111
111
|
"chai-as-promised": "^7.1.1",
|
112
112
|
"chokidar-cli": "^2.1.0",
|
113
113
|
"concat-stream": "^2.0.0",
|
114
|
-
"copyfiles": "^2.
|
114
|
+
"copyfiles": "^2.4.0",
|
115
115
|
"coveralls": "^3.1.0",
|
116
116
|
"cross-env": "^7.0.2",
|
117
117
|
"cross-spawn": "^7.0.3",
|
118
|
-
"eslint": "^7.
|
119
|
-
"eslint-config-prettier": "^6.
|
118
|
+
"eslint": "^7.14.0",
|
119
|
+
"eslint-config-prettier": "^6.15.0",
|
120
120
|
"eslint-plugin-prettier": "^3.1.4",
|
121
121
|
"generate-source-map": "0.0.5",
|
122
|
-
"husky": "^4.
|
123
|
-
"lint-staged": "^10.2
|
124
|
-
"mocha": "^8.
|
122
|
+
"husky": "^4.3.0",
|
123
|
+
"lint-staged": "^10.5.2",
|
124
|
+
"mocha": "^8.2.1",
|
125
125
|
"npm-run-all": "^4.1.5",
|
126
126
|
"nyc": "^15.1.0",
|
127
|
-
"prettier": "^2.0
|
127
|
+
"prettier": "^2.2.0",
|
128
128
|
"rewiremock": "^3.14.3",
|
129
129
|
"rimraf": "^3.0.2",
|
130
130
|
"source-map-support": "^0.5.19",
|
131
|
-
"terser": "^5.
|
132
|
-
"terser-webpack-plugin": "^
|
133
|
-
"ts-node": "^
|
134
|
-
"typescript": "^
|
135
|
-
"webpack": "^
|
131
|
+
"terser": "^5.5.0",
|
132
|
+
"terser-webpack-plugin": "^5.0.3",
|
133
|
+
"ts-node": "^9.0.0",
|
134
|
+
"typescript": "^4.1.2",
|
135
|
+
"webpack": "^5.6.0"
|
136
136
|
}
|
137
137
|
}
|