极限特工–webpack与React
在使用webpack的时候,我们是可以优化包大小的。下面记录下优化的过程。
拆分js
webpack的配置是All in。All in的意思是把所有的Javascript打包成一个js文件,注意是所有的。也就是说,无论你引入了React、React-Router还是lodash,都要全部打包在一起!那这时候就会产生问题,比如,我只改一个业务逻辑,没有涉及到js包,这样的话webpack也会重新编译,生成的js的hash也就发生变化了,用户在使用的时候还要重新加载js。所以这时候要把那些引入的包以及库拆分。
要点
- entry
在配置入口的时候,把药拆分的包写上这样webpack就会把一些依赖包写入vendors里面entry: {
'vendors': [
'react',
'react-dom',
'redux',
'whatwg-fetch',
'react-virtualized',
'localforage',
'react-motion',
'core-js',
'immutable',
'react-tappable',
'history',
'react-redux',
'react-router',
'react-router-dom'
],
'app': ['babel-polyfill', `${rootPath}/src/modules/main.jsx`]
} - output
output是输出格式定义,如果在生产环境,那么希望产出的文件名为 入口文件名+min+五位hash值。path是产出的路径,publicPath是域名(可配置cdn)output: {
path: path.resolve(`${public_path.root}${public_path.static}`),
filename: 'js/[name].min.[chunkhash:5].js',
chunkFilename: "js/[name].min.[chunkhash:5].js",
publicPath: public_path.domain
} - CommonsChunkPlugin
这个插件是把公共代码提出来,以减少js的体积,配置很简单,我把公共代码也放到vendors.js里面了。plugins: [
somethingPlugins,
new CommonsChunkPlugin({
name: ["vendors", "manifest"],
minChunks: Infinity
})
] - HashedModuleIdsPlugin 与webpack-chunk-hash
但这样还不能完全解决我们所期望的效果—-打包只更新响应模块的代码
这时候测试出的结果是webpack每次编译,产生的hash都是不同的。
在webpack2里面,webpack提供了一个插件HashedModuleIdsPlugin,我们还需要一个WebpackChunkHash,这样就可以解决上述说的问题啦import WebpackChunkHash from 'webpack-chunk-hash'
plugins: [
somethingPlugins,
new webpack.HashedModuleIdsPlugin(),
new WebpackChunkHash()
]
manifest缓存
上面说到不修改的js文件在编译的时候不产生新的hash。现在希望,浏览器能将js文件缓存起来,然后在用户访问的时候可以直接读取浏览器的缓存。这时需要用到以下插件
*inline-manifest-webpack-plugin
这个直接写在plugins里面就好了,然后在webpack编译的过程中,会生成一段js代码,要做的把这段代码内联到html里面。
import InlineManifestWebpackPlugin from 'inline-manifest-webpack-plugin' |
有一点要注意的是CommonsChunkPlugin这个插件里面写上manifest这是为了把InlineManifestWebpackPlugin插件生成的js代码给拆分出来。
*html-webpack-plugin
利用html-webpack-plugin这个插件,可以生成html,所以可以把js内联进去。
import InlineManifestWebpackPlugin from 'inline-manifest-webpack-plugin' |
在ejs里面写把js注入进去
|
以上就完成了manifest缓存。
路由拆分代码
在react-router4文档里面有个例子,对于大多数工程来说,这个例子可以胜任了。原理大概是,利用bundle-loader来拆分代码,然后利用Bundle Component来加载模块
import { PureComponent } from 'react' |
lodash
这个工具库实在是太大了。在使用它的时候,打包进来是500K+。并且许多js库都是和它有依赖的。比如说redux,在webpack打包的时候无意中就把所有的lodash打包进来。但实际上,只是用到lodash的少部分方法而已。webpack提供了一个去lodash的插件,babel也有一个。效果都不错。我使用的是babel的去lodash插件,只需要在.babelrc添加plugin就行了
“plugins”: [lodash] |
Tree shaking
这个玩意是我不懂玩还是怎么的,怎么配都不成功。原理应该是根据babel的编译规则,把不用的export干掉呀。


