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 相关文章推荐
prototype 1.5相关知识及他人笔记
Dec 16 Javascript
十分钟打造AutoComplete自动完成效果代码
Dec 26 Javascript
jQuery学习笔记之jQuery的DOM操作
Dec 22 Javascript
jQuery提示插件alertify使用指南
Apr 21 Javascript
javascript判断并获取注册表中可信任站点的方法
Jun 01 Javascript
js实现带圆角的两级导航菜单效果代码
Aug 24 Javascript
jquery中val()方法是从最后一个选项往前读取的
Sep 06 Javascript
AngularJS ng-template寄宿方式用法分析
Nov 07 Javascript
Angular2学习笔记——详解NgModule模块
Dec 02 Javascript
JavaScript中transform实现数字翻页效果
Mar 08 Javascript
Bootstrap fileinput文件上传预览插件使用详解
May 16 Javascript
编写React组件项目实践分析
Mar 04 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
一个数据采集类
2007/02/14 PHP
PHP imagecreatefrombmp 从BMP文件或URL新建一图像
2012/07/16 PHP
php模拟js函数unescape的函数代码
2012/10/20 PHP
PHP基础之运算符的使用方法
2013/04/28 PHP
PHP获取当前URL路径的处理方法(适用于多条件筛选列表)
2017/02/10 PHP
PHP设计模式(四)原型模式Prototype实例详解【创建型】
2020/05/02 PHP
AeroWindow 基于JQuery的弹出窗口插件
2011/06/27 Javascript
当jQuery遭遇CoffeeScript的时候 使用分享
2011/09/17 Javascript
详解AngularJS中的作用域
2015/06/17 Javascript
AngularJS基础 ng-focus 指令简单示例
2016/08/01 Javascript
Javascript+CSS3实现进度条效果
2016/10/28 Javascript
js时间戳格式化成日期格式的多种方法介绍
2017/02/16 Javascript
jquery实现焦点轮播效果
2017/02/23 Javascript
详解vue嵌套路由-params传递参数
2017/05/23 Javascript
jQuery实现动态添加节点与遍历节点功能示例
2017/11/09 jQuery
VueJs 搭建Axios接口请求工具
2017/11/20 Javascript
Vue 使用计时器实现跑马灯效果的实例代码
2019/07/11 Javascript
Vue的双向数据绑定实现原理解析
2020/02/17 Javascript
JS中的变量作用域(console版)
2020/07/18 Javascript
python解析xml文件操作实例
2014/10/05 Python
详解Python中的条件判断语句
2015/05/14 Python
浅谈pyhton学习中出现的各种问题(新手必看)
2017/05/17 Python
python 接口测试response返回数据对比的方法
2018/02/11 Python
python读取视频流提取视频帧的两种方法
2020/10/22 Python
如何实现删除numpy.array中的行或列
2018/05/08 Python
Python 爬虫之Beautiful Soup模块使用指南
2018/07/05 Python
Python操作SQLite数据库过程解析
2019/09/02 Python
pygame实现俄罗斯方块游戏(AI篇2)
2019/10/29 Python
django-利用session机制实现唯一登录的例子
2020/03/16 Python
《一株紫丁香》教学反思
2014/02/19 职场文书
丧事主持词大全
2014/04/02 职场文书
市场开发与营销专业求职信范文
2014/05/01 职场文书
六一儿童节致辞
2015/07/31 职场文书
创业计划书之农家乐
2019/10/09 职场文书
浅谈 JavaScript 沙箱Sandbox
2021/11/02 Javascript
SQL Server Agent 服务无法启动
2022/04/20 SQL Server