source-map-explorer 2.5.1 → 2.5.2

Sign up to get free protection for your applications and to get access to all the features.
package/bin/cli.js CHANGED
@@ -114,8 +114,10 @@ function parseArguments() {
114
114
  })
115
115
  .parse();
116
116
  const quoteRegex = /'/g;
117
- argv._ = argv._.map((path) => path.replace(quoteRegex, ''));
118
- return argv;
117
+ return {
118
+ ...argv,
119
+ _: argv._.filter((arg) => typeof arg === 'string').map((path) => path.replace(quoteRegex, '')),
120
+ };
119
121
  }
120
122
  function logError(message, error) {
121
123
  if (!lodash_1.isString(message)) {
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 // 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"]}
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 return {\n ...argv,\n _: argv._.filter((arg): arg is string => typeof arg === 'string').map((path) =>\n path.replace(quoteRegex, '')\n ),\n };\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,19 +85,19 @@ exports.makeMergedTreeDataMap = makeMergedTreeDataMap;
85
85
  function getNodePath(parts, depthIndex) {
86
86
  return parts.slice(0, depthIndex + 1).join('/');
87
87
  }
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;
88
+ const WEBPACK_FILENAME_PREFIX = 'webpack:///';
89
+ const WEBPACK_FILENAME_PREFIX_LENGTH = WEBPACK_FILENAME_PREFIX.length;
90
+ const PATH_SEPARATOR_REGEX = /[\\/]/;
91
91
  function splitFilename(file) {
92
- const webpackPrefixIndex = file.indexOf(WEBPACK_4_FILENAME_PREFIX);
92
+ const webpackPrefixIndex = file.indexOf(WEBPACK_FILENAME_PREFIX);
93
93
  if (webpackPrefixIndex !== -1) {
94
94
  return [
95
95
  ...file.substring(0, webpackPrefixIndex).split('/'),
96
- WEBPACK_4_FILENAME_PREFIX,
97
- ...file.substring(webpackPrefixIndex + WEBPACK_4_FILENAME_PREFIX_LENGTH).split('/'),
96
+ WEBPACK_FILENAME_PREFIX,
97
+ ...file.substring(webpackPrefixIndex + WEBPACK_FILENAME_PREFIX_LENGTH).split('/'),
98
98
  ].filter(Boolean);
99
99
  }
100
- return file.split('/');
100
+ return file.split(PATH_SEPARATOR_REGEX);
101
101
  }
102
102
  function getTreeNodesMap(fileDataMap) {
103
103
  let partsSourceTuples = Object.keys(fileDataMap).map((file) => [splitFilename(file), file]);
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_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"]}
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;\nconst PATH_SEPARATOR_REGEX = /[\\\\/]/;\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(PATH_SEPARATOR_REGEX);\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/lib/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
  Object.defineProperty(exports, '__esModule', { value: true });
3
- exports.explore = void 0;
3
+ exports.explore = exports.NO_SOURCE_KEY = exports.SOURCE_MAP_COMMENT_KEY = exports.UNMAPPED_KEY = void 0;
4
4
  const api_1 = require('./api');
5
5
  Object.defineProperty(exports, 'explore', {
6
6
  enumerable: true,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "source-map-explorer",
3
- "version": "2.5.1",
3
+ "version": "2.5.2",
4
4
  "description": "Analyze and debug space usage through source maps",
5
5
  "main": "lib/index.js",
6
6
  "bin": {
@@ -77,14 +77,14 @@
77
77
  "glob": "^7.1.6",
78
78
  "gzip-size": "^6.0.0",
79
79
  "lodash": "^4.17.20",
80
- "open": "^7.3.0",
80
+ "open": "^7.3.1",
81
81
  "source-map": "^0.7.3",
82
82
  "temp": "^0.9.4",
83
- "yargs": "^16.1.1"
83
+ "yargs": "^16.2.0"
84
84
  },
85
85
  "devDependencies": {
86
- "@babel/core": "^7.12.9",
87
- "@babel/preset-env": "^7.12.7",
86
+ "@babel/core": "^7.12.10",
87
+ "@babel/preset-env": "^7.12.11",
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",
@@ -97,41 +97,41 @@
97
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.165",
101
- "@types/mocha": "^8.0.4",
100
+ "@types/lodash": "^4.14.167",
101
+ "@types/mocha": "^8.2.0",
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.10",
106
- "@typescript-eslint/eslint-plugin": "^4.8.2",
107
- "@typescript-eslint/parser": "^4.8.2",
105
+ "@types/yargs": "^15.0.12",
106
+ "@typescript-eslint/eslint-plugin": "^4.12.0",
107
+ "@typescript-eslint/parser": "^4.12.0",
108
108
  "babelify": "^10.0.0",
109
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.4.0",
114
+ "copyfiles": "^2.4.1",
115
115
  "coveralls": "^3.1.0",
116
- "cross-env": "^7.0.2",
116
+ "cross-env": "^7.0.3",
117
117
  "cross-spawn": "^7.0.3",
118
- "eslint": "^7.14.0",
119
- "eslint-config-prettier": "^6.15.0",
120
- "eslint-plugin-prettier": "^3.1.4",
118
+ "eslint": "^7.17.0",
119
+ "eslint-config-prettier": "^7.1.0",
120
+ "eslint-plugin-prettier": "^3.3.1",
121
121
  "generate-source-map": "0.0.5",
122
- "husky": "^4.3.0",
123
- "lint-staged": "^10.5.2",
122
+ "husky": "^4.3.7",
123
+ "lint-staged": "^10.5.3",
124
124
  "mocha": "^8.2.1",
125
125
  "npm-run-all": "^4.1.5",
126
126
  "nyc": "^15.1.0",
127
- "prettier": "^2.2.0",
127
+ "prettier": "^2.2.1",
128
128
  "rewiremock": "^3.14.3",
129
129
  "rimraf": "^3.0.2",
130
130
  "source-map-support": "^0.5.19",
131
- "terser": "^5.5.0",
131
+ "terser": "^5.5.1",
132
132
  "terser-webpack-plugin": "^5.0.3",
133
- "ts-node": "^9.0.0",
134
- "typescript": "^4.1.2",
135
- "webpack": "^5.6.0"
133
+ "ts-node": "^9.1.1",
134
+ "typescript": "^4.1.3",
135
+ "webpack": "^5.12.0"
136
136
  }
137
137
  }