谈谈 SCRIPT1002: 语法错误、Babel 和 polyfill | 青训营笔记

611 阅读2分钟

这是我参与「第四届青训营 」笔记创作活动的第 4 天

如果世界上只有一种型号的电脑,一种浏览器就好了。就不会有很多奇奇怪怪的兼容问题了 orz。刚好这里记录一下本周遇到的一个 IE 兼容问题。首先,要从本地用 parcel 本地启动之后,IE 打开报错 SCRIPT1002: 语法错误 讲起。

为什么会出现 SCRIPT1002: 语法错误

因为 IE 无法解析 ES6 语法(即使是 IE11),有些打包工具可能有内置 babel,但不是每个项目都要求兼容低版本浏览器,所以可能没有 polyfill,因此还需要一个 babel-polyfill,来支持一些必要的 api。

关于 Babel 和 polyfill,Babel 官网是这样描述的:Babel 是一款 JavaScript 编译器,主要用于在旧的浏览器或环境中将 ECMAScript 2015+ 代码转换为向后兼容版本的 JavaScript 代码。由于 Babel 只进行语法转换(如箭头函数),你可以使用 babel-polyfill 来支持新的全局变量,如 Promise 或新的原生方法。

举个栗子,我在项目中写了个 async await 函数,这时候需要 babel 把它转换成 Promise,但老版本浏览器不支持 Promise api,所以需要 polyfill 来支持 Promise 方法。这样说大概可以理解 babel 和 polyfill 的职责了吧。

babel 和 polyfill 是相互依赖的吗?

答案是,不是。babel 是在 build 代码时,将 ES6 语法转换为 ES5 语法,如果使用了 babel-polyfill,还会按需创建一些必要的 api 如 Promise,避免低版本浏览器没有 Promise,而代码里又有 new Promise 导致报错。

babel 是个编译器。执行 npx babel script.ts 可以将其转换为 ES5 语法的 js 文件。parcel 默认使用的就是 babel。

polyfill 是个补丁。也就是说,polyfill 可以为老版本浏览器补上一些缺失的 api(如 Promise),甚至可以将常用的 polyfill 保存为 js 文件放到项目里,每次引入打包也行。

二者是独立的,所以,即使有 babel 编译,在一定条件下也还是需要 polyfill 的。

参考:《用了babel还需要polyfill吗???》 《一文搞清楚前端 polyfill》