Skip to content

(三十一)tree shaking清理未使用css

阿峰 edited this page May 30, 2023 · 1 revision

步骤三十一

优化构建结果文件-tree-shaking清理未使用css

js中会有未使用到的代码,css中也会有未被页面使用到的样式,可以通过

  1. 安装依赖:
npm i purgecss-webpack-plugin@5 glob-all -D
  1. 修改webpack.prod.js
// webpack.prod.js
// ...
const globAll = require('glob-all')
const { PurgeCSSPlugin } = require('purgecss-webpack-plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
module.exports = {
  // ...
  plugins: [
    // 抽离css插件
    new MiniCssExtractPlugin({
      filename: 'static/css/[name].[contenthash:8].css'
    }),
    // 清理无用css
    new PurgeCSSPlugin({
      // 检测src下所有tsx文件和public下index.html中使用的类名和id和标签名称
      // 只打包这些文件中用到的样式
      paths: globAll.sync([
        `${path.join(__dirname, '../src')}/**/*.tsx`,
        path.join(__dirname, '../public/index.html')
      ]),
    }),
  ]
}
  1. 测试一下,用上面配置解析图片文件代码拿过来,修改App.tsx
import React from 'react'
import './app.css'
import './app.less'

function App() {
  return (
    <>
      <div className='smallImg'></div>
      <div className='bigImg'></div>
    </>
  )
}
export default App
  1. App.tsx中有两个div,类名分别是smallImg和bigImg,当前app.less代码为
#root {
  .smallImg {
    width: 69px;
    height: 75px;
    background: url('./assets/imgs/5kb.png') no-repeat;
  }
  .bigImg {
    width: 232px;
    height: 154px;
    background: url('./assets/imgs/22kb.png') no-repeat;
  }
}
  1. 此时先执行一下打包,查看main.css

image

因为页面中中有h2标签, smallImg和bigImg类名,所以打包后的css也有,此时修改一下app.less中的 .smallImg为 .smallImg1,此时 .smallImg1就是无用样式了,因为没有页面没有类名为 .smallImg1的节点,再打包后查看 main.css

image

可以看到main.css已经没有 .smallImg1类名的样式了,做到了删除无用css的功能。

但是purgecss-webpack-plugin插件不是全能的,由于项目业务代码的复杂,插件不能百分百识别哪些样式用到了,哪些没用到,所以请不要寄希望于它能够百分百完美解决你的问题,这个是不现实的

  1. 插件本身也提供了一些白名单safelist属性

符合配置规则选择器都不会被删除掉,比如使用了组件库antd, purgecss-webpack-plugin插件检测src文件下tsx文件中使用的类名和id时,是检测不到在src中使用antd组件的类名的,打包的时候就会把antd的类名都给过滤掉,可以配置一下安全选择列表,避免删除antd组件库的前缀ant。

new PurgeCSSPlugin({
  // ...
  safelist: {
    standard: [/^ant-/], // 过滤以ant-开头的类名,哪怕没用到也不删除
  }
})
Clone this wiki locally