前言
在前端应用的优化中,对加载资源的大小控制极其的重要,大多数时候我们能做的是在打包编译的过程对资源进行大小控制、拆分与复用。
本片文章中主要是基于 webpack 打包,以 React、vue 等生态开发的单页面应用来举例说明如何从 webpack 打包的层面去处理资源以及缓存,其中主要我们需要做的是对 webpack 进行配置的优化,同时涉及少量的业务代码的更改。
同时对打包资源的分析可以使用 (webpack-contrib/webpack-bundle-analyzer) 插件,当然可选的分析插件还是很多的,在本文中主要以该插件来举例分析。
TIP: webpack 版本 @3.6.0
一、打包环境与代码压缩
首先我们有一个最基本的 webpack 配置:
// webpack.config.js const path = require('path'); const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin; const PROJECT_ROOT = path.resolve(__dirname, './'); module.exports = { entry: { index: './src/index.js' }, output: { path: path.resolve(__dirname, 'dist'), filename: '[name].[chunkhash:4].js' }, module: { rules: [ { test: /\.js[x]?$/, use: 'babel-loader', include: PROJECT_ROOT, exclude: /node_modules/ } ] }, plugins: [ new BundleAnalyzerPlugin() ], resolve: { extensions: ['.js', '.jsx'] }, };
执行打包可以看到一个项目的 js 有 1M 以上:
Hash: e51afc2635f08322670b Version: webpack 3.6.0 Time: 2769ms Asset Size Chunks Chunk Names index.caa7.js 1.3 MB 0 [emitted] [big] index
这时候只需要增加插件 `DefinePlugin` 与 `UglifyJSPlugin` 即可减少不少的体积,在 plugins 中添加:
// webpack.config.js ... { ... plugins: [ new BundleAnalyzerPlugin(), new webpack.DefinePlugin({ 'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV || 'production') }), new UglifyJSPlugin({ uglifyOptions: { ie8: false, output: { comments: false, beautify: false, }, mangle: { keep_fnames: true }, compress: { warnings: false, drop_console: true }, } }) ] ... }
可以看到这时候的打包输出:
Hash: 84338998472a6d3c5c25 Version: webpack 3.6.0 Time: 9940ms Asset Size Chunks Chunk Names index.89c2.js 346 kB 0 [emitted] [big] index
代码的大小从 1.3M 降到了 346K。
(1)DefinePlugin
DefinePlugin 允许创建一个在编译时可以配置的全局常量。这可能会对开发模式和发布模式的构建允许不同的行为非常有用。如果在开发构建中,而不在发布构建中执行日志记录,则可以使用全局常量来决定是否记录日志。这就是 DefinePlugin 的用处,设置它,就可以忘记开发和发布构建的规则。