inspectpack
An inspection tool for Webpack frontend JavaScript bundles.
Inspectpack gives insight into what's in your production JS bundles and where
you can cut down on size, duplicates, etc.
Install
$ npm install inspectpack
Usage
An inspection tool for Webpack frontend JavaScript bundles.
Usage: inspectpack --action=<string> [options]
Options:
--action, -a Actions to take [string] [required] [choices: "duplicates"]
--bundle, -b Path to webpack-created JS bundle [string]
--format, -f Display output format [string] [choices: "json", "text"] [default: "text"]
--verbose Verbose output [boolean] [default: false]
--minified, -m Calculate / display minified byte sizes [boolean] [default: true]
--gzip, -g Calculate / display minified + gzipped byte size (implies `--minified`)
[boolean] [default: true]
--help, -h Show help [boolean]
--version, -v Show version number [boolean]
Examples:
inspectpack --action=duplicates Report duplicates that cannot be deduped
--bundle=bundle.js
Inputs
The are three potential sources of input for bundle analysis:
- Stats: A metadata file of build / size information generated by Webpack
- Source Maps: The source mappings file for a bundle
- Bundle: And of course, the JS bundle itself.
Additionally, specific analysis steps also may require designated Webpack
configurations to produce a proper input.
Bundle
If an inspectpack
action requires a --bundle
, create one as follows:
Webpack configuration:
- Enable deduplication:
plugins:webpack.optimize.DedupePlugin()
- Disable minification: We need the comment headers.
- Enable output path comments:
output.pathinfo = true
.
Inputs: Create a JavaScript bundle
$ webpack
The created JS bundle path is ready to use. (Note that code split chunks should
work same as a single root bundle, but we haven't tested this yet.)
Actions
duplicates
Detect if there are libraries that should be de-duplicated with the
webpack.optimize.DedupePlugin
but are not because of version mismatches.
First create a bundle. Then run:
$ inspectpack --action=duplicates --bundle=bundle.js
Outputs: A JSON or text report. For example:
## Summary
* Bundle:
* Path: /PATH/TO/bundle.js
* Bytes (min): 1678533
* Missed Duplicates:
* Num Unique Files: 116
* Num Extra Files: 131
* Extra Bytes (min): 253955
* Pct of Bundle Size: 15 %
- Number of unique files with missed duplicates.
- Number of total files that could be removed. This is different from the
previous number because you may have 3+ duplicates of a unique file path
that cannot be deduplicated.
- Minified byte size of the extra files. Note that we choose the "minimum
possible code size" to be the lowest of all file sizes for a given unique
file name.
Notes:
- The vast majority of the analysis time is spent minifying and gzipping
duplicate code snippets and the entire bundle. For just a list of missed
duplicates, add the
--minified=false --gzip=false
flags.
pattern
Detect the occurrence of 1+ patterns in code sections of the bundle. This is
useful for detecting anti-patterns, some of which we aggregate in a useful
option --suspect-patterns
.
First create a bundle. Then run:
$ inspectpack \
--action=pattern --bundle=bundle.js \
--pattern="201[56]"
$ inspectpack \
--action=pattern --bundle=bundle.js \
--pattern "2016" "unicorn"
$ inspectpack \
--action=pattern --bundle=bundle.js \
--suspect-patterns
Notes:
- It is best to use quotes around patterns so that you don't have to escape
shell processing.
- Some regular expressions can be very expensive time-wise, so be sure to try
things out a bit and refactor your patterns if the inspection is taking too
long.
Suspect Patterns: The --suspect-patterns
flag looks for known "suspect"
patterns that potentially contain inefficient code. See
the source code for the full breakdown of
SUSPECT_PATTERNS
.
-
MULTIPLE_EXPORTS_SINGLE
: Multiple exports via one export object.
module.exports = {
foo: __webpack_require__(1),
bar: __webpack_require__(2)
}
-
MULTIPLE_EXPORTS_MUTIPLE
: Multiple exports via 2+ export statements.
module.exports.foo = __webpack_require__(1);
module.exports.bar = __webpack_require__(2);
Outputs: A JSON or text report. For example:
$ inspectpack \
--action=pattern \
--bundle="/PATH/TO/bundle.js" \
--format=text \
--suspect-patterns
## Summary
* Bundle:
* Path: /PATH/TO/bundle.js
* Num Matches: 17
* Num Unique Files: 14
* Num All Files: 17
* Custom Patterns:
* Suspect Patterns:
* MULTIPLE_EXPORTS_SINGLE: [^\n]*(module\.|)exports\s*=\s*{(\s*.*__webpack_require__\(.*){2}
* MULTIPLE_EXPORTS_MUTIPLE: [^\n]*((module\.|)exports\..*\s*=\s*.*__webpack_require__\(.*\s*){2}
## Matches
* custom-lib/lib/index.js
* Num Matches: 1
* Num Files Matched: 1
* 1103: ../~/custom-lib/lib/index.js
* Matches: 1
* MULTIPLE_EXPORTS_SINGLE - /[^\n]*(module\.|)exports\s*=\s*{(\s*.*__webpack_require__\(.*){2}/:
module.exports = {
Foo: __webpack_require__(/*! ./components/foo */ 1104),
Bar: __webpack_require__(/*! ./components/bar */ 1135),
* lodash/string.js
* Num Matches: 1
* Num Files Matched: 1
* 1581: ../~/lodash/string.js
* Matches: 1
* MULTIPLE_EXPORTS_SINGLE - /[^\n]*(module\.|)exports\s*=\s*{(\s*.*__webpack_require__\(.*){2}/:
module.exports = {
'camelCase': __webpack_require__(/*! ./string/camelCase */ 1582),
'capitalize': __webpack_require__(/*! ./string/capitalize */ 1587),
* lodash/lang.js
* Num Matches: 1
* Num Files Matched: 1
* 1862: ../~/lodash/lang.js
* Matches: 1
* MULTIPLE_EXPORTS_SINGLE - /[^\n]*(module\.|)exports\s*=\s*{(\s*.*__webpack_require__\(.*){2}/:
module.exports = {
'clone': __webpack_require__(/*! ./lang/clone */ 1863),
'cloneDeep': __webpack_require__(/*! ./lang/cloneDeep */ 1869),
Other Useful Tools
Other tools that inspect Webpack bundles: