Vue項目兼容IE11

image.png

Vue項目兼容IE11

Vue 不支持 IE8 及以下版本,因為 Vue 使用了 IE8 無法模擬的 ECMAScript 5 特性。但對于 IE9+,Vue 底層是支持。

由于開發(fā)過程中,我們經(jīng)常會使用一些第三方插件或組件,對于這些組件,有時我們需要做一些處理。下述主要闡述如何使用 vue-cli3 腳手架搭建的工程支持 IE11。

現(xiàn)象

IE11 打開 Vue 工程(Vue CLI)構(gòu)建而來出現(xiàn)空白頁,控制臺告警、報錯。

如:

  • DOM7011: 此頁上的代碼禁用了反向和正向緩存
  • HTML1300:進行了導(dǎo)航
  • app.js 各種語法錯誤
image

browserslist

項目中 package.json 文件里的 browserslist 字段 (或一個單獨的 .browserslistrc 文件),指定了項目的目標(biāo)瀏覽器的范圍。這個值會被 @babel/preset-envAutoprefixer 用來確定需要轉(zhuǎn)譯的 JavaScript 特性和需要添加的 CSS 瀏覽器前綴。

  • @babel/preset-env:將你使用最新 JavaScript 語法,靈活的轉(zhuǎn)化為目標(biāo)瀏覽器所支持的 polyfill。
  • Autoprefixer:PostCSS 插件,為瀏覽器增加前綴。

.browserslistrc

> 1%
last 2 versions
not ie < 11

Polyfill

默認的 Vue CLI 項目會使用 @vue/babel-preset-app,它通過 @babel/preset-envbrowserslist 配置來決定項目需要的 polyfill。

默認情況下,它會把 [useBuiltIns: 'usage'](https://link.zhihu.com/?target=https%3A//new.babeljs.io/docs/en/next/babel-preset-env.html%23usebuiltins-usage) 傳遞給 @babel/preset-env,這樣它會根據(jù)源代碼中出現(xiàn)的語言特性自動檢測需要的 polyfill。這確保了最終包里 polyfill 數(shù)量的最小化。然而,這也意味著如果其中一個依賴需要特殊的 polyfill,默認情況下 Babel 無法將其檢測出來。

Vue CLI 文檔 中,提供了三種方式:

  • 如果該依賴基于一個目標(biāo)環(huán)境不支持的 ES 版本撰寫: 將其添加到 vue.config.js 中的 [transpileDependencies](https://link.zhihu.com/?target=https%3A//cli.vuejs.org/zh/config/%23transpiledependencies) 選項。這會為該依賴同時開啟語法轉(zhuǎn)換和根據(jù)使用情況檢測 polyfill。
  • 如果該依賴交付了 ES5 代碼并顯式地列出了需要的 polyfill: 你可以使用 @vue/babel-preset-apppolyfills 選項預(yù)包含所需要的 polyfill。注意 es6.promise 將被默認包含,因為現(xiàn)在的庫依賴 Promise 是非常普遍的。
// babel.config.js
module.exports = {
  presets: [
    ['@vue/app', {
      polyfills: [
        'es6.promise',
        'es6.symbol'
      ]
    }]
  ]
}

提示:我們推薦以這種方式添加 polyfill 而不是在源代碼中直接導(dǎo)入它們,因為如果這里列出的 polyfill 在 browserslist 的目標(biāo)中不需要,則它會被自動排除

  • 如果該依賴交付 ES5 代碼,但使用了 ES6+ 特性且沒有顯式地列出需要的 polyfill (例如 Vuetify):請使用 useBuiltIns: 'entry' 然后在入口文件添加 import '@babel/polyfill'。這會根據(jù) browserslist 目標(biāo)導(dǎo)入所有 polyfill,這樣你就不用再擔(dān)心依賴的 polyfill 問題了,但是因為包含了一些沒有用到的 polyfill 所以最終的包大小可能會增加。

我們采用了最簡單最直接(但是性能不是最好)的第 3 種方式!

第一步: 在 babel 的相關(guān)配置文件(babel.config.js、.babelrc 或 package.json 的 babel 字段任一)中,增加 "useBuiltIns": "entry" 信息。babel 7 版本以后,會有差異 -- Here

babel.config.js

{
  "presets": [
    [
      "@babel/preset-env",
      {
        "useBuiltIns": "entry"
      }
    ]
  ]
}

  • If useBuiltIns: 'usage' is specified in .babelrc then do not include @babel/polyfill in either webpack.config.js entry array nor source. Note, @babel/polyfill still needs to be installed.

  • If useBuiltIns: 'entry' is specified in .babelrc then include @babel/polyfill at the top of the entry point to your application via require or import as discussed above.

  • If useBuiltIns key is not specified or it is explicitly set with useBuiltIns: false in your .babelrc, add @babel/polyfill directly to the entry array in your webpack.config.js.

{
  "presets": [
    [
      "@babel/preset-env",
      {
        "useBuiltIns": "entry"
      }
    ]
  ]
}

!!! 網(wǎng)上信息比較混亂,經(jīng)常出現(xiàn)幾種方式混用,并不合理!

第二步: 安裝 '@babel/polyfill' ,并在入口文件添加 import '@babel/polyfill'

$ npm install --save @babel/polyfill

main.js

import '@babel/polyfill'

注意,Babel 7.4.0 以后,該包已被棄用(deprecated)。官方推薦使用 core-js/stableregenerator-runtime/runtime 替代。 -- @babel/polyfill


至此,我們已按照官方要求做了配置,重新啟動項目,發(fā)現(xiàn)依然不行?。?/strong>

transpileDependencies

默認情況下 babel-loader 會忽略所有 node_modules 中的文件。如果你想要通過 Babel 顯式轉(zhuǎn)譯一個依賴,可以在 transpileDependencies 選項中列出來。

下一步:使用 babel 對 elementUI、vuex(需要 Promise polyfill -- Here) 進行轉(zhuǎn)換。

按照 Vue CLI 提供的 3 種方案的第 1種:

如果該依賴基于一個目標(biāo)環(huán)境不支持的 ES 版本撰寫: 將其添加到 vue.config.js 中的 [transpileDependencies](https://link.zhihu.com/?target=https%3A//cli.vuejs.org/zh/config/%23transpiledependencies) 選項。這會為該依賴同時開啟語法轉(zhuǎn)換和根據(jù)使用情況檢測 polyfill。

vue.config.js

transpileDependencies: [/node_modules[/\\\\](element-ui|vuex|)[/\\\\]/],

根據(jù)你的項目實際情況,此處 element-ui 可能不需要

proxy

針對 Proxy 對象進行 polyfill。

下一步:index.html 文件中引入 es6-proxy-polyfill.js

<script src = "https://cdn.jsdelivr.net/npm/proxy-polyfill@0.3.0/proxy.min.js"></script>

根據(jù)項目實際情況,看是否有必要引入。如果引入,建議下載到本地,再引入。


至此,項目終于不是空白頁了?。?/strong>

但是,出現(xiàn)了大量排版錯誤!

css polyfill

由于我們項目中,大量使用了 CSS var() ,IE11 不兼容導(dǎo)致,思路相同,尋找相應(yīng)的 polyfill 即可。這里我們使用了 [css-vars-ponyfill](https://link.zhihu.com/?target=https%3A//github.com/jhildenbiddle/css-vars-ponyfill)

$ npm install --save css-vars-ponyfill

main.js

import cssVars from 'css-vars-ponyfill'
cssVars({})

大功告成!

總結(jié)

總之,所有的處理都是圍繞轉(zhuǎn)換成 IE11 可以兼容的方式去處理。對于 JavaScript 語法,即是對 babel 的控制;對于 CSS 語法,需要特定分析。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容