webpack4 CSS Tree Shaking的使用


Posted in Javascript onSeptember 03, 2018

本次课程的代码目录(如下图所示):

webpack4 CSS Tree Shaking的使用

什么是tree-shaking

webpack 2 的到来带来的最棒的新特性之一就是tree-shaking 。tree-shaking源自于rollup.js,先如今,webpack 2也有类似的做法。

webpack 里的tree-shaking的到来不得不归功于es6规范的模块。为什么这么说,如今的前端模块规范很多,比较出流行的比如commonJS , AMD , es6 ,我简单的说一下commonJS和es6模块的区别。

1. CSS 也有 Tree Shaking?

是滴,随着 webpack 的兴起,css 也可以进行 Tree Shaking: 以去除项目代码中用不到的 CSS 样式,仅保留被使用的样式代码。

为了方便理解 Tree Shaking 概念,并且与 JS Tree Shaking 进行横向比较,请查看:webpack4 系列教程(八): JS Tree Shaking

2. 项目环境仿真

因为 CSS Tree Shaking 并不像 JS Tree Shaking 那样方便理解,所以首先要先模拟一个真实的项目环境,来体现 CSS 的 Tree Shaking 的配置和效果。

我们首先编写 /src/css/base.css 样式文件,在文件中,我们编写了 3 个样式类。但在代码中,我们只会使用 .box 和 .box--big 这两个类。代码如下所示:

/* base.css */
html {
 background: red;
}

.box {
 height: 200px;
 width: 200px;
 border-radius: 3px;
 background: green;
}

.box--big {
 height: 300px;
 width: 300px;
 border-radius: 5px;
 background: red;
}

.box-small {
 height: 100px;
 width: 100px;
 border-radius: 2px;
 background: yellow;
}

按照正常使用习惯,DOM 操作来实现样式的添加和卸载,是一贯技术手段。所以,入口文件 /src/app.js 中创建了一个 <div> 标签,并且将它的类设为 .box

// app.js

import base from "./css/base.css";

var app = document.getElementById("app");
var div = document.createElement("div");
div.className = "box";
app.appendChild(div);

最后,为了让环境更接近实际环境,我们在index.html的一个标签,也引用了定义好的 box-big 样式类。

<!DOCTYPE html>
<html lang="en">
<head>
 <meta charset="UTF-8">
 <meta name="viewport" content="width=device-width, initial-scale=1.0">
 <meta http-equiv="X-UA-Compatible" content="ie=edge">
 <link rel="stylesheet" href="./dist/app.min.css" rel="external nofollow" >
 <title>Document</title>
</head>
<body>
 <div id="app">
 <div class="box-big"></div>
 </div>
 <script src="./dist/app.bundle.js"></script>
</body>
</html>

按照我们的仿真的环境,最终 Tree Shaking 之后的效果应该是:打包后的 css 文件不含有 box-small 样式类。下面,就实现这个效果!

3. 认识下 PurifyCSS

没错,就是这货帮助我们进行 CSS Tree Shaking 操作。为了能准确指明要进行 Tree Shaking 的 CSS 文件,它还有好朋友 glob-all (另一个第三方库)。

glob-all 的作用就是帮助 PurifyCSS 进行路径处理,定位要做 Tree Shaking 的路径文件。

它们俩搭配起来,画风如下:

const PurifyCSS = require("purifycss-webpack");
const glob = require("glob-all");

let purifyCSS = new PurifyCSS({
 paths: glob.sync([
 // 要做CSS Tree Shaking的路径文件
 path.resolve(__dirname, "./*.html"),
 path.resolve(__dirname, "./src/*.js")
 ])
});

好了,这只是一个小小的 demo。下面我们要把它用到我们的webpack.config.js中来。

4. 编写配置文件

为了方便最后检查打包后的 css 文件,配置中还使用了 extract-text-webpack-plugin 这个插件。如果忘记了它的用法,请查看:

webpack4 系列教程(六): 处理 SCSS
webpack4 系列教程(五): 处理 CSS

所以,我们的package.json文件如下:

{
 "devDependencies": {
 "css-loader": "^1.0.0",
 "extract-text-webpack-plugin": "^4.0.0-beta.0",
 "glob-all": "^3.1.0",
 "purify-css": "^1.2.5",
 "purifycss-webpack": "^0.7.0",
 "style-loader": "^0.21.0",
 "webpack": "^4.16.0"
 }
}

安装完相关插件后,我们需要在 webpack 的plugins配置中引用第三部分定义的代码。

然后结合extract-text-webpack-plugin的配置,编写如下webpack.config.js:

// webpack.config.js
const path = require("path");
const PurifyCSS = require("purifycss-webpack");
const glob = require("glob-all");
const ExtractTextPlugin = require("extract-text-webpack-plugin");

let extractTextPlugin = new ExtractTextPlugin({
 filename: "[name].min.css",
 allChunks: false
});

let purifyCSS = new PurifyCSS({
 paths: glob.sync([
 // 要做CSS Tree Shaking的路径文件
 path.resolve(__dirname, "./*.html"), // 请注意,我们同样需要对 html 文件进行 tree shaking
 path.resolve(__dirname, "./src/*.js")
 ])
});

module.exports = {
 entry: {
 app: "./src/app.js"
 },
 output: {
 publicPath: __dirname + "/dist/",
 path: path.resolve(__dirname, "dist"),
 filename: "[name].bundle.js",
 chunkFilename: "[name].chunk.js"
 },
 module: {
 rules: [
 {
 test: /\.css$/,
 use: ExtractTextPlugin.extract({
  fallback: {
  loader: "style-loader",
  options: {
  singleton: true
  }
  },
  use: {
  loader: "css-loader",
  options: {
  minimize: true
  }
  }
 })
 }
 ]
 },
 plugins: [extractTextPlugin, purifyCSS]
};

5. 结果分析

命令行运行webpack打包后,样式文件被抽离到了 /dist/app.min.css 文件中。文件内容如下图所示(肯定好多朋友懒得手动打包):

webpack4 CSS Tree Shaking的使用

我们在index.html 和 src/app.js 中引用的样式都被打包了,而没有被使用的样式类--box-small,就没有出现在图片中。成功!

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
Js 时间函数getYear()的使用问题探讨
Apr 01 Javascript
JS实现带缓冲效果打开、关闭、移动一个层的方法
May 09 Javascript
javascript日期计算实例分析
Jun 29 Javascript
JS正则表达式比较常见用法
Jan 26 Javascript
javascript cookie基础应用之记录用户名的方法
Sep 20 Javascript
easyui messager alert 三秒后自动关闭提示的实例
Nov 07 Javascript
使用jQuery实现一个类似GridView的编辑,更新,取消和删除的功能
Mar 15 Javascript
Bootstrap免费字体和图标网站(值得收藏)
Mar 16 Javascript
深入浅出理解JavaScript闭包的功能与用法
Aug 01 Javascript
vue 表单验证按钮事件交由父组件触发的方法
Dec 17 Javascript
浅谈Vue的响应式原理
May 30 Javascript
vue实现手机号码的校验实例代码(防抖函数的应用场景)
Sep 05 Javascript
解决Vue+Element ui开发中碰到的IE问题
Sep 03 #Javascript
webpack4 处理SCSS的方法示例
Sep 03 #Javascript
解决vue打包css文件中背景图片的路径问题
Sep 03 #Javascript
解决Vue2.0中使用less给元素添加背景图片出现的问题
Sep 03 #Javascript
vue组件(全局,局部,动态加载组件)
Sep 02 #Javascript
详解jQuery中的easyui
Sep 02 #jQuery
vue-cli脚手架的安装教程图解
Sep 02 #Javascript
You might like
phpmyadmin 常用选项设置详解版
2010/03/07 PHP
关于UEditor编辑器远程图片上传失败的解决办法
2012/08/31 PHP
Yii操作数据库的3种方法
2014/03/11 PHP
Yii中表单用法实例详解
2016/01/05 PHP
PHP图像识别技术原理与实现
2016/10/27 PHP
微信自定义分享php代码分析
2016/11/24 PHP
PHP5.5新特性之yield理解与用法实例分析
2019/01/11 PHP
TP5框架model常见操作示例小结【增删改查、聚合、时间戳、软删除等】
2020/04/05 PHP
由JavaScript中call()方法引发的对面向对象继承机制call的思考
2011/09/12 Javascript
jquery随机展示头像代码
2011/12/21 Javascript
你必须知道的Javascript知识点之&quot;深入理解作用域链&quot;的介绍
2013/04/23 Javascript
js阻止冒泡及jquery阻止事件冒泡示例介绍
2013/11/19 Javascript
整理AngularJS框架使用过程当中的一些性能优化要点
2016/03/05 Javascript
Bootstrap布局之栅格系统详解
2016/06/13 Javascript
JavaScript防止全局变量污染的方法总结
2018/08/02 Javascript
微信小程序自定义toast弹窗效果的实现代码
2018/11/15 Javascript
vue-cli系列之vue-cli-service整体架构浅析
2019/01/14 Javascript
微信小程序如何自定义table组件
2019/06/29 Javascript
[02:20]DOTA2英雄基础教程 黑暗贤者
2013/12/19 DOTA
[03:12]2016完美“圣”典风云人物:单车专访
2016/12/02 DOTA
python 字符串格式化代码
2013/03/17 Python
Python队列的定义与使用方法示例
2017/06/24 Python
PyQt5每天必学之工具提示功能
2018/04/19 Python
python3+PyQt5+Qt Designer实现扩展对话框
2018/04/20 Python
win10下tensorflow和matplotlib安装教程
2018/09/19 Python
对Tensorflow中Device实例的生成和管理详解
2020/02/04 Python
15行Python代码实现免费发送手机短信推送消息功能
2020/02/27 Python
python 获取当前目录下的文件目录和文件名实例代码详解
2020/03/10 Python
浅谈python 调用open()打开文件时路径出错的原因
2020/06/05 Python
Python+Kepler.gl实现时间轮播地图过程解析
2020/07/20 Python
利用python绘制中国地图(含省界、河流等)
2020/09/21 Python
表达自我的市场:Society6
2018/08/01 全球购物
办理信用卡工作证明
2014/01/11 职场文书
班主任寄语2015
2015/02/26 职场文书
药品销售内勤岗位职责
2015/04/13 职场文书
初二物理教学反思
2016/02/19 职场文书