reactjs-如何最小化webpack包的大小?

我正在使用react.min.jswebpack作为模块捆绑程序编写一个Web应用程序。到目前为止,我的-p代码确实很轻巧,整个文件夹的大小为25 kb。

我从webpack创建的react.min.js是2.2 mb。 使用261457785696551010标志运行优化后,它将捆绑包减小到700kb,这仍然非常大。

我调查了react.min.js文件,它的大小为130kb。

Webpack是否可能产生如此大的文件,或者我做错了什么?

webpack.config.js

var path = require('path');
var webpack = require('webpack');

module.exports = {
  entry: './public/components/main.jsx',
  output: {
    path: __dirname + "/public",
    filename: 'bundle.js'
  },
  module: {
    loaders: [{
      test: /.jsx?$/,
      loader: 'babel-loader',
      exclude: /node_modules/,
      query: {
        presets: ['es2015', 'react']
      }
    }, {
      test: /\.css$/,
      loader: "style!css"
    }]
  }
};

编辑

package.json:

{
  "name": "XChange",
  "version": "0.0.0",
  "private": true,
  "scripts": {
    "start": "node ./bin/www"
  },
  "main": "./bin/www",
  "devDependencies": {
    "body-parser": "~1.13.2",
    "cookie-parser": "~1.3.5",
    "debug": "~2.2.0",
    "express": "~4.13.1",
    "jade": "~1.11.0",
    "morgan": "~1.6.1",
    "serve-favicon": "~2.3.0",
    "react-dom": "~0.14.3",
    "react": "~0.14.3",
    "webpack": "~1.12.9",
    "babel-loader": "~6.2.0",
    "babel-core": "~6.2.1",
    "babel-preset-react": "~6.1.18",
    "babel-preset-es2015": "~6.1.18",
    "react-bootstrap": "~0.28.1",
    "material-ui": "~0.14.0-rc1",
    "history": "~1.13.1",
    "react-router": "~1.0.2",
    "style-loader": "~0.13.0",
    "css-loader": "~0.18.0"
  },
  "dependencies": {
    "express-validator": "~2.18.0",
    "mongoose": "~4.2.9",
    "kerberos": "~0.0.17",
    "bcrypt": "~0.8.5"
  }
}
itaied asked 2019-11-15T00:45:22Z
5个解决方案
95 votes

根据您的评论,您正在使用react-bootstrapmaterial-ui。这些依赖项由webpack以及reactreact-dom软件包捆绑在一起。 每当您将requireimport软件包打包时,它都会作为捆绑文件的一部分捆绑在一起。

这就是我的猜测。 您可能使用库方式导入react-bootstrapmaterial-ui组件:

import { Button } from 'react-bootstrap';
import { FlatButton } from 'material-ui';

这很方便,但它不仅捆绑了ButtonFlatButton(及其依赖项),而且捆绑了整个库。

减轻它的一种方法是尝试仅Button或2614578538456024024065需要什么,让我们说一下组件方式。 使用相同的示例:

import Button from 'react-bootstrap/lib/Button';
import FlatButton from 'material-ui/lib/flat-button';

这将仅捆绑ButtonFlatButton及其各自的依存关系。 但不是整个图书馆。 因此,我将尝试摆脱所有库导入,而改用组件方式。

如果您不使用很多组件,那么它将大大减少捆绑文件的大小。

作为进一步的解释:

当使用库方式时,您将导入所有这些react-bootstrap和所有这些material-ui组件,无论您实际使用的是哪个组件。

dreyescat answered 2019-11-15T00:46:22Z
29 votes

2017年1月1日-自那以后,我了解了更多有关不同Webpack插件的知识,并希望对此进行更新。 事实证明,UglifyJS具有大量的配置选项,这些配置选项似乎不是很主流,但会对捆绑包的大小产生巨大影响。 这是我当前的配置,带有一些注释(站点上的文档很棒):

 new webpack.optimize.UglifyJsPlugin({
      comments: false, // remove comments
      compress: {
        unused: true,
        dead_code: true, // big one--strip code that will never execute
        warnings: false, // good for prod apps so users can't peek behind curtain
        drop_debugger: true,
        conditionals: true,
        evaluate: true,
        drop_console: true, // strips console statements
        sequences: true,
        booleans: true,
      }
    })

我曾经遇到'source-map'转义的unicode字符的模糊问题,因此请注意,如果您使用这些转换来使诸如此类的情况变得边缘化,就可以了。

您可以在webpack文档中阅读有关'source-map'支持的特定选项的更多信息,并附带一些后续链接以进一步阅读。


(旁注:我认为您的package.json是混合的...至少其中一些开发依赖项是我见过的每个package.json中的依赖项(例如react-starter-kit)

如果您准备进行生产,则应该采取一些其他步骤来减小文件大小。 这是我的webpack.config.js的片段:

 plugins: [


        new webpack.optimize.UglifyJsPlugin(),
        new webpack.optimize.DedupePlugin(),
        new webpack.DefinePlugin({
            'process.env': {
                'NODE_ENV': JSON.stringify('production')
            }
        })
    ],

1)最小化/丑化您的代码

2)替换重复的代码以最小化文件大小

3)告诉webpack省略一些用于节点环境构建的内容

最后,如果您使用源地图(您可能应该这样做),则需要添加适当的线。 Sentry为此撰写了一篇不错的博客文章。

在我的构建中,我使用devtool:'source-map'进行生产

Brandon answered 2019-11-15T00:47:47Z
16 votes

更新05/18:更新UglifyJsPlugin设置以实现更好的缩小

我将以下配置用于生产代码中的压缩。

 plugins: [
    new webpack.DefinePlugin({
      'process.env': {
        // This has effect on the react lib size
        'NODE_ENV': JSON.stringify('production'),
      }
    }),
    new ExtractTextPlugin("bundle.css", {allChunks: false}),
    new webpack.optimize.AggressiveMergingPlugin(),
    new webpack.optimize.OccurrenceOrderPlugin(),
    new webpack.optimize.DedupePlugin(),
    new webpack.optimize.UglifyJsPlugin({
      mangle: true,
      compress: {
        warnings: false, // Suppress uglification warnings
        pure_getters: true,
        unsafe: true,
        unsafe_comps: true,
        screw_ie8: true,
        conditionals: true,
        unused: true,
        comparisons: true,
        sequences: true,
        dead_code: true,
        evaluate: true,
        if_return: true,
        join_vars: true
      },
      output: {
        comments: false,
      },
      exclude: [/\.min\.js$/gi] // skip pre-minified libs
    }),
    new webpack.IgnorePlugin(/^\.\/locale$/, [/moment$/]), 
    new CompressionPlugin({
      asset: "[path].gz[query]",
      algorithm: "gzip",
      test: /\.js$|\.css$|\.html$/,
      threshold: 10240,
      minRatio: 0
    })
  ],
Khalid Azam answered 2019-11-15T00:48:19Z
1 votes

您是否看过脚本是如何通过网络发送的?我有一些非常简单的react组件,每个组件的大小大约为300kb,这是在webpack优化之后进行的。将它们压缩后,它们下降到38kb。 仍然相当可观-但这就是我们今天使用明天的功能所获得的。如果您正在使用node / express提供静态资源(包括您的javascript),请查看压缩([https://github.com/expressjs/compression)。]我还建议您查看生产的节点最佳实践指南[https://expressjs.com/en/advanced/best-practice-performance.html]如果您不是通过节点提供文件,则apache(或其他Web服务器)将提供用于压缩基于文本的文件的选项。

kimmiju answered 2019-11-15T00:48:46Z
0 votes

我发现提及source-map-explorer实用程序很有用,该实用程序有助于了解bundle.js文件中的确切内容。 它可以帮助您识别bundle js中是否有不必要的东西。您可以从npm安装source-map-explorer并像

source-map-explorer yourBundle.js

除此之外,如@kimmiju所述,请检查您的服务器是否正在使用某种压缩方式。

Network Tab in Chrome

您还可以尝试异步加载路由(在webpack中延迟加载),这样就不会一次性发送整个bundlejs文件,而是在用户导航到这些路由时以块的形式发送。

Rahil Ahmad answered 2019-11-15T00:49:25Z
translate from https://stackoverflow.com:/questions/34239731/how-to-minimize-the-size-of-webpacks-bundle