关于tree-shaking:CSS-Tree-Shaking

我的项目引入bricks根底组件库,并不是独自引入每一个所依赖的根底组件款式,而是在入口文件全局引入所有款式import '@casstime/bricks/lib/styles/bricks.scss';,这就导致一些没有被应用的组件款式被打包到最终产物中,须要对款式做树摇解决。 接下来就该 PurgeCSS 上场了。PurgeCSS 是一个用来删除未应用的 CSS 代码的工具。能够将它作为你的开发流程中的一个环节。 当你构建一个网站时,你可能会决定应用一个 CSS 框架,例如 TailwindCSS、Bootstrap、MaterializeCSS、Foundation 等,然而,你所用到的也只是框架的一小部分而已,大量 CSS 款式并未被应用。PurgeCSS 通过剖析你的内容和 CSS 文件,首先它将 CSS 文件中应用的选择器与内容文件中的选择器进行匹配,而后它会从 CSS 中删除未应用的选择器,从而生成更小的 CSS 文件。 webpack对应插件purgecss-webpack-plugin,该插件的应用依赖款式抽离插件mini-css-extract-plugin,只有先将款式抽离成独立文件后能力将 CSS 文件中应用的选择器与内容文件中的选择器进行匹配,而后它会从 CSS 中删除未应用的选择器,从而生成更小的 CSS 文件。 插件purgecss-webpack-plugin的应用须要指定paths属性,通知purgecss须要剖析的文件列表,这些文件中应用的选择器与抽离的款式文件中的选择器进行匹配,从而剔除未应用的选择器。 因为我的项目中应用到款式的文件有src目录和引入的业务组件以及bricks根底组件,所以须要将这些文件目录指定为被剖析的列表,这些文件中应用到的款式选择器不会被剔除掉 // config-overrides.jsconst fs = require('fs');const path = require('path');const glob = require('glob-all');const webpack = require('webpack');const PurgeCSSPlugin = require('purgecss-webpack-plugin');const paths = require('react-scripts/config/paths');/** css tree shaking */function CssTreeShaking(config) { /** 开发环境下不做非凡解决 */ if (process.env.NODE_ENV === 'development') return; /** 有一些动静款式须要手动匹配保留,形如classNames=`icon-${type}` classNames=`mall-sidebar__${name}-icon` */ function collectSafelist() { return { standard: ['icon', /^icon-/, /^mall-sidebar__/, /^mall-right-trial-modal/], deep: [/^icon-/, /^mall-sidebar__/, /^mall-right-trial-modal/], greedy: [/^icon-/, /^mall-sidebar__/, /^mall-right-trial-modal/], }; } /** 收集我的项目中应用到的bricks组件(引入的业务组件中可能也有应用bricks组件) */ var files = glob.sync([ path.join(paths.appSrc, '/**/*.{ts,tsx}'), path.resolve(__dirname, `./node_modules/@casstime/bre-*/**/*.tsx`), path.resolve(__dirname, `./node_modules/@casstime/mall-*/**/*.tsx`), ]); /** 正则匹配我的项目中应用了哪些bricks组件 */ let usedComps = []; files.forEach((filePath) => { const code = fs.readFileSync(filePath, 'utf-8'); const reg = new RegExp(/import\s+\{(.*)\}\s+from\s+'@casstime\/bricks'/); const ret = code.match(reg); if (ret) { const comps = ret[1].replace(/\s+/g, '').toLowerCase().split(','); usedComps.push(...comps); } }); /** 应用到bricks组件的文件列表 */ const usedBrsPaths = [...new Set(usedComps)].map((comp) => { return path.resolve(__dirname, `./node_modules/@casstime/bricks/lib/components/${comp}/*.js`); }); /** 收集我的项目中应用到业务组件的门路 */ const usedBrePaths = [ path.resolve(__dirname, `./node_modules/@casstime/bre-*/**/*.tsx`), path.resolve(__dirname, `./node_modules/@casstime/mall-*/**/*.tsx`), ]; /** 款式树摇 */ const purgeCSSPlugin = new PurgeCSSPlugin({ /** paths示意这些文件中应用的款式须要保留,没有应用的款式将会被剔除 */ paths: glob.sync( [paths.appHtml, path.join(paths.appSrc, '/**/*.{ts,tsx}', ...usedBrsPaths, ...usedBrePaths], { nodir: true }, ), // fontFace: true, safelist: collectSafelist, }); config.plugins.push(purgeCSSPlugin);}module.exports = function override(config, env) { CssTreeShaking(config); return config;};应用上述purgecss-webpack-plugin解决会有一个问题,那就是没有思考到css modules的影响,因为款式选择器被哈希化,与剖析文件中应用的款式选择器不能匹对,导致被剔除掉了 ...

September 1, 2022 · 3 min · jiezi

关于tree-shaking:从过去到现在聊聊-Treeshaking

前言Tree-shaking 这一术语在前端社区内,起初是 Rich Harris 在 Rollup 中提出。简略概括起来,Tree-shaking 能够使得我的项目最终构建(Bundle)后果中只蕴含你理论须要的代码。 而且,说到 Tree-shaking,不不免提及 Dead Code Elimation,置信很多同学在一些对于 Tree-shaking 的文章中都会看到诸如这样的形容:Tree-shaking 是一项 Dead Code Elimation(以下统称 DCE)技术。 那么,既然有了 DCE 这一术语,为什么又要造一个 Tree-shaking 术语?存在既有价值,上面,让咱们一起来看看 Rich Harris 是如何答复这个问题的。 1 Tree-shaking Vs Dead Code Elimaion在过后 Rich Haris 针对这一发问专门写了这篇文章《Tree-shaking versus dead code elimination》,文中示意 DCE 和 Tree-shaking 最终的指标是统一的(更少的代码),然而它们依然是存在区别的。 Rich Haris 举了个做蛋糕的例子,指出 DCE 就好比在做蛋糕的时候间接把鸡蛋放入搅拌,最初在做好的蛋糕中取出蛋壳,这是不完满的做法,而 Tree-shaking 则是在做蛋糕的时候只放入我想要的货色,即不会把蛋壳放入搅拌制作蛋糕。 因而,Tree-shaking 表白的不是指打消 Dead Code,而是指保留 Live Code。即便最终 DCE 和 Tree-shaking 的后果是统一的,然而因为 JavaScript 动态剖析的局限性,理论过程并不同。并且,蕴含有用的代码能够失去更好的后果,从外表看(做蛋糕的例子)这也是一种更合乎逻辑的办法。 此外,过后 Rich Haris 也认为 Tree-shaking 可能不是一个很好的名称,思考过用 Live Code Inclusion 这个短语来示意,然而仿佛会造成更多的困惑......让咱们看一下 Rich Haris 的原话: ...

August 9, 2021 · 3 min · jiezi

webpack tree shaking 总结

原文链接 https://www.webpackjs.com/gui…什么是tree shakingtree shaking 是一个术语,用于描述移除JavaScript 上下文中的未引用代码为什么可以实现它依赖ES2015 模块系统中的静态结构特性,例如import 和export在webpack 中如何用版本要求:webpack 4。 在package.json 中添加 sideEffects.副作用的定义是,在导入时会执行特殊行为的代码,而不是仅仅暴露一个export 或多个export。例如 polyfill, 它影响全局作用域,并且通常不提供export。如果所有代码都不包含副作用,将其设置为false. webpack 就可以安全地删除未用到的export 导出如果你的代码确实有一些副作用,你可以为sideEffects 提供一个数组。ps: 任何导入的文件都会受到tree shaking 的影响。这意味着,如果在项目中使用类似css-loader 并导入css文件,需要将其添加到side effect 列表中,以免在生成模式中无意将它删除。压缩输出设置webpack mode: production 就可以在bundle 中删除那些未被引用的代码2019年第一篇

January 2, 2019 · 1 min · jiezi