Coder Social home page Coder Social logo

webpack-visualizer's Introduction

Webpack Visualizer

Visualize and analyze your Webpack bundle to see which modules are taking up space and which might be duplicates.

This tool is still pretty new, so please submit issues or feature requests!

Site Usage

Upload your stats JSON file to the site: chrisbateman.github.io/webpack-visualizer/

Plugin Usage

npm install webpack-visualizer-plugin
var Visualizer = require('webpack-visualizer-plugin');

//...
plugins: [new Visualizer()],
//...

This will output a file named stats.html in your output directory. You can modify the name/location by passing a filename parameter into the constructor.

var Visualizer = require('webpack-visualizer-plugin');

//...
plugins: [new Visualizer({
  filename: './statistics.html'
})],
//...

webpack-visualizer's People

Contributors

alfredmachineuser avatar blikblum avatar chrisbateman avatar dean177 avatar swashcap 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

webpack-visualizer's Issues

Add support for multiple configs

Since you are able to put multiple Webpack configs in to an array, it would be nice to use the outcome of that JSON as well! Maybe using a dropdown menu to switch between the modules. This might be a special case, but it is really easy to implement.

var modules = json.modules;

if (json.children) {
    modules = json.children[index].modules;    
}

Doesn't work with Angular CLI output

I have an stats.json file from fresh and empty Angular CLI 6.2.3 project.

I generated it with ng build --stats-json

When I try to upload it I get an error

TypeError: t is undefined[Learn More] build.js:23:11036
n
https://chrisbateman.github.io/webpack-visualizer/build.js:23:11036
handleFileUpload
https://chrisbateman.github.io/webpack-visualizer/build.js:18:5209
handleFileUpload self-hosted:986:17 n/n.onloadend
https://chrisbateman.github.io/webpack-visualizer/build.js:23:9878

Uncaught SyntaxError: Unexpected token p

Any idea what might be causing this?

All I see in the chrome console is this when I load the stats.html

Uncaught SyntaxError: Unexpected token p(anonymous function) @ stats.html:165

Output looks pretty normal, but I do have a very complex config.

//webpack.config.js
//main webpack config
var webpack = require('webpack');
var path = require('path');
var fs = require('fs');
var WebpackStrip = require('strip-loader');
var CachePlugin = require('webpack/lib/CachePlugin');
var PassthruPlugin = require('./webpack-utils/passthru-plugin');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
var NyanProgressPlugin = require('nyan-progress-webpack-plugin');
var ProgressPlugin = require('./webpack-utils/progress-plugin');
var Visualizer = require('webpack-visualizer-plugin');
var RewirePlugin = require('rewire-webpack');
var StatsPlugin = require('stats-webpack-plugin');
var AssetsPlugin = require('assets-webpack-plugin');
var nodeCDN = process.env.NODE_ENV === 'production' ? '//nodecdn.dslam.com/dist/' : '/dist/';
var lifterParams = '?testString=scss&prefix=dist/images&manifest=rev-manifest&outputDir=' + path.join(__dirname, 'public', 'dist');  // add &outputStyle=compressed for prod
var manifestParams = {
    debug: false,
    limit: 5000,
    hash: 'sha512',
    digest: 'hex',
    relativeSplit: 'images/',
    prefix: nodeCDN +'images',
    manifest: 'rev-manifest',
    outputDir: path.join(__dirname, 'public', 'dist')
};
var DeepMerge = require('deep-merge');
var consoleAvailable = (process.argv.indexOf('--profile') === -1 &&
    process.env.NODE_ENV !== 'production' &&
    process.env.NODE_ENV !== 'integration');
var node_modules_dir = path.join(__dirname, 'node_modules');
var deps = [
    'velocity-animate/velocity.min.js',
    'mobile-detect/mobile-detect.min.js',
    'numeral/min/numeral.min.js'
];

var myCache = {};
var productionPlugins = [
    new webpack.optimize.UglifyJsPlugin({
        output: {
            comments: false
        }
    })
];
var productionLoaders = [
    { test: /\.js$/, loader: WebpackStrip.loader('debug', 'console.log') }
];

var deepmerge = DeepMerge(function(target, source, key) {
    if (target instanceof Array) {
        return [].concat(target, source);
    }
    return source;
});

function config(overrides) {
    return deepmerge(defaults, overrides || {});
}

//require common.js for node_modules (better for server)
var node_modules = fs.readdirSync('node_modules').filter(function(x) { return x !== '.bin' });
function node_externals(context, request, cb) {
    if (node_modules.indexOf(request) !== -1) {
        cb(null, 'commonjs ' + request);
        return;
    }
    cb();
}

//require common.js for configs, manifests that might change
var dist_dir  = fs.readdirSync(path.join(__dirname, 'public', 'dist')).filter(function(x) {
    if (x.indexOf('.json') > -1) {
        return x
    }
});

var config_modules  = ['states-json.json'].concat(dist_dir);

function config_externals(context, request, cb) {
    var clean_request = request.split('/').splice(-1)[0];
    if (config_modules.indexOf(clean_request) !== -1) {
        cb(null, 'commonjs ' + request);
        return;
    }
    cb();
}

var test = {
    name: 'karma webpack',
    devtool: 'eval',
    target: 'web',
    node: {
        __dirname: true,
        __filename: true,
        fs: 'empty',
        tls: 'empty',
        net: 'empty',
        module: 'empty',
        console: true
    },
    module: {
        unknownContextRegExp: /$^/,
        exprContextRegExp: /$^/,
        unknownContextCritical: false,
        exprContextCritical: false,
        loaders: [
            {
                test: /\.json$/,
                loaders: ['json-loader']
            }
            , {
                include: [
                    path.resolve(__dirname, 'app'),
                    path.resolve(__dirname, 'test')
                ],
                test: /\.jsx$/,
                loader: 'babel-loader',
                query: {
                    presets: ['es2015', 'stage-0', 'react']
                }
            }, {
                test: /\.scss$/,
                loader: 'noop-loader'
            }
            , {
                test: /\.(jpe?g|png|gif|svg)$/i,
                loaders: [
                    'passthru-loader'
                ]
            }
            , {
                test: /sinon.*\.js$/,
                loader: 'imports?define=>false'
            }
        ],
        postLoaders: [ { // << add subject as webpack's postloader
            test: /\.js$/,
            exclude: /(test|node_modules|bower_components)\//,
            loader: 'istanbul-instrumenter'
        } ]
    },
    resolve: {
        root: path.join(__dirname),
        fallback: path.join(__dirname, 'node_modules'),
        modulesDirectories: ['app', 'images', 'node_modules'],
        extensions: ['', '.json', '.js', '.jsx', '.scss', '.png', '.jpg', '.jpeg', '.gif']
    },
    resolveLoader: {
        root: __dirname,
        fallback: __dirname + '/node_modules',
        alias: {
            'noop-loader': path.join(__dirname,  'webpack-utils', 'noop-loader'),
            'passthru-loader': path.join(__dirname, 'webpack-utils', 'passthru-loader')
        }
    },
    output: {
        path: '/',
        filename: 'testBundle.js'
    },
    alias : {
        'fsevents' : ''
    },
    plugins: [
        new NyanProgressPlugin(),
        new RewirePlugin(),
        new webpack.DefinePlugin({
            __CLIENT__: true,
            __SERVER__: false,
            __PRODUCTION__: JSON.stringify(process.env.NODE_ENV) === 'production',
            __DEV__: JSON.stringify(process.env.NODE_ENV) !== 'production'
        })
    ]
};

var client = {
    name: 'client side webpack',
    target: 'web',
    entry: {
        rehydrate: path.join(__dirname, 'app/rehydrate'),
        app: path.join(__dirname, 'app/app.jsx')
    },
    output: {
        path: path.join(__dirname, 'public/dist'),
        publicPath: nodeCDN,
        filename: '[name].bundle.[hash].js',
        chunkFilename: '[name].chunk.[chunkhash].js'
    },
    resolveLoader: {
        alias: {
            'lift-sass': path.join(__dirname, 'webpack-utils', 'passthru-loader'),
            'react-router-proxy$': 'react-router-proxy-loader'
        }
    },
    module: {
        loaders: [
            {
                test: /\.scss$/,
                loader: ExtractTextPlugin.extract('style-loader', 'css!sass')
            }
            , {
                test: /\.(jpe?g|png|gif|svg)$/i,
                loader: 'gulp-rev-loader',
                query: manifestParams
            }
        ],
        noParse: [path.join(__dirname, 'app', 'lodash.custom.min.js')]
    },
    plugins: [
        new webpack.optimize.CommonsChunkPlugin({
            name: 'commons',
            filename: 'commons.bundle.[hash].js',
            //minChunks: 2,
            chunks: ['rehydrate', 'app']
        }),
        new ExtractTextPlugin('style.[name].[chunkhash].css', {
            disable: false,
            allChunks: true // extract all css from async chunks as well
        }),
        new webpack.DefinePlugin({
            __CLIENT__: true,
            __SERVER__: false,
            __PRODUCTION__: JSON.stringify(process.env.NODE_ENV) === 'production',
            __DEV__: JSON.stringify(process.env.NODE_ENV) !== 'production'
        }),
        new StatsPlugin('webpack-stats.json', {
            assetsByChunkName: false,
            source: false,
            reasons: false,
            modules: false,
            chunks: false
        }),
        new AssetsPlugin({
            filename: 'public/dist/webpack-assets.json',
            prettyPrint: true,
            update: false,
            processOutput: function (assets) {
                return JSON.stringify(Object.assign({assets: assets}, {publicPath: nodeCDN}));
            }
        }),
        new webpack.ProvidePlugin({
            'Promise': 'native-promise-only'
        })
    ],
    resolve: {
        alias: {
            'lodash$' : path.join(__dirname, 'assets', 'scripts', 'lodash.custom.min.js')
        }
    }

};

var server = {
    name: 'server side webpack',
    target: 'node',
    devtool: 'source-map',
    entry: {
        index: path.join(__dirname, 'index.js')
    },
    output: {
        libraryTarget: 'commonjs2',
        path: path.join(__dirname, 'server', 'dist'),
        publicPath: nodeCDN,
        filename: '[name].js'
    },
    resolveLoader: {
        alias: {
            'react-router-proxy$': path.join(__dirname, 'webpack-utils', 'passthru-loader'),
            'lift-sass': path.join(__dirname, 'webpack-utils', 'passthru-loader')
        }
    },
    module: {
        loaders: [
            {
                test: /\.scss$/,
                loader: 'noop-loader'
            }
            , {
                test: /\.(jpe?g|png|gif|svg)$/i,
                loader: 'gulp-rev-loader',
                query: manifestParams
            }
        ]
    },
    plugins: [
        new webpack.DefinePlugin({
            __CLIENT__: false,
            __SERVER__: true,
            __PRODUCTION__: JSON.stringify(process.env.NODE_ENV) === 'production',
            __DEV__: JSON.stringify(process.env.NODE_ENV) !== 'production'
        }),
        new webpack.BannerPlugin('require("source-map-support").install();',
            { raw: true, entryOnly: false })
    ],
    externals: [{ 'react' : true, 'newrelic' : true }, node_externals, config_externals]
};

var integration_client = {
    devtool: false,
    plugins: productionPlugins,
    bail: true,
    debug: false
};

var integration_server = {
    devtool: false,
    plugins: productionPlugins,
    resolveLoader: {
        alias: {
            'lift-sass': path.join(__dirname, 'webpack-utils', 'passthru-loader')
        }
    },
    bail: true,
    cache: false,
    debug: false
};

var production_client = {
    output: {
        publicPath : nodeCDN
    },
    devtool: false,
    plugins: productionPlugins,
    bail: true,
    cache: false,
    debug: false,
    module: {
        loaders: productionLoaders
    }
};

var production_server = {
    output: {
        publicPath : nodeCDN
    },
    devtool: false,
    plugins: productionPlugins,
    resolveLoader: {
        alias: {
            'lift-sass': path.join(__dirname, 'webpack-utils', 'passthru-loader')
        }
    },
    bail: true,
    cache: false,
    debug: false,
    module: {
        loaders: productionLoaders
    }
};

var defaults = {
    context: __dirname,
    node: {
        __dirname: true,
        __filename: true,
        fs: 'empty',
        tls: 'empty',
        net: 'empty',
        console: true
    },
    devtool: '#eval-source-map',
    externals: [/^config[a-z\-0-9]+$/],
    resolve: {
        root: path.join(__dirname),
        fallback: path.join(__dirname, 'node_modules'),
        modulesDirectories: ['app', 'images', 'node_modules'],
        extensions: ['', '.json', '.js', '.jsx', '.scss', '.png', '.jpg', '.jpeg', '.gif'],
        alias: {}
    },
    plugins: [
        new Visualizer(),
        new ProgressPlugin({console :  consoleAvailable}),
        new CachePlugin(myCache),
        new webpack.optimize.DedupePlugin(),
        new webpack.optimize.OccurrenceOrderPlugin(true),
        new webpack.DefinePlugin({
            'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV) || '"development"',
            'process.env.BUILD_NUMBER': JSON.stringify(process.env.BUILD_NUMBER) || '"42"'
        })
    ],
    resolveLoader: {
        root: __dirname,
        fallback: __dirname + '/node_modules',
        alias: {
            'noop-loader': path.join(__dirname,  'webpack-utils', 'noop-loader'),
            'passthru-loader': path.join(__dirname, 'webpack-utils', 'passthru-loader')
        }
    },
    module: {
        // Disable handling of unknown requires and requires with a single expression
        unknownContextRegExp: /$^/,
        exprContextRegExp: /$^/,
        unknownContextCritical: false,
        exprContextCritical: false,
        loaders: [
            {
                test: /\.json$/,
                loaders: ['json-loader']
            }
            , {
                include: [
                    path.resolve(__dirname, 'app'),
                    path.resolve(__dirname, 'server')
                ],
                test: /\.jsx$/,
                loader: 'babel-loader',
                query: {
                    presets: ['es2015', 'stage-0', 'react']
                }
            }
        ],
        noParse: []
    },
    bail: false,
    cache: true,
    debug: true
};

// file and make sure webpack does not try to parse it
deps.forEach(function(dep) {
    var depPath = path.resolve(node_modules_dir, dep);
    defaults.resolve.alias[dep.split(path.sep)[0]] = depPath;
    defaults.module.noParse.push(depPath);
});


module.exports = process.argv.indexOf('--profile') === -1 ? [config(client), config(server)] : config(client);
module.exports.integration = [config(deepmerge(client, integration_client)), config(deepmerge(server, integration_server))];
module.exports.production = [config(deepmerge(client, production_client)), config(deepmerge(server, production_server))];
module.exports.test = test;

how about a CLI version

Something like

$ visualize stats.json

which will proceed to build chart and open web page (locally)

'error writing stats file'

i install this plugin and add the configuration in the webpack.config.js according to the readme file,but when i run the npm start,the error above occured, anyone can show me how to solve this error? thks

should not add generated statistics to assets

When adding Visualizer to the webpack plugins the generated html file is also listed as an emitted asset and thus triggers a warning about exceeding the recommended asset size limit. Is there a way to remove it from that ?

Add legend to chart.

The chart is neat. But it hard to understand what colors are represent. Maybe it is good idea to add legend?

Huge discrepancy for minified size?

I was puzzled by the fact that my react-dom dependency is 506KB raw and 200KB minified, while the official build is 600KB raw and 120KB minified.

I tried comparing minification settings etc before thinking of simply creating an entry with only react-dom. That one has the minified react-dom at 109KB, much nicer and to be expected from tree shaking vs the full minified build.

So now I wonder, what causes the discrepancy between the minified size in my app.js vs the react-dom-only entry? Is there actually more code in the react-dom in my app.js? Are parts counted differently? All the minified sizes do seem to add up to the full minified size…

React 15

React 15 has been out for a while. I like this plugin but I need to drop it from my project until it is bumped to support it.

image

Any plans to bump up the dependency?

Squash 1:1 nested rings

Add option to de-duplicate rings that don't convey information.

If you look at: https://aui-cdn.atlassian.com/atlaskit/pr/stats/e50623ba0ad8b839ba1ebce33cfd49d507823f01/ak-editor-toolbar-hyperlink/cjs.html

You can see a few rings that only represent folders. Each folder only has one subfolder, so the nesting is very deep, but there is no new information added or branching conveyed. It would be great if these rings could be squashed, so the output becomes more meaningful.

TypeError: Cannot read property 'modules' of undefined

I have a set of stats that gives me errors—curiously, different errors in different browsers, for the exact same stats (though it’s consistent between my local HTML and the online site). In Chrome:

Uncaught TypeError: Cannot read property 'modules' of undefined
    at e.onAssetChange (http://chrisbateman.github.io/webpack-visualizer/build.js:18:5684)
    at Object.executeOnChange (http://chrisbateman.github.io/webpack-visualizer/build.js:16:22674)
    at g.i (http://chrisbateman.github.io/webpack-visualizer/build.js:16:29988)
    at Object.r (http://chrisbateman.github.io/webpack-visualizer/build.js:1:28940)
    at a (http://chrisbateman.github.io/webpack-visualizer/build.js:1:27763)
    at Object.u [as executeDispatchesInOrder] (http://chrisbateman.github.io/webpack-visualizer/build.js:1:27974)
    at f (http://chrisbateman.github.io/webpack-visualizer/build.js:1:24401)
    at h (http://chrisbateman.github.io/webpack-visualizer/build.js:1:24527)
    at Array.forEach (native)
    at n (http://chrisbateman.github.io/webpack-visualizer/build.js:1:29425)

In Firefox:

TypeError: i.chunk is undefined[Learn More]  build.js:18:5675
	e.default<.onAssetChange http://chrisbateman.github.io/webpack-visualizer/build.js:18:5675
	bound  self-hosted
	h.executeOnChange http://chrisbateman.github.io/webpack-visualizer/build.js:16:22663
	i http://chrisbateman.github.io/webpack-visualizer/build.js:16:29986
	bound i self-hosted
	r http://chrisbateman.github.io/webpack-visualizer/build.js:1:28940
	a http://chrisbateman.github.io/webpack-visualizer/build.js:1:27761
	u http://chrisbateman.github.io/webpack-visualizer/build.js:1:27974
	f http://chrisbateman.github.io/webpack-visualizer/build.js:1:24399
	h http://chrisbateman.github.io/webpack-visualizer/build.js:1:24527
	forEach self-hosted
	n http://chrisbateman.github.io/webpack-visualizer/build.js:1:29423
	v.processEventQueue http://chrisbateman.github.io/webpack-visualizer/build.js:1:25647
	r http://chrisbateman.github.io/webpack-visualizer/build.js:1:29529
	i.handleTopLevel http://chrisbateman.github.io/webpack-visualizer/build.js:1:29636
	a http://chrisbateman.github.io/webpack-visualizer/build.js:17:4352
	i http://chrisbateman.github.io/webpack-visualizer/build.js:17:4168
	o.perform http://chrisbateman.github.io/webpack-visualizer/build.js:15:12491
	p.batchedUpdates http://chrisbateman.github.io/webpack-visualizer/build.js:16:7078
	i http://chrisbateman.github.io/webpack-visualizer/build.js:15:8436
	m.dispatchEvent http://chrisbateman.github.io/webpack-visualizer/build.js:17:5240
	bound  self-hosted

Don't display unused harmony exports

From the JSON:

          "usedExports": [
            "Button",
            "Modal",
            "TextInput",
            "Select",
            "DatePicker",
            "ActivityIndicator"
          ],
          "providedExports": [
            "PageAndMenu",
            "Page",
            "Menu",
            "MenuButton",
            "Form",
            "Snackbar",
            "Tooltip",
            "ActivityIndicator",
            "TextInput",
            "Select",
            "Button",
            "Switch",
            "Checkbox",
            "SegmentedControl",
            "DatePicker",
            "FileUpload",
            "Modal",
            "DragAndDrop",
            "CanDrop",
            "File",
            "FILE",
            "Files",
            "FILES"
          ],

And it displays the full providedExports list with the corresponding sizes though they clearly aren't present in the resulting minified bundle.

[React Native + Babel issues] depencency issues

I'm using the plugin together with newest React Native, React 15 and Babel 6. Since your plugin uses Babel 5 and older version of React, it causes some collisions (npm 3). Updating them manually solves the issue for me.

Report post-minified sizes

In #9 you mentioned this reports pre-minified sizes.
It'd be great to see the sizes after minification instead, as most bundles are used in production.

Customise port

I'm running inside a docker and I'm interested in setting a fixed port for the server. Reading it from the environment would be enough to me.

Would you consider a PR adding this feature?

DeprecationWarning: Tapable.plugin is deprecated. Use new API on `.hooks` instead

Hi,

This warning is causing, due to upgradation on Webpack 4 because they are still using the old plugin API, they need to be upgraded to the latest version.

I am getting the below error:

(node:10740) DeprecationWarning: Tapable.plugin is deprecated. Use new API on .hooks instead
[ERROR] at VisualizerPlugin.apply (C:\Users\Hp\Desktop\New folder (2)\gateway_upgrade\node_modules\webpack-visualizer-plugin\lib\plugin.js:44:22)
[ERROR] at webpack (C:\Users\Hp\Desktop\New folder (2)\gateway_upgrade\node_modules\webpack\lib\webpack.js:37:12)
[ERROR] at processOptions (C:\Users\Hp\Desktop\New folder (2)\gateway_upgrade\node_modules\webpack-cli\bin\webpack.js:437:16)
[ERROR] at yargs.parse (C:\Users\Hp\Desktop\New folder (2)\gateway_upgrade\node_modules\webpack-cli\bin\webpack.js:513:3)
[ERROR] at Object.parse (C:\Users\Hp\Desktop\New folder (2)\gateway_upgrade\node_modules\webpack-cli\node_modules\yargs\yargs.js:552:18)
[ERROR] at C:\Users\Hp\Desktop\New folder (2)\gateway_upgrade\node_modules\webpack-cli\bin\webpack.js:218:8
[ERROR] at Object. (C:\Users\Hp\Desktop\New folder (2)\gateway_upgrade\node_modules\webpack-cli\bin\webpack.js:515:3)
[ERROR] at Module._compile (module.js:652:30)
[ERROR] at Object.Module._extensions..js (module.js:663:10)
[ERROR] at Module.load (module.js:565:32)
[ERROR] at tryModuleLoad (module.js:505:12)
[ERROR] at Function.Module._load (module.js:497:3)
[ERROR] at Module.require (module.js:596:17)
[ERROR] at require (internal/module.js:11:18)
[ERROR] at Object. (C:\Users\Hp\Desktop\New folder (2)\gateway_upgrade\node_modules\webpack\bin\webpack.js:80:2)
[ERROR] at Module._compile (module.js:652:30)
[ERROR] at Object.Module._extensions..js (module.js:663:10)
[ERROR] at Module.load (module.js:565:32)
[ERROR] at tryModuleLoad (module.js:505:12)
[ERROR] at Function.Module._load (module.js:497:3)
[ERROR] at Function.Module.runMain (module.js:693:10)
[ERROR] at startup (bootstrap_node.js:191:16)
[ERROR] at bootstrap_node.js:612:3

Document command to generate site locally

Hi! I just clone this project and started playing around with it locally, but I haven't been able to figure out how to generate the site locally. What is the command? Thanks!

Does it work with Webpack 3 output?

Currently I am getting the following message:

build.js:23 Uncaught TypeError: Cannot read property 'forEach' of undefined
at n (build.js:23)
at e.handleFileUpload (build.js:18)
at FileReader.n.onloadend (build.js:23)

gzip sizes

This is a nice plugin, but it should be possible to take the actual files content (not just the size) and run an on-the-fly gzip (e.g using zlib) to calculate the correct gzipped size (at least a better approximation) ? Does the code use the file content or just the sizes ?

zlib.gzip(code, (err, zipped) => { // zipped.length })

Writing stats file fails if path doesn't exist

Since stats.html is no longer a Webpack asset (1dae984) The plugin fails to write the file if the directory doesn't exist, for example if configured to write the file to some other directory then ./dist/. Prior to the change above, Webpack took the responsibility of creating the directories.

Now, the plugin fails with error:
webpack-visualizer-plugin: error writing stats file

stats include less-loader, css-loader

The visualiser output for our project attributes a substantial proportion of our bundle to less-loader and css-loader. Their names do not appear in the bundle.

We're using webpack to handle our LESS, so webpack.json includes…

const config = validate({
    entry: [
        './src/client/styles.less',
        './src/client/index.tsx',
    ],
//...
    plugins: [
        new ExtractTextPlugin('dist/static/assets/styles.css'),
    ],
    module: {
        loaders: [
            { test: /\.json$/, loader: 'json-loader' },
            { test: /\.tsx?$/, loader: 'ts-loader' },
            { test: /\.less$/,
              loader: ExtractTextPlugin.extract("style-loader", "css-loader!postcss-loader!less-loader")
            },
            { test: /\.css$/,
              loader: ExtractTextPlugin.extract("style-loader", "css-loader!postcss-loader")

The visualiser output shows a substantial part of our bundle occupied by less-loader and css-loader despite their names not appearing anywhere in the bundle.

stats.json contains:

  "modules": [
    {
...
    },
    {
      "id": 1,
      "identifier": "~/src/project/node_modules/less-loader/stringify.loader.js!~/src/project/node_modules/bootstrap/less/mixins/text-emphasis.less",
      "name": "./~/less-loader/stringify.loader.js!./~/bootstrap/less/mixins/text-emphasis.less",
...
      "issuer": "~/src/project/node_modules/css-loader/index.js!~/src/project/node_modules/postcss-loader/index.js!~/src/project/node_modules/less-loader/index.js!~/src/project/src/client/styles.less",
...
      "reasons": [
        {
          "moduleId": 48,
          "moduleIdentifier": "~/src/project/node_modules/css-loader/index.js!~/src/project/node_modules/postcss-loader/index.js!~/src/project/node_modules/less-loader/index.js!~/src/project/src/client/styles.less",
          "module": "./~/css-loader!./~/postcss-loader!./~/less-loader!./src/client/styles.less",
          "moduleName": "./~/css-loader!./~/postcss-loader!./~/less-loader!./src/client/styles.less",
          "type": "loader",
          "userRequest": "-!~/src/project/node_modules/less-loader/stringify.loader.js!~/src/project/node_modules/bootstrap/less/mixins/text-emphasis.less"
        }

Any tips on how to follow the reasons back to the root cause?

Doesn't work with webpack-dev-server?

Is it possible for this to work when using webpack-dev-server? In my current setup I can see the stats file created in the output folder when using webpack, but when I use webpack-dev-server and visit the correct public path it just serves up my main entry, I guess because I'm using historyApiFallback... can it work?

Post CSS is throwing off numbers

We have recently started using PostCSS with our web-pack build and noticed that even though the output css files are more or less the same size; the visualizer is reporting larger sizes in the pie chart; maybe I don't fully understand the visualization generated but just want to bring this to your attention.

I know this information is a bit scarce; but if you need any information to help debug I will be glad to provide the same.

thank you very much for this project; it is very helpful

Handle dedupe'd modules

Currently, the visualizer will put a black outline on any modules which appear to be duplicated.

If these modules are being successfully de-duped, Webpack leaves those modules where they are but aliases them all to a new copy of the module, which would appear at root level in the visualizer.

So - it's kind of tough to decide how to handle this. The most accurate thing would probably be to hide the original duplicated modules and only show the new copy. The downside is that you don't see all the places where the module is actually being used in the hierarchy.

Let me know if you have any opinions on how to handle this!

Find out why a module is included

Firstly brilliant tool (many thanks) just helped me shave 50% of the size of my bundle. What would be really cool would be an easy way to fin out why a module in included. Then if I see an unexpected module I can find out why and do something about it! Maybe a popup that displays a list of 'inclusion' paths when a segment is clicked on.

Cannot read property 'size' of undefined

Hey,

The visualizer seems to have stopped working for our stats file using "webpack-visualizer-plugin": "^0.1.11"

Stats.json Gist

the error points to: raw:e.reduce(function(t,e){return t+e.chunk.size},0)} in the minified code.

I'm not sure what's caused it, is this a known issue?

Active?

Is this project still active and being maintained? Or is there another recommended alternative?

Endless loop when full path is added in 'filename' option

When called with: path.resolve(__dirname, '../../build/bundle-statistics.html') an endless loop is caused, compilation never ends. When a relative path is used, this is not happening.

Happens on Windows. Path in question became Z:\Dev\financial-app\build\...

Jenkins plugin

I'd really like to be able to get this visualisation in jenkins for each successful deploy to encourage my developers to poke around and ask questions about the bundle size.

I don't expect you to write this plugin, but I might do so one day and refer back to this issue

Add support for multiple entry points

I didn't see a way to visualize multiple entry points. The graph shows everything combined. It would be great if we could see separate endpoints for those with multi-page / single-page mixes.

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.