如何根据 Can I Use 数据动态移除过时前缀
解读
面试官抛出此题,核心想验证三件事:
- 你是否把 Grunt 当成“流程编排器”而非“黑盒工具”,知道该在哪个环节插入“智能后处理”逻辑;
- 你是否理解 Autoprefixer 的底层机制,并能把它与 Can I Use 的 JSON 数据流打通;
- 你是否兼顾国内场景(微信内核、360 安全、QQ 浏览器、国产系统)与官方浏览器列表的差异,做到“降级兼容但不冗余”。
一句话:不是问“怎么压缩 CSS”,而是问“怎么让 Grunt 在构建时实时判断哪些前缀已死并自动剔除,同时不破坏业务”。
知识点
- Autoprefixer 基于 PostCSS,内部使用 browserslist 语义化查询,数据源正是 Can I Use 的 JSON 包(caniuse-lite);
- Grunt 生态里官方插件 grunt-postcss 是标准桥梁,但默认只“加”前缀,不“减”;要“减”必须再配 postcss-unprefix 或 cssnano 的 discardUnused 规则;
- browserslist 查询语句支持
> 1% in CN、iOS >= 9、Chrome >= 49等,国内项目务必加in CN限定,否则按全球份额会把早已淘汰的国产浏览器误判为“活着”; - Gruntfile 里可用
grunt.config.set('postcss.options.browsers', browserslist)动态回写,实现“同一份构建脚本,dev 用宽松规则,prod 用严格规则”; - CI 场景下需锁死 caniuse-lite 版本号,防止上游数据更新导致构建产物突变;
- 若公司内网隔离,需把 caniuse-lite 离线包提前打进私有 npm 仓库,并在
.npmrc里配@browserlist:registry=https://your.npm; - Sourcemap 链路必须保留,方便测试同学回溯“哪一行前缀被删”;否则线上出样式事故难以定位。
答案
-
安装依赖
npm i -D grunt-postcss autoprefixer postcss-unprefix caniuse-lite browserslist -
在 Gruntfile.js 中注册任务
module.exports = function(grunt) { // 1) 基于国内份额动态生成 browserslist const browsers = require('browserslist')([ '> 1% in CN', 'iOS >= 9', 'Chrome >= 49', 'not dead' ]); // 2) 配置 postcss 管道:先删再补,确保“只留必要” grunt.initConfig({ postcss: { options: { processors: [ require('postcss-unprefix')({ browsers }), // 先剔除过时 require('autoprefixer')({ browsers, cascade: false }) // 再补最新 ] }, dist: { src: 'src/css/*.css', expand: true, ext: '.css' } } }); grunt.loadNpmTasks('grunt-postcss'); grunt.registerTask('css', ['postcss']); }; -
本地验证
npx grunt css用
git diff观察产物:- 旧代码
-webkit-border-radius: 5px被整行删除; - 新代码只保留
border-radius: 5px与 微信内核仍需要的-webkit-line-clamp。
- 旧代码
-
上线前加锁
在 package.json 追加"resolutions": { "caniuse-lite": "1.0.30001546" }防止 CI 次日构建结果突变。
拓展思考
- 双轨策略:给 H5 与小程序分别维护
browserslist.h5.js与browserslist.mini.js,在 Gruntfile 里用grunt.option('target')动态切换,一份源码两套前缀; - 增量移除:结合
grunt-newer,只对变更文件跑 postcss,10 万行级别项目可节省 60% 构建时间; - 合规审计:在
postcss管道后插入自定义插件,把被删前缀列表写入 dist/prefix-deprecated.json,方便法务留痕; - 未来替代:当团队迁移到 Vite/Rollup 时,同一套 browserslist 配置可直接复用,只需把 grunt-postcss 换成 rollup-plugin-postcss,实现构建工具无痛升级。