webpack学习笔记--压缩代码
对文本本身进行压缩的作用除了有提升网页加载速度的优势外,还具有混淆源码的作用。 由于压缩后的代码可读性非常差,就算别人下载到了网页的代码,也大大增加了代码分析和改造的难度。
下面来一一介绍如何在 Webpack 中压缩代码。
压缩 JavaScript
目前最成熟的 JavaScript 代码压缩工具是 UglifyJS , 它会分析 JavaScript 代码语法树,理解代码含义,从而能做到诸如去掉无效代码、去掉日志输出代码、缩短变量名等优化。
要在 Webpack 中接入 UglifyJS 需要通过插件的形式,目前有两个成熟的插件,分别是:
- UglifyJsPlugin :通过封装 UglifyJS 实现压缩。
- ParallelUglifyPlugin :多进程并行处理压缩,4-4使用ParallelUglifyPlugin 中有详细介绍。
由于 ParallelUglifyPlugin 在 4-4使用ParallelUglifyPlugin 中介绍过就不再复述, 这里重点介绍如何配置 UglifyJS 以达到最优的压缩效果。
UglifyJS 提供了非常多的选择用于配置在压缩过程中采用哪些规则,所有的选项说明可以在 其官方文档 上看到。 由于选项非常多,就挑出一些常用的拿出来详细讲解其应用方式:
- sourceMap :是否为压缩后的代码生成对应的 Source Map,默认为不生成,开启后耗时会大大增加。一般不会把压缩后的代码的 Source Map 发送给网站用户的浏览器,而是用于内部开发人员调试线上代码时使用。
- 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 : 是否提取出出现多次但是没有定义成变量去引用的静态值,例如把 x = 'Hello'; y = 'Hello' 转换成 var a = 'Hello'; x = a; y = b, 默认为不转换。为了达到更好的压缩效果,可以设置为 false 。
也就是说,在不影响代码正确执行的前提下,最优化的代码压缩配置为如下:
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,
}
}),
],
};
从以上配置中可以看出 Webpack 内置了 UglifyJsPlugin,需要指出的是 UglifyJsPlugin 当前采用的是 UglifyJS2 而不是老的 UglifyJS1, 这两个版本的 UglifyJS 在配置上有所区别,看文档时注意版本。
除此之外 Webpack 还提供了一个更简便的方法来接入 UglifyJSPlugin,直接在启动 Webpack 时带上 --optimize-minimize 参数,即 webpack --optimize-minimize , 这样 Webpack 会自动为你注入一个带有默认配置的 UglifyJSPlugin。本实例提供项目完整代码
压缩 ES6
虽然当前大多数 JavaScript 引擎还不完全支持 ES6 中的新特性,但在一些特定的运行环境下已经可以直接执行 ES6 代码了,例如最新版的 Chrome、ReactNative 的引擎 JavaScriptCore。
运行 ES6 的代码相比于转换后的 ES5 代码有如下优点:
- 一样的逻辑用 ES6 实现的代码量比 ES5 更少。
- JavaScript 引擎对 ES6 中的语法做了性能优化,例如针对 const 申明的变量有更快的读取速度。
所以在运行环境允许的情况下,我们要尽可能的使用原生的 ES6 代码去运行,而不是转换后的 ES5 代码。
在你用上面所讲的压缩方法去压缩 ES6 代码时,你会发现 UglifyJS 会报错退出,原因是 UglifyJS 只认识 ES5 语法的代码。 为了压缩 ES6 代码,需要使用专门针对 ES6 代码的 UglifyES。
UglifyES 和 UglifyJS 来自同一个项目的不同分支,它们的配置项基本相同,只是接入 Webpack 时有所区别。 在给 Webpack 接入 UglifyES 时,不能使用内置的 UglifyJsPlugin,而是需要单独安装和使用最新版本的 uglifyjs-webpack-plugin。 安装方法如下:
npm i -D uglifyjs-webpack-plugin@beta
Webpack 相关配置代码如下:
const UglifyESPlugin = require('uglifyjs-webpack-plugin')
module.exports = {
plugins: [
new UglifyESPlugin({
// 多嵌套了一层
uglifyOptions: {
compress: {
// 在UglifyJs删除没有用到的代码时不输出警告
warnings: false,
// 删除所有的 `console` 语句,可以兼容ie浏览器
drop_console: true,
// 内嵌定义了但是只用到一次的变量
collapse_vars: true,
// 提取出出现多次但是没有定义成变量去引用的静态值
reduce_vars: true,
},
output: {
// 最紧凑的输出
beautify: false,
// 删除所有的注释
comments: false,
}
}
})
]
}
同时,为了不让 babel-loader 输出 ES5 语法的代码,需要去掉 . babelrc
配置文件中的 babel-preset-env ,但是其它的 Babel 插件,比如 babel-preset-react 还是要保留, 因为正是 babel-preset-env 负责把 ES6 代码转换为 ES5 代码。本实例提供项目完整代码
压缩 CSS
CSS 代码也可以像 JavaScript 那样被压缩,以达到提升加载速度和代码混淆的作用。 目前比较成熟可靠的 CSS 压缩工具是 cssnano,基于 PostCSS。
cssnano 能理解 CSS 代码的含义,而不仅仅是删掉空格,例如:
margin: 10px 20px 10px 20px 被压缩成 margin: 10px 20px
color: #ff0000 被压缩成 color:red
还有很多压缩规则可以去其官网查看,通常压缩率能达到 60%。
把 cssnano 接入到 Webpack 中也非常简单,因为 css-loader 已经将其内置了,要开启 cssnano 去压缩代码只需要开启 css-loader 的 minimize 选项。 相关 Webpack 配置如下:
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 值
}),
],
};
本实例提供项目完整代码
webpack学习笔记--压缩代码的更多相关文章
- 更博不能忘——webpack学习笔记
webpack是前端构建系统就像grunt和gulp(之前有学习过grunt所以也就大概明白webpack是个什么东西),所以说前端技术大部分还真是相通的,现在觉得当时多看的东西并不白费,虽然长时间不 ...
- 【原】webpack学习笔记
之前在react的项目中有用过webpack,不过没有认真的去研究,这段时间又重新好好的学习一下webpack,发觉 webpack是一个很强大的东西.而且很好用,方便,接下来主要是做一下学习的笔记 ...
- webpack学习笔记一(入门)
webpack集成了模块加载和打包等功能 ,这两年在前端领域越来越受欢迎.平时一般是用requirejs.seajs作为模块加载用,用grunt/gulp作为前端构建.webpack作为模块化加载兼容 ...
- 【webpack学习笔记(一)】流行的前端模块化工具webpack初探
从开发文件到生产文件 有一天我突然意识到一个问题,在使用react框架搭建应用时,我使用到了sass/less,JSX模版以及ES6的语法在编辑器下进行开发,使用这些写法是可以提高开发的效率.可是 ...
- webpack学习笔记一:安装webpack、webpack-dev-server、内存加载js和html文件、loader处理非js文件
一 .webpack学习环境准备: 1:window系统 2:安装node.js 官方网址 下载好后下一步下一步安装即可 安装步骤略过....... 3:nrm的安装 打开cmd命令控制台 输入:n ...
- webpack学习笔记--区分环境
为什么需要区分环境 在开发网页的时候,一般都会有多套运行环境,例如: 在开发过程中方便开发调试的环境. 发布到线上给用户使用的运行环境. 这两套不同的环境虽然都是由同一套源代码编译而来,但是代码内容却 ...
- Webpack学习笔记九 webpack优化总结
webpack 优化笔记 webpack4 自带的优化包括 swingTree(摇摆树)和作用域提升 swingTree 比如入口文件 index.js引入通用方法 util, 里面有 10个方法, ...
- webpack 学习笔记 03 Code Splitting
Introduction 对于较大的web 应用来说,将所有的代码文件压缩成一个文件是不合适的,在部分代码文件只有特殊情况下才被需要的情况下,这无疑是一种浪费.webpack 提供了讲代码文件分块的能 ...
- webpack学习笔记(二)-- 初学者常见问题及解决方法
这篇文章是webpack学习第二篇,主要罗列了本人在实际操作中遇到的一些问题及其解决方法,仅供参考,欢迎提出不同意见. 注:本文假设读者已有webpack方面相关知识,故文中涉及到的专有名词不做另外解 ...
随机推荐
- mac使用pytesseract
import locale locale.setlocale(locale.LC_ALL, 'C') import pytesseract import pathlib import tracebac ...
- arx对正在操作的文件进行保存
//对正在操作的文件进行保存 STDMETHODIMP CTHDatabase::Save(void) { // TODO: 在此添加实现代码 Acad::ErrorStatus es ; try{ ...
- weblogic和was的巡检报告模板
weblogic巡检报告模板 https://max.book118.com/html/2017/0710/121553357.shtm 用jrockit How to tell Our WebLo ...
- 题解-bzoj4061 CERC-2012Farm and Factory
Problem Please contact lydsy2012@163.com! 题意概要:给定\(n\)点\(m\)边无向图,设定两个起点为\(1,2\),现要求在图中增加一个点,并将这个点与其他 ...
- FHQ Treap摘要
原理 以随机数维护平衡,使树高期望为logn级别 不依靠旋转,只有两个核心操作merge(合并)和split(拆分) 因此可持久化 先介绍变量 ; int n; struct Node { int v ...
- 【原创】大叔经验分享(39)spark cache unpersist级联操作
问题:spark中如果有两个DataFrame(或者DataSet),DataFrameA依赖DataFrameB,并且两个DataFrame都进行了cache,将DataFrameB unpersi ...
- PHP7运行环境搭建(Windows7)
注:本文来源于< PHP7运行环境搭建(Windows7) > php7号称能直追facebook的HHVM,为了体验一把传说中的高性能,我特意在本地电脑上尝试着安装了php7, ...
- iis配置问题
最近调试程序时发现一直用的是vs自带的服务器 当我切换成iis时,发现虽然能显示界面,却连不上数据库 (程序数据库的一系列操作是通过wcf ria完成的) 以前在winserver2012上也遇到过这 ...
- mvc 模式和mtc 模式的区别
首先说说Web服务器开发领域里著名的MVC模式,所谓MVC就是把Web应用分为模型(M),控制器(C)和视图(V)三层,他们之间以一种插件式的.松耦合的方式连接在一起,模型负责业务对象与数据库的映射( ...
- SpringCloud简介
1.什么是微服务? 微服务就是不同的模块部署在不同的服务器上面,通过接口去访问就是微服务 作用:利用分布式解决网站高并发带来的问题 2.什么是集群? 多台服务器部署相同应用构成一个集群 作用:通过负载 ...