最近开发的 APP 内嵌页面在一个 17 年的机型上出现了问题,首先介绍下背景,我们这个项目使用 Create React App 搭建,使用 React 18,React-router V6, TailwindCSS 进行响应式布局。
首先的兼容问题是在该机型上,React-router 的页面跳转无效。报错是
AbortController is undefined
,应该是 React-router V6 在路由跳转时使用了 AbortController
,而这个机型的 BOM 中没有提供这个停止异步操作的 API,我们给他加上 polyfill 就可以解决这个问题,但是应该存在一个 React-router 的配置项目来停止这个操作,暂时还没找到。然后是 TailwindCSS 编译后的 CSS 样式大量失效,一开始以为是 CSS 变量在目标环境不兼容,但是在调试后发现其实可以使用。在经历了多次折磨的控制变量法后,发现是
#0000
—— TailwindCSS 中提供的默认 CSS 变量值在这个环境中不能使用,于是对这个 CSS 变量进行了覆盖。另外在一开始想要解决 CSS 变量问题时,尝试修改 postCSS 的配置,发现在 Create React App 的项目内,我们的
postcss.config.js
并不会被 webpack
读取,CRA 内部对 postcss
在使用和不使用 TailwindCSS 的情况下(项目根目录是否存在 tailwind.config.js
)做了两套配置。// ... plugins: !useTailwind ? [ 'postcss-flexbugs-fixes', [ 'postcss-preset-env', { autoprefixer: { flexbox: 'no-2009', }, stage: 3, }, ], // Adds PostCSS Normalize as the reset css with default options, // so that it honors browserslist config in package.json // which in turn let's users customize the target behavior as per their needs. 'postcss-normalize', ] : [ 'tailwindcss', 'postcss-flexbugs-fixes', [ 'postcss-preset-env', { autoprefixer: { flexbox: 'no-2009', }, stage: 3, }, ], ], // ...
所以我们的
postcss.config.js
在 CRA 项目内就像是一个花瓶,存在但没有意义。如果想要覆盖这个默认的 postcss
配置,我们需要使用 react-app-rewired
来覆盖 CRA 的 webpack 配置,我们还可以通过 所以我们的
postcss.config.js
在 CRA 项目内就像是一个花瓶,存在但没有意义。如果想要覆盖这个默认的 postcss
配置,我们需要使用 react-app-rewired
来覆盖 CRA 的 webpack
配置,配合 react-app-rewire-postcss
使用来完成对 postcss
配置的覆盖。但在实际操作中,
react-app-rewire-postcss
这个项目会使用内置的 postcss-loader
,版本非常久远,使用现在的 postcss
插件时基本都会报错。不过它内部的实现并不复杂,仅仅是一个工厂函数,我们将他的源码复制出来使用也可以实现覆盖的操作。