深入浅出webpack学习(19)--压缩代码

压缩代码

浏览器从服务器访问网页时获取的JavaScript,css资源都是文本形式的,文件越大网页加载时间越长。 为了提升网页加速速度和减少网络传输流量, 可以对这些资源进行压缩。 压缩的方法除了可以通过GIZP算法对文件压缩外,还可以对文本本身压缩。

对文本本身进行压缩的作用除了有提升网页加载速度的优势外, 还具有混淆代码的作用。 由于压缩后的代码可读性非常差, 就算别人下载到网页的代码,也大大增加了代码分析和改造的难度。

压缩JavaScript

目前最成熟的JavaScript压缩工具就是UglifyJS, 它会分析JavaScript的代码语法树, 理解代码含义, 从而能做到诸如去掉无效代码,去掉日志输出代码,缩短变量名等优化。

要在webpack中接入UglifyJS需要通过插件的形式,目前有两个成熟的插件,分别是:

UglifyJsPlugin: 通过封装UglifyJS实现压缩。
 ParalleUglifyPlugin: 多进程并行处理压缩

UglifyJS提供了非常多的选择用于配置在压缩过程中采用哪些规则,我们挑出一些常用的拿出来详细讲解一下

  • sourceMap:是否为压缩后的代码生成对用的SourceMap, 默认不生成,开启后耗时会大大增加。一般不会把压缩后的代码SouceMap发送给网站用户的浏览器,而是用于内部开发人员调试线上代码时使用。
  • beautify:是否输出可读性较强的代码,会保留空格和制表符,默认为是,为了达到更好的压缩效果,可以设置为false。
  • comments:是否保留代码中的注释, 默认保留, 为了达到压缩更好的压缩效果,可以设置为false。
  • compress.warnings:是否在UglifyJS删除没有用到的代码时输出警告信息,默认为输出。可以设置为false以关闭这些不大的警告。
  • drop_console:是否剔除代码中所有的console语句,默认不剔除,开启后不仅可以提升代压缩效果,也可以兼容不支持console语句IE浏览器。
  • collapse_vars:是否内嵌定义了但是只永达一次的变量,例如把var x=5; y=x抓换成 y=5, 默认不转换。为了达到更好的压缩效果,可以设置为false。
  • reduce_vars:是否提取出出现多次但是没有定义成变量去引用的静态值。

也就是说,在不影响代码正确执行的前提下,最优化的代码压缩配置为如下:

const UglifyJSPlugin = require('webpack/lib/optimize/UglifyJsPlugin');

module.exports = {
  plugins: [
    // 压缩输出的 JS 代码
    new UglifyJSPlugin({
      compress: {
        // 在UglifyJs删除没有用到的代码时不输出警告
        warnings: false,
        // 删除所有的 `console` 语句,可以兼容ie浏览器
        drop_console: true,
        // 内嵌定义了但是只用到一次的变量
        collapse_vars: true,
        // 提取出出现多次但是没有定义成变量去引用的静态值
        reduce_vars: true,
      },
      output: {
        // 最紧凑的输出
        beautify: false,
        // 删除所有的注释
        comments: false,
      }
    }),
  ],
};

压缩CSS

CSS代码也可以像JavaScript那样被压缩,目前比较成熟的css压缩工具有cssnano,基于PostCSS.

cssnano能理解css代码的含义,而不仅仅是删除空格。

把cssnano接入到webpack中也很简单,因为css-loader已经将其内置了,要开启cssnan去压缩代码只需要开启css-loader的minimize选项。

const path = require('path');
const {WebPlugin} = require('web-webpack-plugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');

module.exports = {
  module: {
    rules: [
      {
        test: /\.css/,// 增加对 CSS 文件的支持
        // 提取出 Chunk 中的 CSS 代码到单独的文件中
        use: ExtractTextPlugin.extract({
          // 通过 minimize 选项压缩 CSS 代码
          use: ['css-loader?minimize']
        }),
      },
    ]
  },
  plugins: [
    // 用 WebPlugin 生成对应的 HTML 文件
    new WebPlugin({
      template: './template.html', // HTML 模版文件所在的文件路径
      filename: 'index.html' // 输出的 HTML 的文件名称
    }),
    new ExtractTextPlugin({
      filename: `[name]_[contenthash:8].css`,// 给输出的 CSS 文件名称加上 Hash 值
    }),
  ],
};

相关推荐