bug表现
由于兼容ie的一段css代码,某一个文件的样式全部丢失。
场景
我先说一下我们的场景,我们目前有一个主包 A。主包 A 使用 webpack 的 cssnano 进行压缩。然后有一个子包 A-1(神奇流程)。子包 A-1 是主包 A 的依赖。这个子包使用 vite 的 esbuild 进行压缩。其中子包A-1中依赖了antdv4.10
里面有 \9 这样一句兼容ie的代码
原因
- 最根本的原因在于 样式压缩库对于ie兼容代码的解析异常。A-1包中存在着ie的兼容代码,但是 cssnano 和 esbuild的解析同时有异常的情况。cssnano在 压缩的时候 会将无效的转义符进行压缩,而esbuild在解析的时候并没有将ie的兼容代码作为合法的字符。这会产出
a{display:none \}
这样的代码。最后把大括号的后半段转义了,导致整段css样式文件都会失效。具体可以参考我向esbuild提的issue:github.com/evanw/esbui…
最小复现bug源码
index.less
.ant-container{
display: none \9;
}
esbuild.js
import fs from 'fs'
import { transform } from 'esbuild'
import postcss from 'postcss';
import cssnanoPlugin from 'cssnano';
let input = fs.readFileSync('./index.less','utf-8');
transform(input, { loader: 'css',minify: true }).then(({
code
})=>{
// 写入文件
postcss([cssnanoPlugin]).process(code).then(({ css }) => {
console.log("css:", css)
fs.writeFileSync('./index.css',css)
})
})
经过了上方的操作后,会生成如下代码
.ant-container{display:none \}
这段代码最后的那个转义符会毁了这个css文件。。
解决方案
-
解决方案:
- 方案1:子包取消压缩
- 方案2:统一用cssnano或者esbuild就不会有这个问题,因为尽管两个包都存在问题,但只有混用才会触发
- 方案3:子包采用 lightcssing进行压缩
-
后续: 向esbuild提mr,github.com/evanw/esbui…。 添加esbuild css解析器 关于ie代码的兼容识别。这个仓库采用go编写,因此需要重复 go build 才能进行发包,因此不能够作为hack patch添加进仓库中 ,然后evanw似乎认为是cssnano的问题更大一点,一个issue直接提到cssnano上去了(github.com/cssnano/css…)。嗨嗨嗨,虽然目前前端已经不再需要兼容ie,但是需要兼容对 兼容ie代码 的兼容。。。。心路历程是有点复杂的