webpack打包体积优化方法大全

2020-01-14 00:11:16

参考地址webpack打包体积优化

webpack打包的体积越小,对于部署应用的网站来说,性能越好,加载速度越快。

1. 分析打包文件

1. 生成统计信息文件

首先需要通过webpack命令生成统计信息的文件。在package.json的脚本中添加命令

  "scripts": {    "stats": "webpack --config webpack.prod.js --profile --json > stats.json", 
     //...
  }

上面的命令会在根目录下生成一个stats.json的打包统计信息文件。

2. 可视化分析

使用插件可视化分析插件:webpack-bundle-analyzer

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

配置插件的使用信息;

const BundleAnalyzerPlugin = require(‘webpack-bundle-analyzer‘).BundleAnalyzerPlugin;

module.export = {   //...  plugins: [    new BundleAnalyzerPlugin({
      analyzerMode: ‘disabled‘,  // 关闭默认启动的展示信息的http服务器
      generateStatsFile: true  // 打包的时候生成stats.json文件;  }),
}

从上面配置信息可知,使用该插件,不需要再手动生成stats.json文件,第一步可以省略。

然后,在脚本中添加手动启动分析器的http

// 分析命令的使用,应该在打包命令之后。因为它的作用就是分析打包后的文件
 "scripts": {    "build": "webpack --config webpack.prod.js",    "analyzer": "webpack-bundle-analyzer ./dist/stats.json --port 8081"
  }

3. 优化建议

将生成的stats.json文件拖入该网站https://webpack.jakoblind.no/optimize/

会给出打包体积太大的优化措施。

该插件基于webpack-optimize-helper插件。

2. 抽离css并压缩

1.抽离css

使用mini-css-extract-plugin抽离css

npm install --save-dev mini-css-extract-plugin

在plugins配置文件中使用插件

module.exports = {
  plugins: [    new MiniCssExtractPlugin({
      filename: ‘css/[name].[contenthash:8].css‘  // 将css文件统一放入css文件夹    })
  ]  
}

2. 压缩css

使用optimize-css-assets-webpack-plugin压缩css文件

npm install -D optimize-css-assets-webpack-plugin

在optimization中使用该插件

module.exports = {
    optimization: {
        minimize: true,
        minimizer: [            new OptimizeCssAssetsWebpackPlugin()
        ]
    }

3. 移除未使用的css

在大型项目中,经常会有很多样式内容,在代码中根本未使用,但是会被打包,这些样式需要打包时应该移除。

使用purgecss-webpack-plugin移除未使用的css样式。

npm i purgecss-webpack-plugin -D

在pluigns中配置插件

const glob = require(‘glob‘); module.exports = {
  plugins:[     PurgecssWebpackPlugin({ 
      paths: glob.sync(`${path.join(__dirname, ‘src/**/*‘)}`, { nodir:

3. 复用babal转化时runtime代码

@babel/plugin-transform-runtime

?该插件的引入只能通过.babelrc文件,不能在babel-loader的options中,否则报错。

4. 使用CDN

1. 第三方库使用CDN

    new HtmlWebpackExternalsPlugin({
      externals: [
        {
          module: ‘lodash‘,
          global: ‘_‘,
          entry: ‘https://cdn.jsdelivr.net/npm/lodash@4.17.15/lodash.min.js‘
        }
      ]
    })

然后为了避免用户在模块中手动又导入,需要添加

  externals: {
    lodash: ‘_‘
  },

2. 项目生成的静态文件可以部署到CDN服务器中

需要配置publicPath为CDN服务器的域名

// output, module->MiniCssWebpackLoader.loader,  image等可以部署publicPathpublicPath: ‘http://lyralee.com‘

5. webpack.IgnorePlugin

忽略第三方库中多余的文件夹。

new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/)

上面忽略了moment库中的语言包

6. 图片压缩image-webpack-loader

      {
        test: /\.(gif|png|jpe?g|svg)$/i,
        use: [
          {
            loader: ‘url-loader‘,
            options: {
              limit: 2 * 1024,
              outputPath: ‘images‘,
              name: ‘[name].[contenthash:8].[ext]‘
            }
          },
          {
            loader: ‘image-webpack-loader‘,
            options: {
              mozjpeg: {
                progressive: true,
                quality: 65
              },              // optipng.enabled: false will disable optipng              optipng: {
                enabled: false
              },
              pngquant: {
                quality: [0.65, 0.90],
                speed: 4
              },
              gifsicle: {
                interlaced: false
              },              // the webp option will enable WEBP              webp: {
                quality: 75
              }
            }
          }
        ]
      }

7. 使用babel-polyfill的替代方案

如果项目中允许使用外部链接,可以使用

<script src="https://polyfill.io/v3/polyfill.min.js/"></script>

它按照浏览器类型返回需要的内容

 8. TreeShaking

1. 原理:

1)利用es6模块的静态结构,依赖模块命令import/export,进行代码分析,分析出无用/永远不会访问的代码。

1)对于自己写的代码,禁止babel将esModule转为requirerules: [
      {
        test: /\.jsx?$/,
        use: {
          loader: ‘babel-loader‘,
          options: {            // 设置{moduels: false} 则保留ES6的import/export
            presets: [[‘@babel/preset-env‘, {modules: false}],  ‘@babel/preset-react‘],
            plugins: [
              [‘@babel/plugin-proposal-decorators‘, {legacy: true}],
              [‘@babel/plugin-proposal-class-properties‘, {loose: true}]
            ]
          },
        },
        exclude: /node_modules/
      }
    ]2) 对于第三方库,要使用es模块的包, 如: lodash-es(有问题,先不用)import {join } from ‘lodash-es‘

2)通过terser-webpack-plugin移除分析出的多余代码

// ??只要写了optimization属性(即使是空),即使是production,也不会启动该Terser插件 ; 如果是完整的配置,但是mode=development,该属性也不起作用optimization: {
    minimizer: [      new TerserWebpackPlugin({
        parallel: true,
        cache: true
      })
    ],
     ...
  },

2. 注意事项

1. 要使TreeShaking起作用,必须使用ES6语法import/export
2. 减少sideEffects(副作用)代码的书写
3. 引入的第三方库,需要引入他们的ES版本

3. 特殊情形

当多入口文件存在时,只要有一个入口中使用了某方法,就不会被TreeShaking掉

9. 代码分割

1. 入口文件代码分割

entry: {
    index: ‘./src/index.js‘,
    vendors: [‘lodash‘]
}

2. 动态import导入实现懒加载

当代码中触发使用import()动态引入文件时,会发起请求,并返回一个webpackJsonp方法,

该方法中实现代码的按需加载。

另外,React16.6.0中引入的React.lazy()就是基于该方法实现模块的代码分割和懒加载。

3. 使用splitChunks插件

splitChunks: {
      cacheGroups: {
        vendors: {
          chunks: ‘initial‘, // 还有aysnc/all模式
          name: ‘vendors‘, // 覆盖默认生成的名字
          test: /node_modules/,
          priority: -10, //优先级
          minSize: 100*1024  // 生成单独文件的最小体积        },
        commons: {
          chunks: ‘initial‘,
          name: ‘commons‘,
          priority: -10,
          minChunks: 2, // 被引用的模块的最少数量
          minSize: 50*1024
        }
      }
    }

webpack打包体

  • 2019-03-26 19:25:01

    Android studio 打包后安装闪退 Fatal Signal 6(SIGABRT)...

    项目上线前打包安装后闪退,查了很多原因,比如混淆文件的内容,第三方库不加入混淆等等,均未成功,后来关闭混淆打包后运行成功,原因可能是依赖工程中的库文件不能被混淆,关闭本工程混淆开关后,依赖工程的混淆开关也要关闭,关闭混淆后如果怕被反编译,可使用百度开发平台的app加固,加固的同时还能使用多渠道打包工具。

  • 2019-03-26 19:29:05

    Android NDK开发Crash错误定位

     在Android开发中,程序Crash分三种情况:未捕获的异常、ANR(Application Not Responding)和闪退(NDK引发错误)。其中未捕获的异常根据logcat打印的堆栈信息很容易定位错误。ANR错误也好查,Android规定,应用与用户进行交互时,如果5秒内没有响应用户的操作,则会引发ANR错误,并弹出一个系统提示框,让用户选择继续等待或立即关闭程序。并会在/data/anr目录下生成一个traces.txt文件,记录系统产生anr异常的堆栈和线程信息。如果是闪退,这问题比较难查, --------------------- 作者:xyang0917 来源:CSDN 原文:https://blog.csdn.net/xyang81/article/details/42319789 版权声明:本文为博主原创文章,转载请附上博文链接!

  • 2019-04-01 22:46:39

    电子签章的实施方案

    WORD/EXCEL签章模块,该部分实现与WORD/EXCEL的无缝结合,并提供给用户简单直观的菜单和工具条来实现文档签章验证等各种操作,其中,KHSC-64智能密码钥匙是签章模块中用户证书和图章的载体

  • 2019-04-01 22:48:25

    如何用 Java 对 PDF 文件进行电子签章

    印章是我国特有的历史文化产物,古代主要用作身份凭证和行驶职权的工具。它的起源是由于社会生活的实际需要。早在商周时代,印章就已经产生。如今的印章已成为一种独特的,融实用性和艺术性为一体的艺术瑰宝。传统的印章容易被坏人、小人私刻;从而新闻鲜有报道某某私刻公章,侵吞国家财产。随着计算机技术、加密技术及图像处理技术的发展,出现了电子签章。电子签章是电子签名的一种表现形式,利用图像处理技术、数字加密技术将电子签名操作转化为与纸质文件盖章操作相同的可视效果,同时利用电子签名技术保障电子信息的真实性和完整性以及签名人的不可否认性

  • 2019-04-01 22:59:22

    Android Studio 3.0 利用cmake搭建jni环境(很详细哦)

    我用的Android Studio是3.0的版本,然后想搭建一下jni的环境。这里把自己遇到的问题和注意点都记录下。 首先是需要在android studio里面安装最基本的环境。 打开Default Preference里面查看SDK Tool选项。

  • 2019-04-01 23:20:58

    隐藏在图片中的密钥

    在客户端开发的时候,有时需要把密钥保存在本地。这时就会遇到密钥安全性的问题。要保证密钥安全性,无非就是混淆、隐藏、白盒等手段。本文以隐藏在图片中来阐述密钥的安全保存。

  • 2019-04-01 23:22:33

    验证数字签名

    应预先设置验证首选项。在打开 PDF 后显示包含签名的验证详细信息时,这有助于确保数字签名有效。有关详细信息,请参阅设置签名验证首选项。

  • 2019-04-01 23:23:27

    图像隐写之使用PHP隐藏图像中的文本

    隐写术是一门研究隐藏信息的科学艺术,通过隐写术,可以只让发送者和接收者知道隐藏的信息。 图像隐写术则是研究将数据隐藏在图像中,通过该技术可以防止无关用户发现这些隐藏的信息或数据。