我试图使用webpack作为捆绑工具构建反应应用程序 . 输出束很大 . 这是我的webpack设置:

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const merge = require('webpack-merge');
const validate = require('webpack-validator');
const parts = require('./libs/parts');


const PATHS = {
    app:path.join(__dirname.toLowerCase(),'shared'),
    build:path.join(__dirname.toLowerCase(),'build'),
    //css:path.join(__dirname.toLowerCase(),'client','main.css')
    css:[
        //path.join(__dirname,'node_modules','purecss'),
        //path.join(__dirname,'client','client.less'),
        path.join(__dirname,'client','client.less')
    ]
};

const common = {
    entry:{
        app:PATHS.app,
        style:PATHS.css
    },
    output:{
        path:PATHS.build,
        filename:'[name].js',
    },
    /*plugins:[
        new HtmlWebpackPlugin({
            title:"Webpack to pack the whole web",
            template:"client/index.html"
        })
    ]*/
};
var config;
switch (process.env.npm_lifecycle_event) {
    case "build":
        config = merge(common,
            {
                devtool: 'cheap-module-source-map',
                output: {
                    path: PATHS.build,
                    filename: '[name].js',
                    // This is used for require.ensure. The setup
                    // will work without but this is useful to set.
                    chunkFilename: '[chunkhash].js'
                }
            },
            parts.clean(PATHS.build),
            parts.setFreeVariable(
                'process.env.NODE_ENV',
                'production'
            ),
            parts.supportESSix(PATHS.app),
            parts.extractBundle({
                name: 'vendor',
                entries: ['react','react-dom','react-router','react-addons-pure-render-mixin',
                    'redux','react-redux','immutable',"redux-thunk","superagent"]
            }),

            parts.purifyCSS(PATHS.css),
            parts.setupLess(PATHS.css),
            parts.minify(),
            parts.compressBundle()

        );
        break;
    default:
        config = merge(common,
            {
                devtool: 'source-map',
                output: {
                    path: PATHS.build,
                    filename: '[name].js',
                    // This is used for require.ensure. The setup
                    // will work without but this is useful to set.
                    chunkFilename: '[chunkhash].js'
                }
            },
            parts.clean(PATHS.build),
            parts.setFreeVariable(
                'process.env.NODE_ENV',
                'production'
            ),
            parts.supportESSix(PATHS.app),
            parts.extractBundle({
                name: 'vendor',
                entries: ['react','react-dom','react-router','react-addons-pure-render-mixin',
                    'redux','react-redux','immutable',"redux-thunk","superagent"]
            }),

            parts.purifyCSS(PATHS.css),
            parts.setupLess(PATHS.css),
            parts.minify()
        );
}

module.exports = validate(config);

运行特定任务的parts.js文件:

const webpack = require('webpack');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const PurifyCSSPlugin = require('purifycss-webpack-plugin');
const CompressionPlugin = require("compression-webpack-plugin");

exports.devServer=function(options){
    return {
      devServer:{
          historyApiFallback:true,
          hot:true,
          inline:true,
          stats:'errors-only',
          host:options.host,
          port:options.port
      },
        plugins:[
            new webpack.HotModuleReplacementPlugin({
                multiStep:true
            })
        ]
    };
};

exports.setupCSS=function(paths) {
    return {
        module:{
            loaders:[
                {
                test: /\.css$/,
                loaders: ['style', 'css'],
                include: paths
                }
            ]
        }
    };
};

//minify output
exports.minify=function(){
    return {
        plugins:[
            new webpack.optimize.UglifyJsPlugin({
                beautify:false,
                comment:false,
                compress:{
                    warnings:false,
                    drop_console:true
                }
            })
        ]
    }
};


exports.setFreeVariable = function(key, value) {
    const env = {};
    env[key] = JSON.stringify(value);

    return {
        plugins: [
            new webpack.DefinePlugin(env)
        ]
    };
}


exports.extractBundle = function(options) {
    const entry = {};
    entry[options.name] = options.entries;

    return {
        // Define an entry point needed for splitting.
        entry: entry,
        plugins: [
            // Extract bundle and manifest files. Manifest is
            // needed for reliable caching.
            new webpack.optimize.CommonsChunkPlugin({
                names: [options.name, 'manifest']
            })
        ]
    };
}

exports.clean = function(path) {
    return {
        plugins: [
            new CleanWebpackPlugin([path], {
                // Without `root` CleanWebpackPlugin won't point to our
                // project and will fail to work.
                root: process.cwd()
            })
        ]
    };
}

exports.extractCSS = function(paths) {
    return {
        module: {
            loaders: [
                // Extract CSS during build
                {
                    test:/\.less$/,
                    loader: ExtractTextPlugin.extract('style','css'),
                    include: paths
                }
            ]
        },
        plugins: [
            // Output extracted CSS to a file
            new ExtractTextPlugin('[name].[chunkhash].css')
        ]
    };
}

exports.purifyCSS = function(paths) {
    return {
        plugins: [
            new PurifyCSSPlugin({
                basePath: process.cwd(),
                // `paths` is used to point PurifyCSS to files not
                // visible to Webpack. You can pass glob patterns
                // to it.
                paths: paths
            }),
        ]
    }
}

exports.setupLess=function(path) {
    return {
        module:{
            loaders:[
                {
                    test:/\.less$/,
                    loader:ExtractTextPlugin.extract('style-loader','css-loader!less-loader'),
                    include:path
                },
                { test: /\.(ttf|eot|svg)$/, loader: "file-loader" },
                {test: /\.eot$/,  loader: "file" },
                { test: /\.(woff|woff2)$/, loader: "url?limit=10000&minetype=application/font-woff" }
            ]
        },
        plugins: [
            // Output extracted CSS to a file
            new ExtractTextPlugin('style.css')
        ]
    }
};

exports.supportESSix=function(path) {
    return {
        module:{
            loaders:[
                {
                    test:/\.js$/,
                    loader:"babel",
                    include:path,
                    exclude:"node_modules"
                }
            ]
        }
    };
};

exports.compressBundle=function(){
    return {
        plugins: [
            new CompressionPlugin({
                asset: "[path].gz[query]",
                algorithm: "gzip",
                test: /\.js$|\.html$/,
                threshold: 10240,
                minRatio: 0.8
            })
        ]
    }
}

这些是依赖包:

"dependencies": {
    "babel-core": "^6.14.0",
    "babel-loader": "^6.2.5",
    "babel-preset-es2015": "^6.14.0",
    "babel-preset-react": "^6.11.1",
    "body-parser": "^1.15.2",
    "compress": "^0.99.0",
    "cookie-parser": "^1.4.3",
    "csurf": "^1.9.0",
    "es6-promise": "^3.2.1",
    "express": "^4.14.0",
    "express-jwt": "^5.0.0",
    "express-session": "^1.14.1",
    "form-data": "^2.0.0",
    "history": "^3.2.1",
    "immutable": "^3.8.1",
    "isomorphic-fetch": "^2.2.1",
    "jsonwebtoken": "^7.1.9",
    "method-override": "^2.3.6",
    "mongoose": "^4.6.0",
    "passport": "^0.3.2",
    "passport-facebook": "^2.1.1",
    "password-hash": "^1.2.2",
    "q": "^1.4.1",
    "react": "^15.3.2",
    "react-addons-pure-render-mixin": "^15.3.1",
    "react-dom": "^15.3.1",
    "react-redux": "^4.4.5",
    "react-router": "^2.7.0",
    "redux": "^3.6.0",
    "redux-immutable": "^3.0.8",
    "redux-thunk": "^2.1.0",
    "sanitize-html": "^1.13.0",
    "superagent": "^2.3.0"
  },

但输出真的很大:
app.js is 333KB

题:

  • 我的webpack配置有什么问题?

  • 这个捆绑尺寸是正常的吗?

如果没有 . 如何获得较小的捆绑包?

谢谢 .