webpack-contrib / webpack-bundle-analyzer Goto Github PK
View Code? Open in Web Editor NEWWebpack plugin and CLI utility that represents bundle content as convenient interactive zoomable treemap
License: MIT License
Webpack plugin and CLI utility that represents bundle content as convenient interactive zoomable treemap
License: MIT License
Would you accept a PR that allows the bundle analyzer to ignore an entry point?
We currently have two entry points - one with .min.js
and one without. The one with, we send through uglify, the other we don't. The resulting report looks like this: https://aui-cdn.atlassian.com/atlaskit/pr/stats/d8f6cfdb199abff6c0af668b6da94db6c14b64d1/ak-editor-toolbar-text-formatting/with-deps.html but as you can see the information is duplicated.
Webpack looks something like this:
.entry = {
'dist/bundle-with-deps.js': productionConfig.entry['dist/bundle.js'],
'dist/bundle-with-deps.min.js': productionConfig.entry['dist/bundle.js'],
};
First off, i'm not sure if the problem is with bundle analyzer or webpack-merge. :)
I've compared the final webpack config, and it is exactly the same with webpack-merge 2.0.0 and 2.1.0 - So really not sure what's going on. Maybe a conflicting dependency?
However i get this error when running with webpack-merge 2.1.0:
node_modules/webpack-bundle-analyzer/lib/Logger.js:70
if (this.activeLevels.has(level)) this._log.apply(this, [level].concat(args));
^
TypeError: Method Set.prototype.has called on incompatible receiver #<Set>
at Set.has (native)
at Logger.(anonymous function) [as info] (/Users/dsc/Development/Projects/react-start/node_modules/webpack-bundle-analyzer/lib/Logger.js:70:27)
This also seems to be the same error as in #34
How do you use this module? As CLI utility or as plugin?
This is the webpack-config that's causing the error:
const webpack = require('webpack');
const merge = require('webpack-merge');
const ExtractTextPlugin = require('extract-text-webpack-plugin')
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
const extractCSS = require('./utils/extract-css');
const config = require('../config');
/**
* Define config files
*/
const serverConfig = {
target: 'web',
devtool: '#sourcemap',
entry: {
'server.bundle': [
'./src/server'
]
},
output: {
path: `${config.paths.dist}`,
libraryTarget: 'this',
filename: `${config.dirNames.js}/[name].js`,
publicPath: '/'
},
performance: {
hints: false,
},
plugins: [
// Add Client Side only modules - They will be replaced with a no-op function on the server.
new webpack.NormalModuleReplacementPlugin(/^(Modernizr|gsap|ScrollToPlugin|raven-js|raven-redux-middleware|intersection-observer|localforage)$/, 'node-noop'),
new ExtractTextPlugin({filename: `${config.dirNames.css}/[name].min.css`, allChunks: true}),
new webpack.DefinePlugin({
'process.env.NODE_ENV': '"production"',
'process.env.BABEL_ENV': '"server"',
'process.env.VERSION': JSON.stringify(process.env.VERSION),
'process.env.SERVER': '"true"',
'process.env.DEV': false,
'process.env.PROD': true,
'process.env.STORYBOOK': false,
'process.env.TRON': false,
'process.env.REMOTE': false,
}),
new webpack.optimize.UglifyJsPlugin({
sourceMap: true,
compress: {
screw_ie8: true,
warnings: false,
},
mangle: {
screw_ie8: true,
},
output: {
comments: false,
screw_ie8: true,
},
}),
new BundleAnalyzerPlugin({
analyzerMode: 'static',
reportFilename: '../reports/report-server.html',
openAnalyzer: false,
generateStatsFile: true,
statsFilename: '../reports/stats-server.json',
statsOptions: null,
}),
]
};
const common = Object.assign({}, require('./common.config.js'));
common.plugins = null; // Only use the Server Bundle plugins, so we avoid conflicting plugins.
module.exports = extractCSS(merge(common, serverConfig), config.paths.dist);
The final merged config looks like this:
{
"name": "client",
"target": "web",
"resolve": {
"modules": [
"src",
"libs",
"node_modules"
],
"extensions": [
".js",
".jsx"
]
},
"plugins": [
{
"resourceRegExp": /^(Modernizr|gsap|ScrollToPlugin|raven-js|raven-redux-middleware|intersection-observer|localforage)$/,
"newResource": "node-noop"
},
{
"filename": "css\u002F[name].min.css",
"id": 1,
"options": {
"allChunks": true
}
},
{
"definitions": {
"process.env.NODE_ENV": "\"production\"",
"process.env.BABEL_ENV": "\"server\"",
"process.env.VERSION": "\"0.2.16\"",
"process.env.SERVER": "\"true\"",
"process.env.DEV": false,
"process.env.PROD": true,
"process.env.STORYBOOK": false,
"process.env.TRON": false,
"process.env.REMOTE": false
}
},
{
"options": {
"sourceMap": true,
"compress": {
"screw_ie8": true,
"warnings": false
},
"mangle": {
"screw_ie8": true
},
"output": {
"comments": false,
"screw_ie8": true
}
}
},
{
"opts": {
"analyzerMode": "static",
"analyzerPort": 8888,
"reportFilename": "..\u002Freports\u002Freport-server.html",
"openAnalyzer": false,
"generateStatsFile": true,
"statsFilename": "..\u002Freports\u002Fstats-server.json",
"statsOptions": null,
"logLevel": "info",
"startAnalyzer": true
},
"logger": {
"activeLevels": {}
}
}
],
"module": {
"loaders": [
{
"test": /\.jsx?$/,
"include": [
"\u002FUsers\u002Fdsc\u002FDevelopment\u002FProjects\u002Freact-start\u002Fsrc"
],
"exclude": /(node_modules)/,
"loader": "babel-loader",
"query": {
"cacheDirectory": false
}
},
{
"test": /\.css$/,
"include": /(src\/styles\/|(global)\.css)/,
"loader": "\u002FUsers\u002Fdsc\u002FDevelopment\u002FProjects\u002Freact-start\u002Fnode_modules\u002Fextract-text-webpack-plugin\u002Floader.js?{\"omit\":1,\"remove\":true,\"publicPath\":\"..\u002F\"}!style-loader!css-loader?{\"sourceMap\":true,\"importLoaders\":1,\"minimize\":true}!postcss-loader"
},
{
"test": /\.(css)$/,
"include": "\u002FUsers\u002Fdsc\u002FDevelopment\u002FProjects\u002Freact-start\u002Fsrc",
"exclude": /(node_modules|src\/styles\/|(global)\.css)/,
"loader": "\u002FUsers\u002Fdsc\u002FDevelopment\u002FProjects\u002Freact-start\u002Fnode_modules\u002Fextract-text-webpack-plugin\u002Floader.js?{\"omit\":1,\"remove\":true,\"publicPath\":\"..\u002F\"}!style-loader!css-loader?{\"sourceMap\":true,\"importLoaders\":1,\"modules\":true,\"localIdentName\":\"[hash:base64:6]\",\"minimize\":true,\"camelCase\":true}!postcss-loader"
},
{
"test": /\.css$/,
"include": /node_modules/,
"loader": "\u002FUsers\u002Fdsc\u002FDevelopment\u002FProjects\u002Freact-start\u002Fnode_modules\u002Fextract-text-webpack-plugin\u002Floader.js?{\"omit\":1,\"remove\":true,\"publicPath\":\"..\u002F\"}!style-loader!css-loader"
},
{
"test": /\.md$/,
"loaders": [
"html-loader",
"markdown-loader"
]
},
{
"test": /\.(jpe?g|png|gif|svg|ico)$/i,
"include": "\u002FUsers\u002Fdsc\u002FDevelopment\u002FProjects\u002Freact-start\u002Fsrc",
"exclude": /(fonts|static|inline|icon?s)/,
"loaders": [
"file-loader?name=images\u002F[name]_[hash:base64:6].[ext]",
{
"loader": "image-webpack-loader",
"query": {
"bypassOnDebug": true,
"progressive": true,
"svgo": {
"plugins": [
{
"removeViewBox": false
},
{
"removeXMLProcInst": false
}
]
}
}
}
]
},
{
"test": /((icon|inline)\.svg|(icon?s|inline)\/.*\.svg)$/,
"loader": "svg-inline-loader?removeTags=true&removeSVGTagAttrs=true",
"include": "\u002FUsers\u002Fdsc\u002FDevelopment\u002FProjects\u002Freact-start\u002Fsrc",
"exclude": /(fonts|static)/
},
{
"test": /fonts\/.*\.(woff|woff2|eot|ttf|svg)$/,
"loader": "file-loader?name=fonts\u002F[name].[ext]"
},
{
"test": /\.(mp4|webm)$/,
"loader": "url-loader?limit=10000"
}
]
},
"devtool": "#sourcemap",
"entry": {
"server.bundle": [
".\u002Fsrc\u002Fserver"
]
},
"output": {
"path": "\u002FUsers\u002Fdsc\u002FDevelopment\u002FProjects\u002Freact-start\u002Fdist",
"libraryTarget": "this",
"filename": "scripts\u002F[name].js",
"publicPath": "\u002F"
},
"performance": {
"hints": false
}
}
I have two webpack project, one is a module, the other an application.
I have installed the plugin on both, however, I don't know how to run the analysis. Could you please update the README.md so I can try this module ?
Just wanted to say that this tool is incredible. The content of our bundles have been a black box but with webpack-bundle-analyzer it's super clear what goes where and we can finally optimize it!
It can not open analyzer server when openAnalyzer
is false
.
I am getting this message in the end of the webpack emitts:
TypeError: Cannot read property 'raw' of undefined Could't find any javascript bundles in provided stats file
How do you use this module?
Plugin
If plugin, what options were provided?
None
What other Webpack plugins were used?
new webpack.LoaderOptionsPlugin({
options: { worker: { output: { filename: "build/worker.js" } } } }),
new webpack.HotModuleReplacementPlugin(),
new webpack.NamedModulesPlugin(),
new BundleAnalyzerPlugin()
There should be an option where as soon as the stats are opened in the browser, the server shuts down that way developers can still see their stats and don't have to ctrl+c
every time they make a build.
Hi there,
I was trying this out by running the two CLI commands mentioned at the end of the readme, and I end up with a generated static report.html that shows just a blank page. There's not even any console or network errors. The code is there in the file, it just doesn't seem to do anything at all.
The stats.json file seems to be generated correctly and with no errors.
I tried this on a couple of separate apps, and also opening the report.html on Chrome, Safari and Firefox.
I can provide the stats.json and generated report.html if desired to help debug the issue but I'd rather not do it directly here.
Alternatively, if there's something I can do myself to help debug it, let me know.
In any case, this seems like an amazing and very helpful idea, so thanks for taking the time to work on this :)
with this commit, i got wrong filepath with the report file in dev mode
with webpack-dev-server
new BundleAnalyzerPlugin({
analyzerMode: 'static',
reportFilename: 'report.html',
openAnalyzer: false,
generateStatsFile: true,
statsFilename: 'stats.json',
statsOptions: null,
source: false,
logLevel: 'silent'
}),
This issue is a place to discuss and track a possible separation of webpack analyzer plugin code from the reporter UI code.
This idea was triggered by a proposal to add sunburst charts to the UI, where @th0r and me eventually thought it might be interesting to split these two concerns to distinct packages:
Or that the UI that is opened could be configurable, so that I could build a totally separate npm package that would only contain the UI parts that could be plugged into this packages webpack parts.
That's a very interesting idea and, at first glance, it won't be too hard to split analyzer from report UI.
We can move all current UI code from
webpack-bundle-analyzer
into, say,webpack-bundle-analyzer-treemap-reporter
.
webpack-bundle-analyzer
will be responsible only for analyzing bundle and feeding this info to reporter-plugins whose responsibility will be showing it in any way.And the nice thing is reporter is not limited to some UI stuff - it can do anything it want with provided data!
Hello,I would like to ask what does state size and parsed size mean?
I do like beblow
new BundleAnalyzerPlugin({
startAnalyzer:false,
generateStatsFile:true,
statsFilename:'stats.json'
})
after building completed,I don't find states.json,why?
I love this plugin; this is an absolutely awesome way to understand the contents of a bundle, but once we see the things making our bundle huge, we end up asking how it even got there. A lot of times, especially in large projects, it isn't obvious.
It would be AWESOME to be able to click on a module box and somehow get a list of other modules that reference said thing. Then those things could be expanded to see things that reference them.
This would definitely help in knowing which require statements needs to be translated into "ensures" so that they can be deferred.
This is a great tool! I really enjoy visualizations of my work. I think it would be neat if the treemap's nodes were only modules instead of following the folder structure. It might make the map more useful and you can already see the path when you mouseover the node.
wba is reporting this error on a valid stats.json file.
How do you use this module? As CLI utility or as plugin?
As CLI
Generated stats with
webpack --profile --json > dist/stats.json
If CLI, what command was used? webpack-bundle-analyzer dist/stats.json dist
What other Webpack plugins were used?
LodashModuleReplacementPlugin
webpack.optimize.CommonsChunkPlugin
It would be nice to also attach webpack stats file. Attached!
stats.zip
hey there -
i ran into the following error when i tried the run the analyzer:
Error: Cannot find module 'ejs'
at Function.Module._resolveFilename (module.js:325:15)
at Function.Module._load (module.js:276:25)
at Module.require (module.js:353:17)
at require (internal/module.js:12:17)
at new View (/path/to/my/app/node_modules/express/lib/view.js:78:30)
at EventEmitter.render (/path/to/my/app/node_modules/express/lib/application.js:569:12)
at ServerResponse.render (/path/to/my/app/node_modules/express/lib/response.js:960:7)
at /path/to/my/app/node_modules/webpack-bundle-analyzer/lib/viewer.js:44:9
at Layer.handle [as handle_request] (/path/to/my/app/node_modules/express/lib/router/layer.js:95:5)
at trim_prefix (/path/to/my/app/node_modules/express/lib/router/index.js:312:13)
at /path/to/my/app/node_modules/express/lib/router/index.js:280:7
at Function.process_params (/path/to/my/app/node_modules/express/lib/router/index.js:330:12)
at next (/path/to/my/app/node_modules/express/lib/router/index.js:271:10)
at SendStream.error (/path/to/my/app/node_modules/express/node_modules/serve-static/index.js:121:7)
at emitOne (events.js:77:13)
at SendStream.emit (events.js:169:7)
$node -v
v4.6.0
$npm -v
2.15.11
(yeah, i know ;-)
$npm list --depth=0
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
└── [email protected]
the analyzer seems to have the deps it needs (edited for brevity):
├─┬ [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ └── [email protected]
i get the same error whether i run as CLI or plugin.
When this is used in an environment where node_modules packages are symlinked (via lerna, @microsoft/rush, npm link) the locations to npm modules are expanded such that it makes things hard to parse. Basically half of the tree map is dedicated to resolving the node_modules folder:
Would there be any way to fix this such that I can provide "filters" that would alias a folder to say blank string, to remove the extraneous path? Any suggestions, other than to avoid symlinking?
What are your thoughts on including a noInfo
property in the config? I imagine the default value would be false
. It would be nice to turn off logs, such as this, from the plugin:
Webpack Bundle Analyzer is started at http://localhost:8888
Use Ctrl+C to close it
There are cases where one might not want additional information logged.
Thanks!
I've created a proof-of-concept package dependency algorithm using the reasons
metadata which might make this tool even more useful.
Instead of creating a tree of modules based on their location in the file system, it creates a tree where leafs are modules but non-leaf (folder) nodes are packages and connections are module/package dependencies. This shows more clearly the complete size of installed packages and how they relate.
For shared code, if a package is used in multiple places, it becomes a "shared" package node higher in the tree. If a package contains optional modules used in different places, then it could appear in multiple places in the tree. Example:
react: 103.8 KB - shared by <root>, react-dom & 6 more
react-addons-css-transition-group: 30.7 KB
react: 30.64 KB (99.8%)
<self>: 62 B (0.197%)
This example shows 103,8KB of "shared" react code used by two or more packages. However, react-addons-css-transition-group is loading an additional 30,64KB of react code, making the "sum cost" of css-transition-group 30,7KB instead of 62B. This is difficult to figure out with existing analyzers and might make other animation libraries more appealing.
I honestly think this is a life saver when evaluating new project dependencies or when looking for fat dependencies to trim. Some might have a small tree of huge dependencies, others might have a large tree of tiny dependencies, yet others might depend on packages already being used, making the difference a smaller one.
I'm going to try and integrate the algorithm into this project/viewer. At least as a fork for my use, but I think it is very useful to others.
EDIT: Feel free to try the POC running in a fork of webpack-bundle-size-analyzer.
cd ~/temp
npm pack [email protected]
tar -zxvf webpack-bundle-analyzer-2.2.2.tgz
ls -al package/src/parseUtils.js
6372 8 Feb 15:42 package/src/parseUtils.js
ls -al package/lib/parseUtils.js
4228 6 Jan 04:25 package/lib/parseUtils.js
Looks like the lib directory didn't get updated when 2.2.2 was published to npm.
How do you use this module? As CLI utility or as plugin?
If CLI, what command was used? (e.g. webpack-bundle-analyzer -O path/to/stats.json
)
If plugin, what options were provided? (e.g. new BundleAnalyzerPlugin({ analyzerMode: 'disabled', generateStatsFile: true })
)
What other Webpack plugins were used?
It would be nice to also attach webpack stats file.
It can be generated using these options:
new BundleAnalyzerPlugin({
analyzerMode: 'disabled',
generateStatsFile: true,
// Excludes module sources from stats file so there won't be any sensitive data
statsOptions: { source: false }
})`
stats.json
will be created in Webpack bundle output directory.
I noticed the reports show a link which looks like it could be part of the report but it's a link to the foamtree project. Not sure if this is intentional but figured I'd pass it along.
I'm trying to run this, but the page just starts up blank.
I can see that the chartData isn't set.
window.chartData = [];
Would it be safe to assume that this is because I'm using webpack 2?
I use:
externals: {
react: 'React',
'react-dom': 'ReactDOM',
immutable: 'Immutable',
},
and the production bundle size obviously goes down, (by 60kB), but all of those libraries still show up in the bundle composition map of the bundle-analyzer.
How do you use this module? As CLI utility or as plugin?
Plugin
If plugin, what options were provided? (e.g. new BundleAnalyzerPlugin({ analyzerMode: 'disabled', generateStatsFile: true })
)
new BundleAnalyzerPlugin({
analyzerMode: 'server',
analyzerPort: 8888,
reportFilename: 'report.html',
openAnalyzer: true,
generateStatsFile: false,
statsFilename: 'stats.json',
statsOptions: null,
}),
What other Webpack plugins were used?
A lot, but I disabled the CommonsChunkPlugin, to see if it was causing the issue, but it wasn't.
Thanks @th0r for this great analyzer tool.
I tried to use this plugin in webpack --watch mode but when I do changes to my project and save, webpack crashes and shows error that the port already in use. I guess the tool tries to open a new web page and establish a new 8888 port rather than connecting to existing 8888 port and refresh the result. Any help on this?
I am using the analyser as a plugin to get the gzipped stats.
Recently some code change caused this to happen.
Couldn't parse bundle asset "main-1468dcadd5cb43aed7c5.js".
Analyzer will use module sizes from stats file.
How do you use this module? As CLI utility or as plugin?
As a plugin.
Stats and bundles: https://www.dropbox.com/s/9kbr4lyljlsvqgw/stats%20and%20bundle.zip?dl=0
cc @valscion
Getting following error message
Could't analyze webpack bundle:
TypeError: Cannot read property 'raw' of undefined
Could't find any javascript bundles in provided stats file
How do you use this module? As CLI utility or as plugin?
Plugin
If CLI, what command was used? (e.g. webpack-bundle-analyzer -O path/to/stats.json
)
If plugin, what options were provided? (e.g. new BundleAnalyzerPlugin({ analyzerMode: 'disabled', generateStatsFile: true })
)
new BundleAnalyzerPlugin({
analyzerMode: isProduction ? 'server': 'disabled',
analyzerHost: '10.0.0.50', //I am using vagrant
analyzerPort: 8888,
generateStatsFile: false,
openAnalyzer: false
})
What other Webpack plugins were used?
new webpack.NoEmitOnErrorsPlugin(),
new webpack.HotModuleReplacementPlugin(),
new webpack.NamedModulesPlugin(),
new WebpackNotifier({
alwaysNotify: false,
title: 'Hello World',
contentImage: root('src/assets/images/favicon.ico')
}),
new webpack.LoaderOptionsPlugin({
debug: true
}),
new webpack.DefinePlugin({
'process.env': {
'ENV': JSON.stringify(ENV)
}
}),
new webpack.DllReferencePlugin({
context: root('src'),
manifest: require('build/dll/vendor-manifest.json')
}),
new webpack.DllReferencePlugin({
context: root('src'),
manifest: require('build/dll/polyfill-manifest.json')
})
The vendor library for drawing the chart (Carrot Search FoamTree) by default configures devicePixelRatio to 1. This looks really blurry for those of us with Retina, 4k, 5k or even better screens. Let's set this to be dynamic to the device using window.devicePixelRatio
. It should be an easy tweak.
Also, it's a good idea to add <meta name="viewport" content="width=device-width, initial-scale=1"/>
to the HTML. It seems to be missing.
I have problem very similar to this: #8
I'm using this configuration:
new BundleAnalyzerPlugin({
analyzerMode: 'static',
reportFilename: './reports-index.html',
openAnalyzer: false
})
But I cannot find any generated html. What am I doing wrong?
When using the webpack.NamedChunksPlugin the bundle can't be parsed anymore by the analyzer.
Couldn't parse bundle asset "dist\version\1493729489528\js\app.js".
If I disable the plugin everything works like a charm.
Attached a bundle that can't be parsed.
app.txt
Are there definitions somewhere of exactly what "stat size", "parsed size," etc. means? I'd be happy to add these definitions to the README if they're somewhere else right now. Just lmk!
Thanks for the great plugin ✌️
With gzip-size you could report the gzipped size to complement the minified
(so minified+gzipped size).
Hi,
I saw that this project doesn't currently have a CI service set up. Would you like to have one? I could whip together a PR for any CI service you'd like, so that we could get automated tests for every new Pull Request easily and to avoid regressions 😄
Was working brilliantly till I attempted to update to WebPack 2.2.0
How do you use this module? As CLI utility or as plugin?
Tried both, same result
If CLI, what command was used? (e.g. webpack-bundle-analyzer -O path/to/stats.json
)
If plugin, what options were provided? (e.g. new BundleAnalyzerPlugin({ analyzerMode: 'disabled', generateStatsFile: true })
)
No options, just the defaults
Can't generate stats.json as it blows up before then.
Could't analyze webpack bundle:
TypeError: currentFolder.addModule is not a function
Could't find any javascript bundles in provided stats file
new BundleAnalyzerPlugin({ generateStatsFile: true, statsFilename: 'xxx.json' })
./node_modules/.bin/webpack-bundle-analyzer ~/online5/build/public/xxx.json -p 8888
Could't analyze webpack bundle:
TypeError: Cannot read property 'end' of undefined
Problem appears in production build of our application, which have no build-in server. In dev-mode all good.
During "npm instal" ejs is listed, but when I ran webpack it fails on Error: Cannot find module 'ejs'
, so I tried to install ejs manually "npm i ejs" and it works now. Probably some issue with ejs project it self. But at least you should know about this. Thaks for your great tool btw ;)
Running analyzer in server mode causes an express error
Error: ENOENT: no such file or directory, open '/Users/sandro/Documents/PersonalProjects/webpack-bunle-analyzer-ejs/node_modules/webpack-bundle-analyzer/views/('style', { filename: 'viewer.css' })'
if project has nightwatch as a dependency.
I found that nightwatch also has ejs as a dependency but version 0.8.3 from https://github.com/tj/ejs. It's installed by NPM in the root of project's node_modules.
ejs 2.5.2 (https://github.com/mde/ejs) required by webpack-bundle-analyzer is installed in node_modules/webpack-bundle-analyzer/node_modules.
I haven't figured out why but looks like express tries to use ejs from project's node_modules and that version has incompatible include
syntax.
Instead of starting an HTTP server, is there a way to simply output the generated HTML files (and necessary resources) into static files in a chosen folder?
This would allow us to create simple reports for each build in our CI system.
Thanks for the plugin, it's really cool! 👍
Running into this issue:
Unable to find bundle asset "/filename_settings.js".
Analyzer will use module sizes from stats file.
Could't analyze webpack bundle:
TypeError: currentFolder.addFile is not a function
I just included BundleAnalyzerPlugin
. My webpack
bundle has multiple entry points and I'm only including the plugin by adding new BundleAnalyzerPlugin()
.
My webpack
version is 1.13.2
.
We have a project where we generate multiple entry points at once, but we would like the stats to be reported independently (per entry point).
Pretty much a whitelist (or blacklist) option for the entry points that should be included int he analyzer output.
I tried using the statsOptions
, but after reading through some of the source I think this has no effect on the generated visuals. The change would probably need to live somewhere here: https://github.com/th0r/webpack-bundle-analyzer/blob/master/src/analyzer.js#L29-L35
How do you use this module? As CLI utility or as plugin?
as a plugin via:
new BundleAnalyzerPlugin({
analyzerMode: 'static',
defaultSizes: 'stat',
reportFilename: 'stats.html',
openAnalyzer: false,
statsOptions: {
exclude: [/editor/] // <- here is my attempt to hide a specific chunk
},
})
Happy to open a pull request to make this work.
I'm using webpack in watch mode, and the bundle analyzer to analyze/serve the analysis in browser. The initial run works great, but when I modify a file, the bundle analyzer causes the process to crash with the following error:
events.js:160
throw er; // Unhandled 'error' event
^
Error: listen EADDRINUSE :::8888
at Object.exports._errnoException (util.js:1022:11)
at exports._exceptionWithHostPort (util.js:1045:20)
at Server._listen2 (net.js:1262:14)
at listen (net.js:1298:10)
at Server.listen (net.js:1376:9)
at Function.listen (C:\project\node_modules\express\lib\application.js:617:24)
at Object.startServer (C:\project\node_modules\webpack-bundle-analyzer\lib\viewer.js:58:14)
at BundleAnalyzerPlugin.startAnalyzerServer (C:\project\node_modules\webpack-bundle-analyzer\lib\BundleAnalyzerPlugin.js:94:12)
at C:\project\node_modules\webpack-bundle-analyzer\lib\BundleAnalyzerPlugin.js:60:24
at C:\project\node_modules\webpack-bundle-analyzer\lib\BundleAnalyzerPlugin.js:72:20
at Array.forEach (native)
at Immediate.<anonymous> (C:\project\node_modules\webpack-bundle-analyzer\lib\BundleAnalyzerPlugin.js:71:19)
at runCallback (timers.js:651:20)
at tryOnImmediate (timers.js:624:5)
at processImmediate [as _immediateCallback] (timers.js:596:5)
Looks like it's trying to create a new server with the same port to host the file.
How do you use this module?
As a plugin in my webpack.config.js
file
If plugin, what options were provided?
const bundleAnalyzerPlugin = new BundleAnalyzer({
analyzerMode: "server",
analyzerPort: 8888,
openAnalyzer: true,
generateStatsFile: true,
statsFilename: "build.stats.json",
statsOptions: null,
logLevel: "info"
});
What other Webpack plugins were used?
"html-webpack-plugin": "^2.26.0"
...
How do you use this module? As CLI utility or as plugin?
would like to use as CLI utility. But can't create stats.json
If CLI, what command was used? (e.g. webpack-bundle-analyzer -O path/to/stats.json
)
If plugin, what options were provided? (e.g. new BundleAnalyzerPlugin({ analyzerMode: 'disabled', generateStatsFile: true })
)
What other Webpack plugins were used?
It would be nice to also attach webpack stats file.
It can be generated using these options:
new BundleAnalyzerPlugin({
analyzerMode: 'disabled',
generateStatsFile: true,
// Excludes module sources from stats file so there won't be any sensitive data
statsOptions: { source: false }
})`
stats.json
will be created in Webpack bundle output directory.
Throws an error when an external sourceMap file (*.map.js) is part of the stats.json. I believe the problem is when acorn is trying to parse the file.
This could easily be fixed by ignoring all sourceMap files, but am not sure if this is the right approach.
https://webpack.js.org/api/node/#compiling-to-memory
I want to use webpack-bundle-analyzer
with memory-fs
, for not output to the specified files on disk. But this will cause error:
Couldn't parse bundle asset "F:\projects\businessmap-app\.analyse\scripts\c-condition.c9ded9.js".
How do you use this module? As CLI utility or as plugin?
plugin
If CLI, what command was used? (e.g. webpack-bundle-analyzer -O path/to/stats.json
)
If plugin, what options were provided? (e.g. new BundleAnalyzerPlugin({ analyzerMode: 'disabled', generateStatsFile: true })
)
new BundleAnalyzerPlugin({
generateStatsFile: true
})
For some reason, I can't provide the full info about webpack config file. Maybe try a demo with memory-fs
will reproduce the issue. Thx.
It''d be very helpfull to see actual size of the bundle (and each part) after any minification/optimization plugins were applyed.
Main reason - some code might be removed, merged and agressive minified. And it might great change overall sizes map.
Currently, it shows bundle parts sizes likely before minification/optimization.
Also, it'd be great, if webpack-bundle-analyzer were able to show actual info depend on which place it was placed in the "pluguns" array (before or after some plugins)
I have next "plugins" array:
`plugins: [
// Define free variables
// https://webpack.github.io/docs/list-of-plugins.html#defineplugin
new webpack.DefinePlugin({
'process.env.NODE_ENV': isDebug ? '"development"' : '"production"',
'process.env.BROWSER': true,
__DEV__: isDebug,
}),
// Emit a file with assets paths
// https://github.com/sporto/assets-webpack-plugin#options
new AssetsPlugin({
path: path.resolve(__dirname, '../build'),
filename: 'assets.js',
processOutput: x => `module.exports = ${JSON.stringify(x)};`,
}),
// Assign the module and chunk ids by occurrence count
// Consistent ordering of modules required if using any hashing ([hash] or [chunkhash])
// https://webpack.github.io/docs/list-of-plugins.html#occurrenceorderplugin
new webpack.optimize.OccurrenceOrderPlugin(true),
...isDebug ? [] : [
// Search for equal or similar files and deduplicate them in the output
// https://webpack.github.io/docs/list-of-plugins.html#dedupeplugin
new webpack.optimize.DedupePlugin(),
// Minimize all JavaScript output of chunks
// https://github.com/mishoo/UglifyJS2#compressor-options
new webpack.optimize.UglifyJsPlugin({
compress: {
screw_ie8: true,
warnings: isVerbose,
},
}),
],
// Webpack plugin and CLI utility that represents bundle
// content as convenient interactive zoomable treemap
// https://github.com/th0r/webpack-bundle-analyzer
new BundleAnalyzerPlugin({
// Can be `server`, `static` or `disabled`.
// In `server` mode analyzer will start HTTP server to show bundle report.
// In `static` mode single HTML file with bundle report will be generated.
// In `disabled` mode you can use this plugin to just generate
// Webpack Stats JSON file by setting `generateStatsFile` to `true`.
analyzerMode: isReport ? 'static' : 'disabled',
// Port that will be used by in `server` mode to start HTTP server.
analyzerPort: 8888,
// Path to bundle report file that will be generated in `static` mode.
// If relative path is provided, it will be relative to bundles output directory
reportFilename: 'ui-report.html',
// Automatically open report in default browser
openAnalyzer: isReport,
// If `true`, Webpack Stats JSON file will be generated in bundles output directory
generateStatsFile: false,
// Name of Webpack Stats JSON file that will be generated if `generateStatsFile` is `true`.
// Relative to bundles output directory.
statsFilename: 'ui-stats.json',
}),
],`
I am using grunt to run webpack-dev-server and build webpack modules, but when run grunt default task it fails, I use inspect-process to debug the issue and found this.activeLevels.has is not a function
, more exactly the error occurs with webpack-dev-server
task
inspect --debug-exception grunt
Stacktrace
TypeError: this.activeLevels.has is not a function
at Object.Logger.(anonymous function) [as info] (/home/leosuncin/Workspaces/TadeoSystems/pet-retail/node_modules/webpack-bundle-analyzer/lib/Logger.js:70:27)
at Object.generateStatsFile (/home/leosuncin/Workspaces/TadeoSystems/pet-retail/node_modules/webpack-bundle-analyzer/lib/BundleAnalyzerPlugin.js:90:17)
at /home/leosuncin/Workspaces/TadeoSystems/pet-retail/node_modules/webpack-bundle-analyzer/lib/BundleAnalyzerPlugin.js:49:24
at /home/leosuncin/Workspaces/TadeoSystems/pet-retail/node_modules/webpack-bundle-analyzer/lib/BundleAnalyzerPlugin.js:72:20
at Array.forEach (native)
at Immediate.<anonymous> (/home/leosuncin/Workspaces/TadeoSystems/pet-retail/node_modules/webpack-bundle-analyzer/lib/BundleAnalyzerPlugin.js:71:19)
at runCallback (timers.js:649:20)
at tryOnImmediate (timers.js:622:5)
at processImmediate [as _immediateCallback] (timers.js:594:5)
My webpack.config.js
'use strict'
const resolve = require('path').resolve
const webpack = require('webpack')
const merge = require('webpack-merge')
const VisualizerPlugin = require('webpack-visualizer-plugin')
const StyleLintPlugin = require('stylelint-webpack-plugin')
const ExtractTextPlugin = require('extract-text-webpack-plugin')
const {BundleAnalyzerPlugin} = require('webpack-bundle-analyzer')
const PORT = process.env.WEBPACK_PORT || 1635
const common = {
entry: {
dependencies: [],
dashboard: 'js/dashboard',
mobile: 'js/mobile',
main: [
'babel-polyfill',
'js/main.js',
],
},
output: {
path: resolve('.tmp/public'),
filename: 'js/[name].js',
publicPath: '/',
},
target: 'web',
context: resolve('assets'),
resolve: {
extensions: ['', '.js', '.scss', '.less', '.css', '.html', '.json'],
root: [
resolve('assets'),
resolve('node_modules'),
resolve('bower_components'),
],
moduleDirectories: ['node_modules', 'bower_components'],
},
plugins: [
new StyleLintPlugin({
files: 'styles/**/*.{css,sass,scss,sss}',
}),
new VisualizerPlugin({filename: 'webpack-stats.html'}),
new ExtractTextPlugin('production' === process.env.NODE_ENV ?
'min/[name]-[chunkhash].min.css' : 'styles/[name].css'
),
new BundleAnalyzerPlugin({
analyzerMode: 'server', // 'static',
reportFilename: resolve('.tmp/public/report.html'),
openAnalyzer: false,
generateStatsFile: true,
statsFilename: resolve('.tmp/public/stats.json'),
logLevel: 'silent',
}),
],
failOnError: true,
module: {
preLoaders: [
{
test: /\.js$/i,
loader: 'eslint',
exclude: /(node_modules|bower_components)/,
}, {
test: /\.(jpg|jpeg|png|gif|svg)$/i,
loader: 'image-webpack',
query: {
bypassOnDebug: true,
},
},
],
loaders: [
{
test: /\.js$/i,
loader: 'babel',
exclude: /node_modules/,
}, {
test: /\.css$/i,
loader: ExtractTextPlugin.extract([
'css?sourceMap&importLoaders=1',
'postcss?sourceMap',
]),
}, {
test: /\.less$/i,
loader: ExtractTextPlugin.extract([
'css?sourceMap&importLoaders=1',
'postcss',
'less?sourceMap',
]),
}, {
test: /\.s[ac]ss$/i,
loader: ExtractTextPlugin.extract([
'css?sourceMap&importLoaders=1',
'postcss',
'sass?sourceMap',
]),
}, {
test: /\.html$/i,
loader: 'html',
}, {
test: /\.(jpg|jpeg|webp|png|gif)$/i,
loader: 'file',
query: {
name: 'images/[name].[ext]',
},
}, {
test: /\.svg/i,
loader: 'svg-url',
query: {
limit: 20480,
},
}, {
test: /\.woff(\?v=\d+(\.\d+\.\d+)?)?$/i,
loader: 'url',
query: {
mimetype: 'application/font-woff',
name: 'fonts/[name].[ext]',
},
}, {
test: /\.woff2(\?v=\d+(\.\d+\.\d+)?)?$/i,
loader: 'url',
query: {
mimetype: 'application/font-woff2',
name: 'fonts/[name].[ext]',
},
}, {
test: /\.[ot]tf(\?v=\d+(\.\d+\.\d+)?)?$/,
loader: 'url',
query: {
mimetype: 'application/octet-stream',
name: 'fonts/[name].[ext]',
},
}, {
test: /\.eot(\?v=\d+(\.\d+\.\d+)?)?$/i,
loader: 'url',
query: {
mimetype: 'application/vnd.ms-fontobject',
name: 'fonts/[name].[ext]',
},
}, {
test: /\.svg(\?v=\d+(\.\d+\.\d+)?)?$/i,
loader: 'url',
query: {
mimetype: 'image/svg+xml',
name: 'fonts/[name].[ext]',
},
},
],
},
}
const dev = {
entry: {
main: [
'webpack/hot/dev-server',
`webpack-dev-server/client?http://0.0.0.0:${PORT}/`,
'babel-polyfill',
resolve('assets/js/main.js'),
],
},
plugins: [
new webpack.DefinePlugin({
'PRODUCTION': false,
'process.env': {
NODE_ENV: JSON.stringify('development'),
},
}),
new webpack.HotModuleReplacementPlugin({
multiStep: true,
}),
new webpack.optimize.CommonsChunkPlugin({
name: 'common',
filename: 'js/common.js',
}),
],
debug: true,
devtool: 'source-map',
stats: {
errorDetails: true,
colors: true,
modules: true,
reasons: true,
},
}
const dist = {
output: {
filename: 'min/[name]-[chunkhash].min.js',
chunkFilename: '[chunkhash].js',
},
plugins: [
new webpack.DefinePlugin({
'PRODUCTION': false,
'process.env': {
NODE_ENV: JSON.stringify('development'),
},
}),
new webpack.optimize.OccurenceOrderPlugin(),
new webpack.optimize.DedupePlugin(),
new webpack.optimize.CommonsChunkPlugin({
name: 'common',
filename: 'min/common-[chunkhash].min.js',
}),
new webpack.optimize.UglifyJsPlugin({
output: {
comments: false,
},
compress: {
drop_console: true, /* eslint camelcase: off */
},
}),
],
}
module.exports = merge.smart(common,
'production' === process.env.NODE_ENV ? dist : dev
)
My grunt task for webpack
module.exports = function(grunt) {
const config = require('../../webpack.config')
const PORT = process.env.WEBPACK_PORT || 1635
grunt.config.set('webpack', {
build: config,
})
config.plugins = config.plugins.filter(plugin =>
!(plugin instanceof require('webpack-visualizer-plugin'))
)
grunt.config.set('webpack-dev-server', {
options: {
contentBase: '.tmp/public',
// https: true,
historyApiFallback: true,
port: PORT,
host: '0.0.0.0',
hot: true,
inline: true,
open: true,
proxy: {
'*': {
target: 'http://localhost:1337',
},
},
webpack: config,
},
start: {
failOnError: false,
progress: false,
watch: true,
watchOptions: {
aggregateTimeout: 500,
poll: true,
},
keepalive: true,
stats: 'errors-only',
},
})
grunt.loadNpmTasks('grunt-webpack')
}
When this package, at its latest versions, is integrated with CircleCI, it gets caught in the build stage.
If this package is removed, the build stage completes successfully.
From both a config object and the cli tool, I'd like the ability to set the initial view for the file size out to be set to 'Gzipped' or any other available option.
Thanks for the great work.
Error in script.
Console said © Cannot read property 'parsedSize' of undefined
850: r.hasParsedSizes = "number" == typeof r.props.data[0].parsedSize,
I have quite big report generated for ~4Mb bundle.
While navigating it browser hangs and after time suggests to kill the tab.
This occurs almost immediately in Chrome. In Firefox it lasts a bit longer, but hangs after 3 or 4 navigations. Surprisingly works well in Edge, which shows that this browser could be used at least for something.
I use it as a plugin to generate static report.
If plugin, what options were provided?
new BundleAnalyzerPlugin({
// Can be `server`, `static` or `disabled`.
// In `server` mode analyzer will start HTTP server to show bundle report.
// In `static` mode single HTML file with bundle report will be generated.
// In `disabled` mode you can use this plugin to just generate Webpack Stats JSON file by setting `generateStatsFile` to `true`.
analyzerMode: 'static',
// Path to bundle report file that will be generated in `static` mode.
// Relative to bundles output directory.
reportFilename: '../reports/bundle-analyzer-report.html',
// Automatically open report in default browser
openAnalyzer: false,
// If `true`, Webpack Stats JSON file will be generated in bundles output directory
generateStatsFile: false,
// Log level. Can be 'info', 'warn', 'error' or 'silent'.
logLevel: 'info'
})
What other Webpack plugins were used?
I thing that is not relevant
Stats.json attached.
stats.zip
Anyway thanks for awesome tool!
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.