Code Monkey home page Code Monkey logo

source-map-explorer's Introduction

Build Status NPM version install size Coverage Status NPM

source-map-explorer

Analyze and debug JavaScript (or Sass or LESS) code bloat through source maps.

The source map explorer determines which file each byte in your minified code came from. It shows you a treemap visualization to help you debug where all the code is coming from. Check out this Chrome Developer video (3:25) for a demo of the tool in action.

Install:

npm install -g source-map-explorer

Use (you can specify filenames or use glob pattern):

source-map-explorer bundle.min.js
source-map-explorer bundle.min.js bundle.min.js.map
source-map-explorer bundle.min.js*
source-map-explorer *.js

This will open up a visualization of how the space is used in your minified bundle:

Here's a demo with a more complex bundle.

Here's another demo where you can see a bug: there are two copies of React in the bundle (perhaps because of out-of-date dependencies).

Requirements

  • Node 10 or later

Options

Default behavior - write HTML to a temp file and open it in your browser

source-map-explorer foo.min.js

Write output in specific formats to stdout

source-map-explorer foo.min.js --html
source-map-explorer foo.min.js --json
source-map-explorer foo.min.js --tsv

Write output in specific formats to a file

source-map-explorer foo.min.js --html result.html
source-map-explorer foo.min.js --json result.json
source-map-explorer foo.min.js --tsv result.tsv
  • --json: output JSON instead of displaying a visualization:

    source-map-explorer foo.min.js --json
    {
      "results": [
        {
          "bundleName": "tests/data/foo.min.js",
          "totalBytes": 718,
          "mappedBytes": 681,
          "unmappedBytes": 1,
          "eolBytes": 1,
          "sourceMapCommentBytes": 35,
          "files": {
            "node_modules/browser-pack/_prelude.js": {
              "size": 480
            },
            "src/bar.js": {
              "size": 104
            },
            "src/foo.js": {
              "size": 97
            },
            "[sourceMappingURL]": {
              "size": 35
            },
            "[unmapped]": {
              "size": 1
            },
            "[EOLs]": {
              "size": 1
            }
          }
        }
      ]
    }
    
  • --tsv: output tab-delimited values instead of displaying a visualization:

    source-map-explorer foo.min.js --tsv
    Source                                  Size
    node_modules/browser-pack/_prelude.js   480
    src/bar.js                              104
    src/foo.js                              97
    [sourceMappingURL]                      35
    [unmapped]                              1
    [EOLs]                                  1
    

    If you just want a list of files, you can do source-map-explorer foo.min.js --tsv | sed 1d | cut -f1.

  • --html: output HTML to stdout. If you want to save the output (e.g. to share), specify filename after --html:

    source-map-explorer foo.min.js --html tree.html
    
  • -m, --only-mapped: exclude "unmapped" bytes from the output. This will result in total counts less than the file size.

  • --exclude-source-map: exclude source map comment size from output. This will result in total counts less than the file size.

  • --replace, --with: The paths in source maps sometimes have artifacts that are difficult to get rid of. These flags let you do simple find & replaces on the paths. For example:

    source-map-explorer foo.min.js --replace 'dist/' --with ''
    

    You can specify these flags multiple times. Be aware that the find/replace is done after eliminating shared prefixes between paths.

    These are regular expressions.

  • --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.

  • --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.

  • --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

  • --gzip: Calculate gzip size. It also sets onlyMapped flag

  • --sort: Sort filenames

Examples

Get help

source-map-explorer -h
Analyze and debug space usage through source maps.
Usage:
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]

Output:
  --json  If filename specified save output as JSON to specified file otherwise output to stdout.  [string]
  --tsv   If filename specified save output as TSV to specified file otherwise output to stdout.  [string]
  --html  If filename specified save output as HTML to specified file otherwise output to stdout rather than opening a browser.  [string]

Replace:
  --replace  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.
  [array]
  --with     See --replace.  [array]

Options:
  --version             Show version number  [boolean]
  --only-mapped, -m     Exclude "unmapped" bytes from the output. This will result in total counts less than the file size  [boolean]
  --exclude-source-map  Exclude source map comment size from output  [boolean]
  --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]
  --no-border-checks    Disable invalid mapping column/line checks.  [boolean]
  --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
[string]
  --gzip                Calculate gzip size. It also sets onlyMapped flag  [boolean]
  --sort                Sort filenames  [boolean]
  -h, --help            Show help  [boolean]

Examples:
  source-map-explorer script.js script.js.map       Explore bundle
  source-map-explorer script.js                     Explore bundle with inline source map
  source-map-explorer dist/js/*.*                   Explore all bundles inside dist/js folder
  source-map-explorer script.js --tsv               Explore and output result as TSV to stdout
  source-map-explorer script.js --json result.json  Explore and save result as JSON to the file

Explore bundle and view result as an interactive map

source-map-explorer script.js script.js.map

Will open an HTML file containing explore result as a tree data map

Result as HTML tree data map

Explore and output result as JSON

source-map-explorer script.js script.js.map --json
{
  "results": [
    {
      "bundleName": "script.js",
      "totalBytes": 718,
      "unmappedBytes": 1,
      "eolBytes": 1,
      "sourceMapCommentBytes": 35,
      "files": {
        "node_modules/browser-pack/_prelude.js": {
          "size": 480
        }
        "src/bar.js": {
          "size": 104
        }
        "src/foo.js": {
          "size": 97
        },
        "[sourceMappingURL]": {
          "size": 35
        }
        "[unmapped]": {
          "size": 1
        }
      }
    }
  ]
}

Explore and output result as TSV

source-map-explorer script1.js script2.js --tsv
Source  Size
node_modules/browser-pack/_prelude.js   480
src/bar.js      104
src/foo.js      97
[sourceMappingURL]      35
[unmapped]      1

[sourceMappingURL]      2308
node_modules/browser-pack/_prelude.js   480
src/bar.js      104
src/foo.js      97
[unmapped]      1

Explore and output result as HTML

source-map-explorer script.js --html
<!doctype html>
<html lang="en">
<head>
...
  selectBundle(selectedBundle);
</script>
<html>

Explore and save result as HTML file

source-map-explorer script.js --html ./sme/result.html

Replace substring in filenames

source-map-explorer script.js --tsv --replace dist node_modules --with gist modules
Source  Size
gist/bar.js     2854
modules/browserify/modules/browser-pack/_prelude.js     463
gist/foo.js     137
[unmapped]      0

Remove [unmapped] from result files

source-map-explorer script.js --tsv --only-mapped
Source  Size
[sourceMappingURL]      2308
node_modules/browser-pack/_prelude.js   480
src/bar.js      104
src/foo.js      97

Remove [sourceMappingURL] from result files

source-map-explorer script.js --tsv --exclude-source-map
Source  Size
node_modules/browser-pack/_prelude.js   480
src/bar.js      104
src/foo.js      97
[unmapped]      1

Do not remove common path prefix

source-map-explorer script.js --tsv --no-root

On error

Errors will be displayed only if no output flags specified

source-map-explore with-unmapped.js no-map-comment.js
no-map-comment.js
  Unable to find a source map.
  See https://github.com/danvk/source-map-explorer/blob/master/README.md#generating-source-maps
with-unmapped.js
  Unable to map 274/1335 bytes (20.52%)

API

explore(bundlesAndFileTokens, [options])

bundlesAndFileTokens:

  • Glob: dist/js/*.*
  • Filename: dist/js/chunk.1.js
  • Bundle: { code: 'dist/js/chunk.1.js', map: 'dist/js/chunk.1.js.map' } or { code: fs.readFileSync('dist/js/chunk.2.js') }
  • Array of globs, filenames and bundles:
    [
      'dist/js/chunk.2.*',
      'dist/js/chunk.1.js', 'dist/js/chunk.1.js.map',
      { code: 'dist/js/chunk.3.js', map: 'dist/js/chunk.3.js.map' }
    ]
    

options:

  • onlyMapped: boolean (default false) - Exclude "unmapped" bytes from the output. This will result in total counts less than the file size
  • excludeSourceMapComment: boolean (default false) - Exclude source map comment size from output. This will result in total counts less than the file size.
  • output: Object - Output options
    • format: string - 'json', 'tsv' or 'html'
    • filename: string - Filename to save output to
  • noRoot: boolean (default false) - See --no-root option above for details
  • noBorderChecks: boolean - Disable invalid mapping column/line checks. See --no-border-checks above.
  • replaceMap: <Object<{ [from: string]: string }>> - Mapping for replacement, see --replace, --with options above for details.
  • 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
  • gzip: boolean - Calculate gzip size. It also sets onlyMapped flag

Example:

import { explore } from 'source-map-explorer'
// or import explore from 'source-map-explorer'

explore('tests/data/foo.min.js', { output: { format: 'html' } }).then()

// Returns
{
  bundles: [{
    bundleName: 'tests/data/foo.min.js',
    totalBytes: 718,
    unmappedBytes: 1,
    mappedBytes: 681,
    eolBytes: 1,
    sourceMapCommentBytes: 35,
    files: {
      'node_modules/browserify/node_modules/browser-pack/_prelude.js': { size: 480 },
      'dist/bar.js': { size: 104 },
      'dist/foo.js': { size: 97 },
      '[sourceMappingURL]': { size: 35 },
      '[unmapped]': { size: 1 },
      '[EOLs]': { size: 1 }
    }
  }],
  output: '<!doctype html>...',
  errors: []
}

See more at wiki page

More details

explore(bundlesAndFileTokens, [options])

Returns Promise that is resolved to an object with properties:

  • bundles: array - List of bundle explore result objects
    • bundleName: string - Path associated with the bundle
    • totalBytes: number - Size of the provided file
    • unmappedBytes: number | undefined
    • eolBytes: number - Bytes taken by end of line characters
    • sourceMapCommentBytes: number - sourceMappingURL comment bytes
    • files: { [sourceFile: string]: number }[] - Map containing filenames from the source map and size in bytes they take inside of provided file. Additional key <unmapped> is included if options.onlyMapped is false.
  • output: string - Result as a string if output.format options specified. If output='html' it contains self-packed HTML that can be opened in the browser
  • errors: array - List of bundle explore error objects
    • bundleName: string - Path associated with the bundle
    • code: string - Error code
    • message: string - User friendly message
    • error: Error
    • isWarning: boolean - Whether error isn't fatal

The promise is rejected when there is a fatal error or all bundles explore failed. Reject reason is either explore result object (the same one returned when promise resolved) or Error object with code property specified.

Possible error codes are:

  • Unknown
  • NoBundles - Empty array is passed to explore
  • OneSourceSourceMap - Bundle source map only contains one source
  • UnmappedBytes (warning) - There are unmapped bytes
  • InvalidMappingLine - Source map refers to the generated line beyond source last line
  • InvalidMappingColumn - Source map refers to generated column beyond source last column at the line
  • CannotSaveFile - Error saving HTML to file when file option specified
  • CannotCreateTempFile - Temporary HTLM file with visualization cannot be created. Check temporary folder access.
  • CannotOpenTempFile - Temporary HTLM file cannot be opened. Check if default browser can openen html files.
  • CannotOpenCoverageFile - Unable to open/parse coverage file
  • NoCoverageMatches - No matched bundles found for coverages.
  • Node.js error code (e.g. 'ENOENT')

Examples

Full

explore('js/*.*', {
  file: './sme-results/2019-04-27.html',
  output: {
    format: 'html',
    filename: './sme-result.html'
  },
  noRoot: true,
  onlyMapped: true,
  replaceMap: {
    dist: ''
  }
})
  .then((result: ExploreResult) => {
    result.errors.forEach((error: ExploreErrorResult) => {
      if (error.isWarning) {
        console.log(`Issue during '${error.bundleName}; explore`, error.message);
      } else {
        console.log(`Failed to explore '${error.bundleName}'`, error.message);
      }
    });

    result.bundles.forEach((bundle: ExploreBundleResult) => {
      console.log(bundle.bundleName);
      console.log(JSON.stringify(bundle.files));
    });
  })
  .catch(error => {
    console.log('Failed to explore');
    if (error.errors) {
      error.errors.forEach((exploreError: ExploreErrorResult) => {
        console.log(exploreError.bundleName);
        console.log(exploreError.message);
      });
    } else {
      console.log(error);
    }
  });

Inline or referenced map

explore('with-inline-map.js');

Separate map

explore(['foo.min.js', 'foo.min.js.map']);

Glob pattern

explore('js/*.*');

Multiple globs

explore(['js/foo.1*.js', 'js/foo.mi?.js']);

Specify bundles explicitly

const bundle: Bundle = { code: 'foo.min.js', map: 'foo.min.js.map' };

explore(bundle);

explore([{ code: 'foo.min.js', map: 'foo.min.js.map' }, { code: 'with-inline-map.js' }]);

Pass buffer

explore({ code: fs.readFileSync('js/foo.min.js'), map: fs.readFileSync('js/foo.min.js.map') });

gzip size

When gzip option (or --gzip parameter) is specified result size calculated as gzip size. Due to the nature of compression a gzip file size is inaccurate. It means that removing a 1k gzipped file in a bundle may reduce the bundle size by less than 1k. Also it's impossible to calculate unmapped bytes because the sum of spans' gzip sizes isn't equal to gzip size of the source file.

Code coverage heat map

In Google Chrome, you can collect code coverage stats. source-map-explorer accepts path to via --coverage argument (or coverage API option) and attempts to color code the heat map. This allows you to find the code that is not strictly needed for the initial page load and helps to identify the ideal ways to code split.

Red boxes correspond to code that would only be executed if the user took some action, or if some condition was met. For example, it may be a component inside of a dropdown the user never interacted with, or components that are only needed if the user opens a modal. In cases where the parent is green but the boxes inside are red, that means maybe some "initialization" logic ran, but the inner code never ran. Maybe we mounted a button, but not the other components in that module that are only needed if and when the user clicks the button, in that case, I would have the button trigger the rest of the code to load.

The heat map feature helps you identify the code that is needed for a fast initial page load (green), as well as helps to identify the code that can be (potentially) deferred because it doesn't run until the user interacts with some feature (red).

What might contribute to a generated file size

In addition to mapped generated code a file may contain:

  • sourceMappingURL comment - A comment containing source map or referencing the file with source map. Represented by [sourceMappingURL] in explore result.
  • Mapped code without source. It might be code generated by a bundler (e.g. webpack). Represented by [no source] in explore result.
  • Unmapped code - code that is not referenced within the source map. Represented by [unmapped] in explore result. For example webpack keeps on-demand chunk's content unmapped.

Generating source maps

For source-map-explorer to be useful, you need to generate a source map which maps positions in your minified file all the way back to the files from which they came.

If you use browserify, you can generate a JavaScript file with an inline source map using the --debug flag:

browserify -r .:foo --debug -o foo.bundle.js
source-map-explorer foo.bundle.js

If you subsequently minify your JavaScript, you'll need to ensure that the final source map goes all the way back to the original files. For example, using browserify, uglify and exorcist:

browserify -r .:foo --debug -o foo.bundle.js
# foo.bundle.js has an inline source map
cat foo.bundle.js | exorcist foo.bundle.js.map > /dev/null
# foo.bundle.js.map is an external source map for foo.bundle.js
uglifyjs -c -m \
  --in-source-map foo.bundle.js.map \
  --source-map foo.min.js.map \
  -o foo.min.js \
  foo.bundle.js
# foo.min.js has an external source map in foo.min.js.map
source-map-explorer foo.min.js

Types of source maps

There are two types of source maps: inline and external.

If your JS file has an inline source map, then its last line will look something like this:

//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJm...

This encodes the sourcemap as a base64 data URL. If your file has an inline source map, the source-map-explorer should have no trouble understanding it.

If your last line instead looks like this:

//# sourceMappingURL=foo.min.js.map

Then the source map lives in an external .map file. The source-map-explorer will try to find this file, but this often fails because it's unclear what the URL is relative to.

If this happens, just pass in the source map explicitly, e.g. (in bash or zsh):

source-map-explorer path/to/foo.min.js{,.map}

Other source map tools

Learn about source maps

source-map-explorer's People

Contributors

aholachek avatar also avatar anish2 avatar arve0 avatar danvk avatar dependabot[bot] avatar dinony avatar duhdugg avatar eins78 avatar elektronik2k5 avatar hypercubed avatar insin avatar jackyef avatar jakub300 avatar joshribakoff avatar khanguy00 avatar michens avatar nikolay-borzov avatar paulirish avatar penx avatar rodneyrehm avatar tylergraf avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

source-map-explorer's Issues

Add a --replace flag

Sometimes file names in source maps aren't quite right, e.g. in pileup they get doubled: dist/main/formats/main/formats. A repeated --replace flag could help with this.

Are sizes compressed/tree-shaked sizes? + Respect gzip?

I was wondering - because it does not seem to be documented anywhere - whether the sizes displayed are based on the compression applied (uglify/babili). Also I think it would be interesting to additionally or per parameter use gzip sizes instead.

Output image

It'd be useful to be able to output an image, preferrably SVG. I could generate it as part of my build, and include the image in my README.

Security vulnerability in 'open' package

There is a security advisory with the open package, which this library uses. From npm audit:

│ Critical      │ Command Injection                                            │
│ Package       │ open                                                         │
│ Patched in    │ No patch available                                           │
│ Dependency of │ source-map-explorer [dev]                                    │
│ Path          │ source-map-explorer > open                                   │
│ More info     │ https://nodesecurity.io/advisories/663                       │

open seems to be un-maintained, so highly unlikely this issue will be fixed. There is a suggestion to move to opener or opn.

Print URL when browser unavailable

When I ssh into a system to build JS and run source-map-explorer on it, it generates HTML somewhere in /tmp but fails to launch a browser on it and it doesn't tell me the path so I can view it myself.

It looks like the open library lets you specify a callback for errors -- you could just print the path on error or something.

Support inline source maps

A JS bundle with an inline source map has all the information source-map-explorer needs. This should work:

source-map-explorer path/to/inline-bundle.js

Improvement: Support multiple bundles

This makes source-map-explorer really useful for situations where you are doing bundle splitting.

A simple version would just plot all the bundles next to each other on the toplevel. The cli tool would just have to support multiple JS files.

A more advanced version would visualise the files which are in multiple bundles. A possibility would be to show a number representing in how many bundles the files is. A hover could highlight the files in all its bundles.

API for programmatic use

Hey, exports currently provide access only to parts of the library and are there only for testing purposes (per comment).

I'm wondering what do you think about API allowing simple use of source-map-explorer as a whole. I imagine it as a method that accepts buffers or files and returns html of the report (or other thing based on options).

Explain the JSON output

The numbers in the JSON file don't match the numbers in the web page, and I can't begin to guess what those numbers mean. When I sum the ones from the JSON file I get 78, the file is 900K. Not sure exactly what those numbers are, and why the JSON file is a single level and the UI allows me to drill down.

Your demo examples seem to show the actual bytes in those regions.

Wrong size displayed

Is it alright that source-map-explorer shows / 545 kB 100.0 % whereas the size of the file is 940 kB? I'm using rollup for compilation and creating source map file. Thanks in advance for any ideas on what might be wrong here.

Resolve sourceMappingURLs relative to the JS file

If source-map-explorer finds a path to the map file in the JS file, it will try to read it relative to the current directory. Instead, it should read it relative to the JS file's directory:

$ tail -1 dist/dygraph-combined.js
//# sourceMappingURL=dygraph-combined.js.map

$ source-map-explorer dist/dygraph-combined.js
/Users/danvk/github/dygraphs/node_modules/source-map-explorer/node_modules/convert-source-map/index.js:31
    throw new Error('An error occurred while trying to read the map file at '
          ^
Error: An error occurred while trying to read the map file at dygraph-combined.js.map
Error: ENOENT, no such file or directory 'dygraph-combined.js.map'

Same file listed multiple times

The same file appears to be listed multiple times. I have a file named Keywords.vue. It's listed multiple times in the visualization:

  • Keywords.vue?7abc • 2.05 KB • 0.6%
  • Keywords.vue?7d9c5 • 767 B • 0.2%
  • Keywords.vue • 912 B • 0.3%

I'm guessing that the params after the ? mean something. Perhaps different parts of the file are included multiple times?

Glob not working when not matching _exactly_ two files (and error message is misleading)

No response on comment yet, so opening an issue.

Has anything changed in 1.6.0? Cannot get globs to work:

C:\Temp\sme>npm i -g source-map-explorer
C:\Users\_\AppData\Roaming\npm\source-map-explorer -> C:\Users\_\AppDa
ta\Roaming\npm\node_modules\source-map-explorer\index.js
+ [email protected]
updated 1 package in 0.957s

C:\Temp\sme>source-map-explorer --version
1.6.0

C:\Temp\sme>source-map-explorer main.*
File not found! --  ENOENT: no such file or directory, open 'main.*'

C:\Temp\sme>dir main.*
 Volumet i stasjon C er OSDisk
 Volumserienummeret er F65B-C808

 Innhold i C:\Temp\sme

11.01.2019  08:36             2 146 main.js
               1 fil(er)            2 146 byte
               0 mappe(r)   9 305 964 544 byte ledig

C:\Temp\sme>

Incorrect map of json files

Repo:

import moment from 'moment-timezone';
console.log(moment().toISOString());

This will produce an incorrect source map. The latest.json from moment-timezone is included in the bundle but attributed to a random module that is not moment-timezone.

Unable to map a large amount of bytes

When running this tool I get: Unable to map 4270596 / 6575223 bytes (64.95%) printed to the console. The report still generates, but most of my bundle is 'unmapped'. This seems related to #47 , since this corresponds to TypeScript code. However, I get no information about any TypeScript code at all. Is this normal?

bundle_analysis

Unable to find a source map.

I want to use 'source-map-explorer bundle.js' to generate visualized data. But it failed. It prompts 'unable to find a source map'. The bundle.js is generated by webpack like 'webpack -p --config webpack.build.config.js'. How to resolve it? thanks.

Enhancement: Give error message rather than crashing on ENOENT

I had a path wrong and typed source-map-explorer main.bundle.js, which yielded this:

fs.js:584
  return binding.open(pathModule._makeLong(path), stringToFlags(flags), mode);
                 ^

Error: ENOENT: no such file or directory, open 'main.bundle.js'
    at Object.fs.openSync (fs.js:584:18)
    at Object.fs.readFileSync (fs.js:491:33)
    at loadSourceMap (/Users/ssterling3/.npm-global/lib/node_modules/source-map-explorer/index.js:81:19)
    at Object.<anonymous> (/Users/ssterling3/.npm-global/lib/node_modules/source-map-explorer/index.js:159:12)
    at Module._compile (module.js:571:32)
    at Object.Module._extensions..js (module.js:580:10)
    at Module.load (module.js:488:32)
    at tryModuleLoad (module.js:447:12)
    at Function.Module._load (module.js:439:3)
    at Module.runMain (module.js:605:10)

At first I thought the install was broken, and almost reported a bug that it doesn't work on install. But no, I just had to type source-map-explorer dist/main.bundle.js.

It would be better if a missing file resulted in a simple error message.

generate standalone HTML file

We archive reports per build and that includes source-map-explorer's output. The HTML file is generated as follows

source-map-explorer dist/bundle.min.js \
  --replace "`node -e 'console.log(process.cwd())'`/dist/" --with '' \
  --html > reports/bundle-size.html

When opening that file the screen remains empty, because the following resources could not be loaded:

  • file:///-path-to-project/node_modules/source-map-explorer/node_modules/underscore/underscore.js
  • file:///-path-to-project/node_modules/source-map-explorer/vendor/webtreemap.css
  • file:///-path-to-project/node_modules/source-map-explorer/vendor/webtreemap.js

Those files could either be inlined - so everything is contained in the generated HTML. Or source-map-explorer could accept a destination path and copy the required resources to it. E.g.

source-map-explorer dist/bundle.min.js \
  --replace "`node -e 'console.log(process.cwd())'`/dist/" --with '' \
  --html \
  --destination reports/gustav

would create the following structure

reports/gustav
  index.html
  underscore.js
  webtreemap.css
  webtreemap.js

Expand globs

Currently it seems like the program doesn't expand globs itself. This makes it impossible to run something like source-map-explorer build/static/js/main.* on Windows and get it to pick up a hashed filename. Which makes it hard to put into package.json as one of the scripts because the built filename is different every time.

It would be great if source-map-explorer could expand globs (it's fine to enforce it only expands to a single file) for this particular use case on Windows.

Unable to map 42 / 2766661 bytes (0.00%) - Temp file open error

Hey ,
Im using create react app, and getting the following error when trying to explore the bundle using source-map-explorer.

this is the command im running:
source-map-explorer build/static/js/main.28a6ec23.js build/static/js/main.28a6ec23.js.map

I also need to mention that my bundle is very big (2766661 bytes)

Any idea what could be the issue?

Thanks !

Running with *.js and '*.js' (quoted) should behave the same

I got quite confused when I tried to run:

$ source-map-explorer *.js
Usage:
  source-map-explorer <script.js> [<script.js.map>]
  source-map-explorer [--json | --html | --tsv] [-m | --only-mapped] <script.js> [<script.js.map>] [--replace=BEFORE --with=AFTER]... [--noroot]
  source-map-explorer -h | --help | --version

in a directory with 4 bundles. It just shows the usage.

The solution was to run with '*.js' (quoted):

$ source-map-explorer '*.js'

These should do the same thing.

Publish latest version to get security updates

I have a security warning in my project relating to the open package. This has been fixed in #71 but has not been published to NPM. Can we get it published so I can update it in my project please?

Facilitate diffing

You're usually visualizing a source map because you want to make the source smaller.

It would be nice if source-map-explorer facilitated this in some way, e.g. by letting you pass in a --before JSON file. The output would be a list of changes.

Windows backslash support

I tried using source-map-explorer on my windows machine but it doesn't split the paths correctly as it only seems to split paths with forward slashes instead of backslashes (and so there was no hierarchy, just a flat list of modules). I tried to work around this issue by using the following arguments: --replace=\ --with=/

However this only replaced the first backslash, and not all of them. This is because it creates a regular express with the replace argument using new RegExp(pattern[, flags]), but leaves the flags blank. In order to replace all it needs to use the "g" flag (global replace). I think this should be enabled by default as it makes more sense. But if not perhaps we could have a way of enabling that flag from the command line? e.g. --replaceFlags=g ?

Thanks,

Martin.

See what package import other packages.

I need to understand which package imports which package.

For example, I have lodash full here:

image

and I don't need it.

But I still don't know which package is importing it... How to?

Be able to view all chunks

If webpack generates a bunch of different chunks, source-map-explorer has no way of opening them all together in one visualization. Ideally I could just do:
source-map-explorer build/static/js/* and it puts everything in one map.
Currently I have to decide which chunk to analyze and put it in the argument.

Eg:

main.8b21277f.chunk.js         runtime~main.41117e05.js       vendors.a1b9586e.chunk.js   main.8b21277f.chunk.js.map     runtime~main.41117e05.js.map   vendors.a1b9586e.chunk.js.map  

Browser plugin

Would be fun to run on sites to peak at their bundles.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.