ybyc / fe-blog

前端开发总结,大家有什么好的点子都可以写进去
0 stars 1 forks source link

[webpack]Webpack 打包优化 #5

Open BowenZ opened 6 years ago

BowenZ commented 6 years ago

一、分析打包文件

使用webpack-bundle-analyzer可直接生成打包文件的分析图,对分析每个依赖和组件对于打包的影响有很大的帮助。

如何使用:

1.安装

npm install --save-dev webpack-bundle-analyzer

2.build/webpack.dev.conf.js中配置:

const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin

...

plugins: [
    new BundleAnalyzerPlugin(
      {
        analyzerMode: 'server',
        analyzerHost: '127.0.0.1',
        analyzerPort: 8889,
        reportFilename: 'report.html',
        defaultSizes: 'parsed',
        openAnalyzer: true,
        generateStatsFile: false,
        statsFilename: 'stats.json',
        statsOptions: null,
        logLevel: 'info'
      }
    )
    ...
  ]

3.开启服务后,将自动打开http://127.0.0.1:8889/,接下来就能看到:

image

二、使用DllPlugin

DllPlugin的原理是将通常不会变化的第三方库提前打包构建,然后直接在页面引入,在项目构建时不会再打包到vender文件中。

如何使用:

1.在build/下新建webpack.dll.conf.js文件,代码如下:

var path = require('path')
var webpack = require('webpack')
var HtmlWebpackPlugin = require('html-webpack-plugin')

module.exports = {
  //需要打包的模块
  entry: {
    // 打包出来的文件名将以vender开头
    vendor: [
      'babel-polyfill',
      'vue',
      'vuex',
      'vue-router',
      'axios',
      'qs',
      'viewerjs',
      'vue-amap',
      'vue-awesome',
      'element-ui',
      'moment'
    ]
  },
  output: {
    path: path.resolve(__dirname, '../static/js'), //打包后文件输出的文职
    filename: '[name].dll.js',
    library: '[name]_library'
  },
  module: {
    rules: [
      {
        test: /\.vue$/,
        loader: 'vue-loader'
      },
      {
        test: /\.js$/,
        loader: 'babel-loader',
        exclude: /node_modules/
      }
    ]
  },
  plugins: [
    new webpack.optimize.ModuleConcatenationPlugin(),
    new webpack.ContextReplacementPlugin(/moment[\/\\]locale$/, /zh-cn|en-gb/),
    new webpack.DllPlugin({
      path: path.join(__dirname, '.', '[name]-manifest.json'),
      libraryTarget: 'commonjs2',
      name: '[name]_library'
    }),
    // 压缩打包后的文件
    new webpack.optimize.UglifyJsPlugin({
      compress: {
        warnings: false
      }
    })
  ]
}

然后运行webpack -p --progress --config build/webpack.dll.conf.js

运行完成之后会在build目录中生成一个vendor-manifest.json文件,这个文件是用来关联vender中配置的第三方模块的,打包的时候不会把这些文件打包进去。

同时在static下会有一个vendor.dll.js文件,这个就是dll打包出来的第三方模块。

下一步,修改buidl/webpack.base.config文件,增加如下代码:

const webpack = require('webpack')
const manifest = require('./vendor-manifest.json')

module.exports = {
  ...
  plugins: [
    new webpack.DllReferencePlugin({
      manifest
    })
  ]
}

然后在index.html中增加<script src="./static/dll.vendor.js"></script>

然后执行npm run build,就会发现构建时间明显缩短了。

三、减小lodash打包文件体积

lodash是一个很有用的库,但我们往往只是用其中一部分方法,如果全部引入就会非常浪费。

所以,普通的优化方法是只引入用到的方法,如:

import flatten from 'lodash/flatten';
import flatMap from 'lodash/flatMap';

但是每次使用都要这么写还是有点麻烦的,所以接下来就要介绍一种只需正常引入使用lodash,就能自动按需打包的方法:

使用babel-plugin-lodash

babel-plugin-lodash可以将

import _ from 'lodash'
import { add } from 'lodash/fp'

const addOne = add(1)
_.map([1, 2, 3], addOne)

转化为

import _add from 'lodash/fp/add'
import _map from 'lodash/map'

const addOne = _add(1)
_map([1, 2, 3], addOne)

使用方法:

然后打包出来的文件就会小很多

使用lodash-webpack-plugin

未完待续...

reference

https://jeffjade.com/2017/08/06/124-webpack-packge-optimization-for-volume/ https://juejin.im/post/5a8797c15188257a836c385d