我正在使用react
和webpack
作为我的模块捆绑器编写Web应用程序.jsx
到目前为止,我的代码非常轻,整个文件夹的大小为25 kb.
我bundle.js
创建的webpack
是2.2 mb.在使用-p
标志运行优化之后,它将捆绑包减少到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" } }
dreyescat.. 98
根据您的评论,您正在使用material-ui
和react-bootstrap
.这些依赖项由webpack与您react
和react-dom
包捆绑在一起.无论何时您require
或import
它将捆绑包作为捆绑文件的一部分.
这是我的猜测.您可能正在使用库方式导入react-bootstrap
和material-ui
组件:
import { Button } from 'react-bootstrap'; import { FlatButton } from 'material-ui';
这很好用,但它不仅捆绑Button
和FlatButton
(及其依赖),而是整个库.
缓解它的一种方法是尝试仅仅import
或者require
需要什么,让我们说组件方式.使用相同的例子:
import Button from 'react-bootstrap/lib/Button'; import FlatButton from 'material-ui/lib/flat-button';
这只会捆绑Button
,FlatButton
以及它们各自的依赖关系.但不是整个图书馆.所以我会试图摆脱你所有的库导入并改用组件方式.
如果您没有使用大量组件,那么它应该大大减少捆绑文件的大小.
作为进一步说明:
当您使用库方式时,您将导入所有这些react-bootstrap和所有这些material-ui组件,无论您实际使用哪些组件.
根据您的评论,您正在使用material-ui
和react-bootstrap
.这些依赖项由webpack与您react
和react-dom
包捆绑在一起.无论何时您require
或import
它将捆绑包作为捆绑文件的一部分.
这是我的猜测.您可能正在使用库方式导入react-bootstrap
和material-ui
组件:
import { Button } from 'react-bootstrap'; import { FlatButton } from 'material-ui';
这很好用,但它不仅捆绑Button
和FlatButton
(及其依赖),而是整个库.
缓解它的一种方法是尝试仅仅import
或者require
需要什么,让我们说组件方式.使用相同的例子:
import Button from 'react-bootstrap/lib/Button'; import FlatButton from 'material-ui/lib/flat-button';
这只会捆绑Button
,FlatButton
以及它们各自的依赖关系.但不是整个图书馆.所以我会试图摆脱你所有的库导入并改用组件方式.
如果您没有使用大量组件,那么它应该大大减少捆绑文件的大小.
作为进一步说明:
当您使用库方式时,您将导入所有这些react-bootstrap和所有这些material-ui组件,无论您实际使用哪些组件.
01/2017编辑 - 我已经了解了不同的Webpack插件,并希望更新它.事实证明,UglifyJS有很多配置选项,似乎不是很主流,但可能会对您的包大小产生巨大影响.这是我当前的配置w /一些注释(网站上的文档很棒):
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, } })
我曾经遇到过一个带有uglify
逃逸的unicode字符的模糊问题,所以如果你使用这些转换就可以注意到像这样的边缘情况是可能的.
您可以webpack
在webpack文档中阅读有关特定选项支持的更多信息,以及一些后续链接以进一步阅读.
(旁注:我认为你的package.json是混淆的...至少有一些dev-dependencies是我所见过的每个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)缩小/ uglifies您的代码
2)替换重复的代码以最小化文件大小
3)告诉webpack省略它用于节点环境构建的一些东西
最后,如果您使用源地图(您可能应该使用),则需要添加相应的行.Sentry写了一篇关于此的好文章.
在我的构建中,我使用devtool:'source-map'
用于生产
更新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 }) ],