umi icon indicating copy to clipboard operation
umi copied to clipboard

[discussion] solution for legacy browsers compatibility

Open PeachScript opened this issue 3 years ago • 7 comments

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 走编译。

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

PeachScript avatar Jul 21 '22 04:07 PeachScript

esbuild 的 ”优化“ 目前遇到的例子

  1. 模板字符串换行的字节数比 \n 少,所以会优化成 es6 模板字符串:

    `
    `
    
  2. chrome 60 以上的 targets 会导致 rgba() 变成 #rrggbbaa ,省字节

  3. parcel-css 一致,在不指定低 targets 时,四边 0 将转换为 inset :

    .a {
      left: 0; right: 0; top: 0; bottom: 0;
    }
    .a-transformed {
      inset: 0;
    }
    

fz6m avatar Jul 21 '22 05:07 fz6m

仅供参考:旧 legacy bundle 一键回归 es5 打包的思路整理

  1. babel 全量处理 node_modules

  2. srcTranspiler 只能使用 babel

  3. jsMinifier 只能使用 terser

  4. cssMinifier 只能使用 cssnano

  5. svgr 处理时,需要改为 babel 解析 svg (现在是 esbuild,不支持 es5 )

FYI:

  • https://github.com/umijs/umi-next/pull/793

fz6m avatar Aug 18 '22 04:08 fz6m

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

xiaorong61 avatar Aug 18 '22 06:08 xiaorong61

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

jounzhang avatar Aug 19 '22 08:08 jounzhang

IE 兼容性问题 IE 被淘汰,现代浏览器主流背景下,umi4 默认不兼容 IE ,在 https://github.com/umijs/umi/issues/8658 可以参与相关讨论。

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

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

https://github.com/umijs/umi/issues/8930

drizzlesconsin avatar Aug 19 '22 10:08 drizzlesconsin

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

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

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

#8930

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

jounzhang avatar Aug 20 '22 01:08 jounzhang

默认的兼容说明

默认不支持 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'
  ],
  legacy: {}
}

参考的思路有:

方案 说明
CDN 引入 以 cdn 形式引入 script 形式且前置的 、目标浏览器环境缺少的 polyfill js 文件,如 es6-shim
人工 core-js 利用 core-js 系工具,如通过 core-js-builder 构建自己需要的 polyfill 产物,再以 前置 script 脚本 形式引入项目。
动态 polyfill 服务 使用根据当前浏览器请求 UA 动态下发所需 polyfill 的服务,比如 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 并不能完整支持开发时的热更新,且缓存可能需要人为在控制台进行清除后才能看到最新的页面,请做好准备。

fz6m avatar Aug 30 '22 17:08 fz6m

低浏览器相关的兼容,可以使用配置 legacy 有其他异常欢迎新开 issues 讨论

xiaohuoni avatar Oct 26 '22 09:10 xiaohuoni

WechatIMG8 image 求帮助,这个怎么处理😂

caoxuccc avatar May 12 '23 02:05 caoxuccc

这个是你的逻辑问题,自己修正下,legacy 只是帮助提供 es6 到 es5 的转换而已,代码逻辑错了需要自己排查。

fz6m avatar May 12 '23 06:05 fz6m

@fz6m 谢谢提醒,你说的是对的,一个三方库的问题

caoxuccc avatar May 15 '23 01:05 caoxuccc

如开启了 legacy 选项,则仅会在构建时进行低版本的转换,要检验部署预览内效果而不是开发时。

如还有问题,需要给一个最小复现。

fz6m avatar Nov 22 '23 12:11 fz6m