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 相关文章推荐
理解JavaScript中的事件
Sep 23 Javascript
键盘 keycode的值 javascript时触发事件时很有用的要素
Nov 02 Javascript
基于jQuery的前端数据通用验证库
Aug 08 Javascript
CSS中position属性之fixed实现div居中
Dec 14 Javascript
JQuery实现的按钮倒计时效果
Dec 23 Javascript
谈谈对JavaScript原生拖放的深入理解
Sep 20 Javascript
JavaScript中return用法示例
Nov 29 Javascript
使用Dropzone.js上传的示例代码
Oct 10 Javascript
jQuery实现模糊查询的方法分析
May 10 jQuery
浅谈webpack4.x 入门(一篇足矣)
Sep 05 Javascript
react-navigation之动态修改title的内容
Sep 26 Javascript
JS/HTML5游戏常用算法之碰撞检测 包围盒检测算法详解【矩形情况】
Dec 13 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
PHP 面向对象详解
2012/09/13 PHP
php格式化日期实例分析
2014/11/12 PHP
PHP中的use关键字及文件的加载详解
2016/11/28 PHP
PHP使用ActiveMQ实现消息队列的方法详解
2019/05/31 PHP
Laravel中如何轻松容易的输出完整的SQL语句
2020/07/26 PHP
在网页里看flash的trace数据的js类
2009/01/10 Javascript
Extjs EditorGridPanel中ComboBox列的显示问题
2011/07/04 Javascript
jquery及原生js获取select下拉框选中的值示例
2013/10/25 Javascript
Javascript执行效率全面总结
2013/11/04 Javascript
javascript使用定时函数实现跳转到某个页面
2013/12/25 Javascript
jquery操作下拉列表、文本框、复选框、单选框集合(收藏)
2014/01/08 Javascript
点击表单提交时出现jQuery没有权限的解决方法
2014/07/23 Javascript
上传图片js判断图片尺寸和格式兼容IE
2014/09/01 Javascript
jquery实现点击label的同时触发文本框点击事件的方法
2015/06/05 Javascript
jQuery实现类似淘宝网图片放大效果的方法
2015/07/08 Javascript
在WordPress中加入Google搜索功能的简单步骤讲解
2016/01/04 Javascript
js的form表单提交url传参数(包含+等特殊字符)的两种解决方法
2016/05/25 Javascript
AngularJS入门教程之链接与图片模板详解
2016/08/19 Javascript
WEB前端实现裁剪上传图片功能
2016/10/17 Javascript
判断颜色是否合法的正则表达式(详解)
2017/05/03 Javascript
JavaScript内置对象math,global功能与用法实例分析
2019/06/10 Javascript
Python脚本判断 Linux 是否运行在虚拟机上
2015/04/25 Python
Numpy之文件存取的示例代码
2018/08/03 Python
解决python3捕获cx_oracle抛出的异常错误问题
2018/10/18 Python
使用Python来做一个屏幕录制工具的操作代码
2020/01/18 Python
详解Python高阶函数
2020/08/15 Python
python性能测试工具locust的使用
2020/12/28 Python
Java程序员面试题
2016/09/27 面试题
我的梦想演讲稿
2014/04/30 职场文书
2014县政府领导班子三严三实对照检查材料思想汇报
2014/09/26 职场文书
以权谋私检举信范文
2015/03/02 职场文书
python实现Thrift服务端的方法
2021/04/20 Python
Python网络编程之ZeroMQ知识总结
2021/04/25 Python
基于Redis过期事件实现订单超时取消
2021/05/08 Redis
python使用torch随机初始化参数
2022/03/22 Python
关于pytest结合csv模块实现csv格式的数据驱动问题
2022/05/30 Python