因为 Vue3 使用了 ES6 的 Proxy 作为其观察者机制,并且无法通过 polyfill 进行转换,所以工程要兼容低版本浏览器的话,还得继续使用 Vue2,经过一些研究,整理了以下 2 个版本的 Vue2 工程在兼容低版本浏览器时的详情步骤:
温馨提示:现在 Vue2 也可以使用组合式 api 了,具体参考:https://www.npmjs.com/package/@vue/composition-api
根据 Vue Cli
官网上提供的教程,默认创建出来的 Vue2 工程就是 webpack 版。
Vue Cli
安装:https://cli.vuejs.org/zh/guide/installation.htmlVue Cli
基础:https://cli.vuejs.org/zh/guide/creating-a-project.html执行如下命令:
# 例如:vue create webpack-vue2-ts
vue create your-project-name
选择 Manually select features
后回车,进入特性选择环节,根据工程需求,选择即可:
注意:空格选中或取消,回车确认。
之后一路回车即可,等待工程初始化完成(会自动拉取 node_modules
需要点时间)
工程创建完成之后,就可以来着手兼容低浏览器了,先安装如下几个 babel 插件:
npm i @babel/plugin-transform-arrow-functions -D
npm i @babel/plugin-proposal-optional-chaining -D
打开 babel.config.js
,如下配置:
// babel.config.js
module.exports = {
presets: [
"@vue/cli-plugin-babel/preset",
[
"@babel/preset-env",
{
useBuiltIns: "entry",
corejs: 3,
targets: {
ios: "8",
android: "4",
chrome: "58",
},
},
],
],
plugins: [
"@babel/plugin-transform-arrow-functions", // 箭头函数转换
"@babel/plugin-proposal-optional-chaining", // 可选链(?.)转换
],
};
最后,在 main.ts
文件顶部进行如下导入:
// main.ts
import "core-js/stable";
import "regenerator-runtime/runtime";
import Vue from "vue";
import App from "./App.vue";
...
至此,webpack 版 Vue2 工程 使用 npm run build
打包出来的 h5 就可以在低版本浏览器上运行了。
注意:以上配置仅针对
Vue Cli 4
,Vue Cli 4
与Vue Cli 3
的 babel 配置大不相同。
useBuiltIns
说明这里是对上述配置中的 useBuiltIns
的说明,没兴趣可以直接跳过~
值 | 示例 | 说明 |
---|---|---|
false | “useBuiltIns”: false | 不对 polyfill 做操作,如果引入 @babel/polyfill ,则无视配置的浏览器兼容,引入所有的 polyfill 。 |
entry | “useBuiltIns”: “entry”, “corejs”: 2 | 根据配置的游戏器兼容,引入浏览器不兼容的 polyfill 。需要在入口文件手动添加 import '@babel/polyfill' ,会自动根据 browserslist 替换成浏览器不兼容的所有 polyfill 。这里需要指定 core-js 的版本, 如果 “corejs”: 3, 则 import '@babel/polyfill' 需要改成 import 'core-js/stable';import 'regenerator-runtime/runtime'; |
usage | “useBuiltIns”: “usage”, “corejs”: 2 | 会根据配置的浏览器兼容,以及你代码中用到的 API 来进行 polyfill,实现了按需添加。 |
Vite 工程需要使用 Vite 脚手架来创建:
执行如下命令:
npm init vite@latest
选择 Vanilla
,之后再选择 TypeScript
,回车,即刻创建好工程(Vite 不会自动拉取 node_modules
,所以比较快):
使用 Vite
创建的 Vue 工程默认是 Vue3 版本,需要对工程进行改造,转成 Vue2 版本需要安装一个 Vite 插件,执行如下命令:
npm i vite-plugin-vue2 -D
创建 vite.config.ts
文件,如下配置:
// vite.config.ts
import { createVuePlugin } from "vite-plugin-vue2";
export default {
plugins: [createVuePlugin()],
};
安装完插件之后,还需要安装 Vue2 依赖,执行如下命令:
npm i vue@2.7.13
npm i vue-template-compiler
注意:使用
npm i vue
默认会安装 Vue3,需要手动指定版本才能安装 Vue2。
在 src
目录下创建 App.vue
文件:
Hello Vite Vue2 --- GitLqr
重写 src
目录下的 main.ts
文件,内容如下:
// main.ts
import Vue from "vue";
import App from "./App.vue";
new Vue({
render: (h) => h(App),
}).$mount("#app");
因为工程使用了 TypeScript
,此时代码中的 "./App.vue"
还不会被 ts 识别,所以会提示报错,如果放置不理的话还会导致编译失败,此时只需要在 vite-env.d.ts
文件中对 vue
进行类型声明即可解决:
// vite-env.d.ts
///
declare module "*.vue" {
import Vue from "vue";
export default Vue;
}
@vitejs/plugin-legacy
工程改造成 Vue2 之后,就可以着手兼容低版本浏览器了。Vite 官方提供了 @vitejs/plugin-legacy
插件,专门用来处理兼容低版本浏览器问题,执行如下命令:
npm i @vitejs/plugin-legacy -D
打开 vite.config.ts
文件,如下配置:
// vite.config.ts
import { createVuePlugin } from "vite-plugin-vue2";
import legacy from "@vitejs/plugin-legacy";
export default {
plugins: [
createVuePlugin(),
legacy({
targets: ["android 4", "ios 8", "chrome 52", "ie 11"],
additionalLegacyPolyfills: ["regenerator-runtime/runtime"],
renderLegacyChunks: true,
polyfills: [
"es.symbol",
"es.array.filter",
"es.promise",
"es.promise.finally",
"es/map",
"es/set",
"es.array.for-each",
"es.object.define-properties",
"es.object.define-property",
"es.object.get-own-property-descriptor",
"es.object.get-own-property-descriptors",
"es.object.keys",
"es.object.to-string",
"web.dom-collections.for-each",
"esnext.global-this",
"esnext.string.match-all",
],
}),
],
};
以上配置源自:https://blog.csdn.net/Mr_JavaScript/article/details/125388234
Unhandled promise rejection
配置完 @vitejs/plugin-legacy
之后,在个别浏览器上会出现 Unhandled promise rejection
错误,这时需要使用 @babel/polyfill
来解决,执行如下命令安装:
npm i @babel/polyfill
在 main.ts
最顶端添加:
// main.ts
import "@babel/polyfill";
import Vue from "vue";
import App from "./App.vue";
...
至此,Vite 版 Vue2 工程使用 npm run build
打包好的 h5 就可以在低版本浏览器上运行了。
注意:因为
@vitejs/plugin-legacy
只在 build 模式下生效,这也意味着 dev 模式下不经过@vitejs/plugin-legacy
处理,所以 dev 模式下无法在低版本浏览器上运行。
Vue2.6 及之前版本需要通过 composition-api
插件来支持组合式 API,而最近发布的 Vue2.7 则已经内置了组合式 API,所以接下来顺便让上面的 Vite 版 Vue2 工程支持组合式 API 吧:
Vue2.7 不再使用 vue-template-compiler
插件,执行如下命令进行卸载:
npm un vue-template-compiler
注意:你会发现,就会没有
vue-template-compiler
插件,运行项目也是不会报错的~
根据官方说明,Vue2.7 应该使用 @vitejs/plugin-vue2
插件来代替 vite-plugin-vue2
插件,执行如下命令:
npm un vite-plugin-vue2
npm i @vitejs/plugin-vue2 -D
注意:必须使用新的
@vitejs/plugin-vue2
插件,否则将无法正常使用!!!
更换好插件后,打开 vite.config.ts
修改配置:
// vite.config.ts
// import { createVuePlugin } from "vite-plugin-vue2";
import vue from "@vitejs/plugin-vue2";
export default {
plugins: [
// createVuePlugin(),
vue(),
...
],
};
至此,就可以在项目中使用组合式 API 了,例如:
{{ hello }}
上述两个工程示例已提交 GitHub:
可以发现不管 webpack 还是 Vite,在兼容低版本浏览器时,都会配置一个 targets
参数,该参数很关键,配置不当会达不到效果,详细介绍请参考如下文档: