2023年6月21日发(作者:)

关于Vite项⽬打包后浏览器兼容性问题的解决⽅案⼀、问题描述vite+vue3项⽬开发完以后,你会发现打包后的项⽬运⾏在新版浏览器可以正常显⽰,但运⾏在⼀些版本⽐较⽼的浏览器如 Chrome <23、Firefox < 21和IE等浏览器上时显⽰⼀⽚空⽩,并且没有任何的错误提⽰。⼆、问题分析此时你的⼤脑可能跟页⾯⼀样也是⼀⽚空⽩,但是不要慌,我们先分析⼀下产⽣这个问题的可能的原因:那些版本较低的浏览器不⽀持ES6的语法和新API,⽽Babel默认只转换新的JavaScript句法,不转换新的API,⽐如Proxy、Symbol、Promise等全局对象,以及⼀些定义在全局对象上的⽅法都不会转码。三、解决⽅案Plan A:在中配置浏览器的兼容性。我们项⽬是⽤vite搭建的,因此我⾸先想到了使⽤vite⾃带的API去配置浏览器兼容性。配置和get build: { target: ['chrome52'], cssTarget: ["chrome52"], }打包并运⾏到浏览器后发现还是⼀⽚空⽩,查看打包⽣成的⽂件,发现⾥⾯依然有const、Promise等新语法和API,并没有为我们转换。Plan A , B:先配置TypeScript转换语法,然后再让vite兼容⽬标。在⽂件内配置target为”es5”,然后开始打包。打包时报错:error: Transforming const to the configured target environment (“es5”) is not supported yet错误信息⼤抵在告诉我们:代码中有const等⽬标环境不⽀持的语法,并且它⽬前还不⽀持将const转换为⽬标环境"es5"。嗯这就有点意思了。Plan B, C:引⼊babel-polyfill环境垫⽚上⾯转换语法的⽅案失败后,我尝试给浏览器环境请⼀个外援:babel-polyfill,让它来做那些低版本浏览器环境做不到的事情。什么是polyfill?官⽅的解释是:“⽤于实现浏览器不⽀持原⽣功能的代码”,我们可以简单理解为polyfill可以在当前运⾏环境中模拟出那些当前环境不⽀持的API,它为我们的当前环境提供了⼀个垫⽚,我们可以在这个垫⽚上使⽤新API。·⾸先我们先安装babel-polyfill:npm install --save babel-polyfill·然后在⾥引⼊它:import ‘babel-polyfill’然后我们重新打包、启动、运⾏到浏览器,有些伙伴到这⼀步可能就成功了,但我的仍然是⼀⽚空⽩!慌不慌?你说慌不慌,慌!我也觉得慌,为什么?⽹上那么多⼈⽤这个⽅法成功了,但我们失败了,这能不慌? Plan C,No!Plan D:使⽤@vitejs/plugin-legacy插件以上三个⽅案失败后,我⼜重新回归到vite这⼀块,在vite官⽅⽂档中我找到了vite⾃带插件库,并且在插件库中找到了⼀个关于浏览器兼容⽀持的插件:@vitejs/plugin-legacy·⾸先安装插件:npm i @vitejs/plugin-legacy -D·然后在中配置import legacyPlugin from '@vitejs/plugin-legacy'export default defineConfig( { plugins: [ legacyPlugin({ targets:['chrome 52'], //

需要兼容的⽬标列表,可以设置多个 additionalLegacyPolyfills:['regenerator-runtime/runtime'] //

⾯向IE11时需要此插件 }) ]})·打包、运⾏到浏览器。新版本浏览器运⾏正常!旧版本浏览器运⾏正常!Plan D,yes!以下是@vitejs/plugin-legacy插件的简单介绍:插件默认⾏为:1.使⽤@babel/preset-env转换,为包中的每个块⽣成相应的遗留块。2.⽣成⼀个包含 SystemJS 运⾏时的 polyfill 块。3.使⽤打包后的变化:1. 启⽤插件后打包完成的⽬录多出了⼀些带有legacy字样的⽂件,每个js脚本⽂件都有⼀个与其对应的遗留版本。2. html⽂件中新增了⼀些脚本,这些脚本根据浏览器的⽀持程度来动态的引⼊正常版本⽂件还是带有legacy字样的遗留版本⽂件。3. 此时当项⽬运⾏在⼀些版本较低的浏览器时,插件添加的脚本会⾃动加载legacy版本的⽂件。四、过程中遇到的其他问题在Plan D成功在低版本浏览器运⾏以后,发现有⼀些CSS样式显⽰不正常,随后确认是重写Vant的CSS变量没有⽣效。刚开始认为是CSS在打包时没有做好兼容处理,然后就折腾了⼀番CSS的兼容⽀持。css解释器、postcss插件和vite配置css⽬标环境都没⽤。后⾯就没有什么思路了,后来想起来在配置中有⼀个关于样式按需加载的插件:此时就想是不是这个插件影响到了我的CSS的正常效果,当我把它移除并重新打包运⾏后,样式就回归正常了,看来确实是被它影响的。使⽤这个按需加载的插件后,当页⾯加载时,它会根据它的⼀些规则去判断当前需要加载哪些样式⽂件,哪些不需要加载。在加载这些样式⽂件时,如果样式⽂件⾥有我们⾃定义全局样式重名的,那么根据css规则,我们⾃定义过的全局样式会被覆盖掉。在本次的案例中,我们重写了Vant组件的部分变量,并全局引⼊了。在打开包含这些变量的页⾯时,按需加载插件此时才会加载Vant的样式⽂件,我们在全局重写的变量⼜被重写了,因此重写的全局变量没有⽣效。

2023年6月21日发(作者:)

关于Vite项⽬打包后浏览器兼容性问题的解决⽅案⼀、问题描述vite+vue3项⽬开发完以后,你会发现打包后的项⽬运⾏在新版浏览器可以正常显⽰,但运⾏在⼀些版本⽐较⽼的浏览器如 Chrome <23、Firefox < 21和IE等浏览器上时显⽰⼀⽚空⽩,并且没有任何的错误提⽰。⼆、问题分析此时你的⼤脑可能跟页⾯⼀样也是⼀⽚空⽩,但是不要慌,我们先分析⼀下产⽣这个问题的可能的原因:那些版本较低的浏览器不⽀持ES6的语法和新API,⽽Babel默认只转换新的JavaScript句法,不转换新的API,⽐如Proxy、Symbol、Promise等全局对象,以及⼀些定义在全局对象上的⽅法都不会转码。三、解决⽅案Plan A:在中配置浏览器的兼容性。我们项⽬是⽤vite搭建的,因此我⾸先想到了使⽤vite⾃带的API去配置浏览器兼容性。配置和get build: { target: ['chrome52'], cssTarget: ["chrome52"], }打包并运⾏到浏览器后发现还是⼀⽚空⽩,查看打包⽣成的⽂件,发现⾥⾯依然有const、Promise等新语法和API,并没有为我们转换。Plan A , B:先配置TypeScript转换语法,然后再让vite兼容⽬标。在⽂件内配置target为”es5”,然后开始打包。打包时报错:error: Transforming const to the configured target environment (“es5”) is not supported yet错误信息⼤抵在告诉我们:代码中有const等⽬标环境不⽀持的语法,并且它⽬前还不⽀持将const转换为⽬标环境"es5"。嗯这就有点意思了。Plan B, C:引⼊babel-polyfill环境垫⽚上⾯转换语法的⽅案失败后,我尝试给浏览器环境请⼀个外援:babel-polyfill,让它来做那些低版本浏览器环境做不到的事情。什么是polyfill?官⽅的解释是:“⽤于实现浏览器不⽀持原⽣功能的代码”,我们可以简单理解为polyfill可以在当前运⾏环境中模拟出那些当前环境不⽀持的API,它为我们的当前环境提供了⼀个垫⽚,我们可以在这个垫⽚上使⽤新API。·⾸先我们先安装babel-polyfill:npm install --save babel-polyfill·然后在⾥引⼊它:import ‘babel-polyfill’然后我们重新打包、启动、运⾏到浏览器,有些伙伴到这⼀步可能就成功了,但我的仍然是⼀⽚空⽩!慌不慌?你说慌不慌,慌!我也觉得慌,为什么?⽹上那么多⼈⽤这个⽅法成功了,但我们失败了,这能不慌? Plan C,No!Plan D:使⽤@vitejs/plugin-legacy插件以上三个⽅案失败后,我⼜重新回归到vite这⼀块,在vite官⽅⽂档中我找到了vite⾃带插件库,并且在插件库中找到了⼀个关于浏览器兼容⽀持的插件:@vitejs/plugin-legacy·⾸先安装插件:npm i @vitejs/plugin-legacy -D·然后在中配置import legacyPlugin from '@vitejs/plugin-legacy'export default defineConfig( { plugins: [ legacyPlugin({ targets:['chrome 52'], //

需要兼容的⽬标列表,可以设置多个 additionalLegacyPolyfills:['regenerator-runtime/runtime'] //

⾯向IE11时需要此插件 }) ]})·打包、运⾏到浏览器。新版本浏览器运⾏正常!旧版本浏览器运⾏正常!Plan D,yes!以下是@vitejs/plugin-legacy插件的简单介绍:插件默认⾏为:1.使⽤@babel/preset-env转换,为包中的每个块⽣成相应的遗留块。2.⽣成⼀个包含 SystemJS 运⾏时的 polyfill 块。3.使⽤打包后的变化:1. 启⽤插件后打包完成的⽬录多出了⼀些带有legacy字样的⽂件,每个js脚本⽂件都有⼀个与其对应的遗留版本。2. html⽂件中新增了⼀些脚本,这些脚本根据浏览器的⽀持程度来动态的引⼊正常版本⽂件还是带有legacy字样的遗留版本⽂件。3. 此时当项⽬运⾏在⼀些版本较低的浏览器时,插件添加的脚本会⾃动加载legacy版本的⽂件。四、过程中遇到的其他问题在Plan D成功在低版本浏览器运⾏以后,发现有⼀些CSS样式显⽰不正常,随后确认是重写Vant的CSS变量没有⽣效。刚开始认为是CSS在打包时没有做好兼容处理,然后就折腾了⼀番CSS的兼容⽀持。css解释器、postcss插件和vite配置css⽬标环境都没⽤。后⾯就没有什么思路了,后来想起来在配置中有⼀个关于样式按需加载的插件:此时就想是不是这个插件影响到了我的CSS的正常效果,当我把它移除并重新打包运⾏后,样式就回归正常了,看来确实是被它影响的。使⽤这个按需加载的插件后,当页⾯加载时,它会根据它的⼀些规则去判断当前需要加载哪些样式⽂件,哪些不需要加载。在加载这些样式⽂件时,如果样式⽂件⾥有我们⾃定义全局样式重名的,那么根据css规则,我们⾃定义过的全局样式会被覆盖掉。在本次的案例中,我们重写了Vant组件的部分变量,并全局引⼊了。在打开包含这些变量的页⾯时,按需加载插件此时才会加载Vant的样式⽂件,我们在全局重写的变量⼜被重写了,因此重写的全局变量没有⽣效。