umi [discussion] solution for legacy browsers compatibility

5jdjgkvh  于 2022-10-22  发布在  其他
关注(0)|答案(6)|浏览(361)

Background

目前 Umi 4 主要碰到两个浏览器兼容的问题:

  1. esbuild 作为压缩器会对 ES5 代码做反向优化变成 ES6,导致配置 targets 以后不改压缩器也不能工作,用户排查及使用成本较高, from @xiaohuoni
  2. 社区越来越多包只发布 ES6 产物,但 Umi 4 默认不用 babel 编译 node_modules ,导致产物里出现高级语法,添加 extraBabelIncludes 一旦数量变大维护成本也会变高,from @fz6m

Proposal

根据 targets 自动切换框架配置?例如 targets 的最低浏览器如果不兼容 ES6,那么默认就切压缩器 + node_modules 走编译。

如果有其他建议或方案,请直接在下方讨论。

ymdaylpp

ymdaylpp1#

esbuild 的 ”优化“ 目前遇到的例子
  1. 模板字符串换行的字节数比 \n 少,所以会优化成 es6 模板字符串:
`
`
  1. chrome 60 以上的 targets 会导致 rgba() 变成 #rrggbbaa ,省字节
  2. parcel-css 一致,在不指定低 targets 时,四边 0 将转换为 inset :
.a {
  left: 0; right: 0; top: 0; bottom: 0;
}
.a-transformed {
  inset: 0;
}
beq87vna

beq87vna2#

还有人需要兼容不支持 es6 的浏览器,太惨啦。😂

qojgxg4l

qojgxg4l3#

作为一个新手,我就想知道,umi4创建的脚手架,能不能默认配置成不支持ie,现在一build就报错啊,大神些!
没法build,也不知道改哪里!

ztmd8pv5

ztmd8pv54#

IE 兼容性问题
IE 被淘汰,现代浏览器主流背景下,umi4 默认不兼容 IE ,在 #8658 可以参与相关讨论。

若你需要兼容 es5 ,目前的缓解方法是: 调整 js 与 css 的压缩器

// .umirc.ts
export default {
  jsMinifier: 'terser',
  cssMinifier: 'cssnano'
}

#8930

icnyk63a

icnyk63a5#

IE 兼容性问题 IE 被淘汰,现代浏览器主流背景下,umi4 默认不兼容 IE ,在 #8658 可以参与相关讨论。

若你需要兼容 es5 ,目前的缓解方法是: 调整 js 与 css 的压缩器

// .umirc.ts
export default {
  jsMinifier: 'terser',
  cssMinifier: 'cssnano'
}

#8930

我现在的问题是使用antdpro初始化脚手架后,build报错不兼容ie,不知道怎么处理。我不需要兼容ie!

nfzehxib

nfzehxib6#

默认的兼容说明

默认不支持 IE , targetschrome: 80 ,如需调整,请指定明确的 targets :

// .umirc.ts

export default {
  targets: { chrome: 67 }
}

兼容旧时代浏览器 ( IE 11 ) 的说明

一、一种自带的兼容解法

框架自带提供一个 legacy 配置用于构建降级(使用限制等详见 config > legacy ):

// .umirc.ts

export default {
  legacy: {}
}

默认仅在构建时生效,将尝试构建能使 IE 兼容的产物。

二、legacy mode 的更多自定义

legacy 开启时,默认会转译全部 node_modules ,这在大型项目中,会极大的增加构建时间。

若你了解当前项目使用的第三方依赖情况(知道哪些不再提供 es5 产物了),可以关闭 node_modules 的转换,改为使用 extraBabelIncludes 定点配置那些需要额外纳入转换范围的包。

一个例子:

// .umirc.ts

export default {
  legacy: {
    nodeModulesTransform: false
  },
  extraBabelIncludes: [
    'some-es6-pkg',
    /@scope\//
  ]
}

三、提高兼容的鲁棒性

legacy 选项并不能 100% 保证产物没有边界情况的运行在被淘汰的浏览器内,你可能还需要添加前置的全量 polyfill 来增强项目的 鲁棒性

// .umirc.ts

export default {
  headScripts: [
    'http://polyfill.alicdn.com/v3/polyfill.min.js' // or https://polyfill.io/v3/polyfill.min.js
  ],
  legacy: {}
}

参考的思路有:

方案说明
CDN 引入以 cdn 形式引入script 形式且前置的、目标浏览器环境缺少的 polyfill js 文件,如 es6-shim
人工 core-js利用 core-js 系工具,如通过 core-js-builder 构建自己需要的 polyfill 产物,再以前置 script 脚本形式引入项目。
动态 polyfill 服务使用根据当前浏览器请求 UA 动态下发所需 polyfill 的服务,比如 polyfill.io ,考虑到速度,可使用国内的 alicdn polyfill.io 服务。另外,你还可以使用 polyfill-service 自建相同的动态 polyfill 下发服务。

注:

  1. 当你处于内外网隔离开发环境时,可以考虑将全部 polyfill 的 js 内容跳板传入内网,在内网的 CDN 使用,或放入 public 目录等方式使用。
  2. 使用 script 前置引入的意义在于,在项目 js 资源运行前就准备好一个完整的、被 polyfill 过 api 的环境。

四、在开发环境验证

推荐的做法是:构建后在本地通过 umi previewserve 、nginx 等启动服务,来验证产物的 IE 11 运行可行性。

当你需要在开发环境验证时:

  1. legacy.buildOnly 置为 false
  2. 由于 react fresh 、hmr 等开发注入的 es6 代码始终在第一位运行,你需要以 script 形式添加一个前置的 polyfill ,提前准备好环境。
// .umirc.ts

const isProd = process.env.NODE_ENV === 'production'
export default {
  legacy: {
    buildOnly: false
  },
  headScripts: isProd 
    ? [] 
    : ['http://polyfill.alicdn.com/v3/polyfill.min.js']
}

注:IE 11 并不能完整支持开发时的热更新,且缓存可能需要人为在控制台进行清除后才能看到最新的页面,请做好准备。

相关问题