This is my current bundle information which i got from bundle analyzer plugin,
I want to move the jquery to a separate chunk and extract css into a separate single css bundle, is there any other optimization which i can do to reduce my bundle size?
My current webpack is this webpack.base.js
/**
* COMMON WEBPACK CONFIGURATION
*/
const path = require('path');
const webpack = require('webpack');
const AddAssetHtmlPlugin = require('add-asset-html-webpack-plugin');
// const BundleAnalyzerPlugin = require('webpack-bundle-
analyzer').BundleAnalyzerPlugin;
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const autoprefixer = require('autoprefixer');
// Remove this line once the following warning goes away (it was meant
webpack loader authors not users):
// 'DeprecationWarning: loaderUtils.parseQuery() received a non-string
value which can be problematic,
be replaced with getOptions()
// in the next major version of loader-utils.'
process.noDeprecation = true;
const environment = require('../../environments/environment');
let publicDeployPath = '/';
const loaderOptions = {};
if (!environment.isLocal) {
publicDeployPath = environment.blobContainerPath;
loaderOptions.root = environment.blobContainerPath;
loaderOptions.minimize = true;
}
module.exports = (options) => ({
entry: options.entry,
output: Object.assign({ // Compile into js/build.js
path: path.resolve(process.cwd(), 'build'),
publicPath: publicDeployPath,
}, options.output), // Merge with env dependent settings
module: {
rules: [
{
test: /\.js$/, // Transform all .js files required somewhere with
Babel
use: {
loader: 'babel-loader',
options: options.babelQuery,
},
},
{
test: /\.jsx$/, // Transform all .js files required somewhere with
Babel
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: options.babelQuery,
},
},
{
// Preprocess our own .css files
// This is the place to add your own loaders (e.g. sass/less etc.)
test: /\.css$/,
// exclude: /node_modules/,
loader: ExtractTextPlugin.extract({
fallback: 'style-loader',
use: [{
loader: 'css-loader',
options: loaderOptions,
}, {
loader: 'postcss-loader',
options: {
plugins: () => [autoprefixer()],
},
},
] }, true),
},
// {
// // Preprocess 3rd party .css files located in node_modules
// test: /\.css$/,
// include: /node_modules/,
// loader: ExtractTextPlugin.extract({
// fallback: 'style-loader',
// use: [{
// loader: 'css-loader',
// options: loaderOptions,
// },
// ] }, true),
// },
{
test: /\.mp3$/,
loader: 'url-loader?limit=10000&mimetype=audio/mpeg',
options: {
publicPath: publicDeployPath,
},
},
{
test: /\.(eot|svg|otf|ttf|woff|woff2)$/,
loader: 'file-loader',
options: {
publicPath: publicDeployPath,
},
},
{
test: /\.(jpg|png|gif)$/,
use: [
'file-loader',
{
loader: 'image-webpack-loader',
options: {
publicPath: publicDeployPath,
progressive: true,
optimizationLevel: 7,
interlaced: false,
pngquant: {
quality: '65-90',
speed: 4,
},
},
},
],
},
{
test: /\.html$/,
use: 'html-loader',
},
{
test: /\.json$/,
use: 'json-loader',
},
{
test: /\.(mp4|webm)$/,
use: {
loader: 'url-loader',
options: {
limit: 10000,
},
},
},
],
},
plugins: options.plugins.concat([
new webpack.ProvidePlugin({
// make fetch available
fetch: 'exports-loader?self.fetch!whatwg-fetch',
}),
// new BundleAnalyzerPlugin(),
new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery',
'window.jQuery': 'jquery',
'root.jQuery': 'jquery',
}),
// Always expose NODE_ENV to webpack, in order to use
`process.env.NODE_ENV`
// inside your code for any environment checks; UglifyJS will
automatically
// drop any unreachable code.
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: JSON.stringify(process.env.NODE_ENV),
},
}),
new AddAssetHtmlPlugin({ filepath: path.resolve(process.cwd(),
'app/vendor/VidyoConnector.js'), hash: true }),
new webpack.NamedModulesPlugin(),
]),
resolve: {
modules: ['app', 'node_modules'],
extensions: [
'.js',
'.jsx',
'.react.js',
],
mainFields: [
'browser',
'jsnext:main',
'main',
],
},
devtool: options.devtool,
target: 'web', // Make web variables accessible to webpack, e.g. window
performance: options.performance || {},
node: {
fs: 'empty',
},
});
webpack.production.js
// Important modules this config uses
const path = require('path');
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const pathsToClean = [
'build',
];
const cleanOptions = {
root: path.resolve(__dirname, '..'),
verbose: true,
dry: false,
allowExternal: true,
};
module.exports = require('./webpack.base.babel')({
// In production, we skip all hot-reloading stuff
entry: [
path.join(process.cwd(), 'app/app.js'),
],
// Utilize long-term caching by adding content hashes (not compilation hashes) to compiled assets
output: {
filename: '[name].[chunkhash].js',
chunkFilename: '[name].[chunkhash].chunk.js',
},
plugins: [
new webpack.optimize.ModuleConcatenationPlugin(),
new webpack.optimize.CommonsChunkPlugin({
name: 'reactjs',
filename: 'reactjs.[chunkhash].js',
minChunks: (module) => (
// If module has a path, and inside of the path exists the name "somelib",
// and it is used in 3 separate chunks/entries, then break it out into
// a separate chunk with chunk keyname "my-single-lib-chunk", and filename "my-single-lib-chunk.js"
module.resource && (/react/).test(module.resource)
),
}),
new CleanWebpackPlugin(pathsToClean, cleanOptions),
new ExtractTextPlugin({ filename: 'style.[hash].css', disable: false, allChunks: true }),
new webpack.optimize.CommonsChunkPlugin({
name: 'vendor',
filename: 'vendor.[chunkhash].js',
minChunks: (module) => (
// If module has a path, and inside of the path exists the name "somelib",
// and it is used in 3 separate chunks/entries, then break it out into
// a separate chunk with chunk keyname "my-single-lib-chunk", and filename "my-single-lib-chunk.js"
module.context && module.context.includes('node_modules')
),
}),
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify('production'),
}),
// Minify and optimize the index.html
new HtmlWebpackPlugin({
template: 'app/index.html',
minify: {
removeComments: true,
collapseWhitespace: true,
removeRedundantAttributes: true,
useShortDoctype: true,
removeEmptyAttributes: true,
removeStyleLinkTypeAttributes: true,
keepClosingSlash: true,
minifyJS: true,
minifyCSS: true,
minifyURLs: true,
},
inject: true,
}),
new HtmlWebpackPlugin({ // Also generate a invalid page html
filename: 'ppVideoInvalid.html',
template: 'app/ppVideoInvalid.html',
}),
new HtmlWebpackPlugin({ // Generate a test client html
filename: 'testClient.html',
template: 'app/TestInterface/testClient.html',
}),
],
performance: {
assetFilter: (assetFilename) => !(/(\.map$)|(^(main\.|favicon\.))/.test(assetFilename)),
},
});