iPhone 刘海屏适配打包问题

1,292 阅读2分钟

针对iphone X等刘海屏,需要写多个padding-top属性,大致如下:

.body {
    padding-top: 44px;
    padding-top: calc(~'44px + env(safe-area-inset-top)');
    padding-top: calc(~'44px + constant(safe-area-inset-top)');

    padding-bottom: 0;
    padding-bottom: env(safe-area-inset-bottom);
    padding-bottom: constant(safe-area-inset-bottom);
}

本地开发没有啥问题,然而项目经过build之后,发现样式变成了:

.body {
    padding-top: calc(~'44px + constant(safe-area-inset-top)');
    padding-bottom: constant(safe-area-inset-bottom);
}

同名属性莫名被吃了??? 于是开始坎坷的解决之路。

  1. 先搜索相关问题,问题其实都不知道出现在哪,于是搜索也没有结论。绝望
  2. 然后再问别人看看是否有类似问题。没有人遇到过。绝望 + 1
  3. 开始分析打包配置,然后修改打包入口文件,指向一个最简单的Demo,就只包含上述这些样式。
  4. 分步注释打包对CSS的配置,排除变量。
  5. 最终发现是optimize-css-assets-webpack-plugin中引入一个cssnano这样一个包,里面又包含了mergeLonghand这种一个功能模块,会将 padding/margin等属性的子属性(padding-top、padding-bottom)尝试合并为一个。然而不知道为何没有合并,反而将同名的padding-top、padding-bottom属性吃了几个。

知道原因后,解决方案也很简单,修改webpack的配置:

...
optimization: {
    moduleIds: 'hashed',
    minimizer:[
      new OptimizeCSSPlugin({
        cssProcessorPluginOptions: {
          preset: ['default', { mergeLonghand: false }] // 不使用 mergeLonghand 这个功能
        }
      }),
      new UglifyJsPlugin({
        cache: true,
        parallel: true
      })
    ]
}

再次打包就不会出现 padding-top 属性被吃的情况了。

解决过程中陷入了一个僵局,因为使用mini-css-extract-plugin这个插件,如果不使用,也就是css in js这种方式时,就不会出现被吃情况,故误以为是这个插件的问题,看了好半天源码,发现没那个地方存在这种可能性。。故回过头继续看配置文件。