Skip to content

Latest commit

 

History

History
98 lines (83 loc) · 4.91 KB

vue-cli-1.md

File metadata and controls

98 lines (83 loc) · 4.91 KB

在vue-cli中了解Polyfill

学习vue-cli文档的时候 初学的小伙伴对于 浏览器兼容性 的Polyfill应该会有疑惑吧~~(是不是只有我呢?)~~

需要了解Polyfill 就得先来了解Babel

Babel又是什么

我们写项目搬轮子 在package.json中看到很多开发依赖的包Babel-xxx Babel有什么用? 直白的说 我们写的ES/2015/2016/2017/20xx等JavaScript的代码语法 转成让运行环境(浏览器、node环境)能认识并执行 (只是语法的转换 而不改变原来的API) 现在大部分浏览器都覆盖了ES5的规范 所以说把这些代码语法转成ES5是比较稳妥的

我看不懂法语 用转译工具 给我换成中文 而这个转译工具 也可以理解成是Babel

Babel的原理

babel需要经过三个阶段: 解析、转换、生成,最终要呈现所转换后的代码 都是要通过里面配置好的插件 你可以试试不写任何插件转换,最终的代码是一模一样的 这里安装了转译插件,在转换这一步把源码转换 在输出,比如我们常用的箭头函数 就是转成function

preset

自己手动安装转译插件不现实 因为es5的规范太多了 所以babel提供了一些插件的集合预设preset 让开发者更好的使用 (这里顺口一提 vue-cli也有自己的preset 理解的根本都是一样的) 集合的预设很多 我就只说常用的env
为什么是env 因为是根据我们设置目标的环境在做出对应的转换,只转换必要的 直接上一段代码理解 (以下的Babel语法按着7.x+版本)

presets: [
    [
        '@babel/preset-env',
        {
            targets: {
                browsers: ["last 2 versions", "safari >= 7"]
            }
        }                              
    ],
    '@babel/react'
]

如果某个预设有参数的 那么就是要写错一个数组形式 没有参数就直接字符串传入就可以 这里用到env预设 7.x+写法需要 完整的@babel/preset-env 带的参数traget 浏览器兼容最新2个版本 和 safari浏览器版本要大于或者等于7的 那么env预设就会根据这个目标去做出对应的转换

Polyfill

上文说得那么多 是因为要清楚Polyfill的作用是什么 babel只是转换语法 不会转换api 也就是说 有些方法不会被转译 也就是说 es5+的一些方法API 不会直接被转译 也没办法在现有的环境上运行 比如Array.from等 所以就要用到@babel/polyfill
官方对于@babel/polyfill 的使用描述是

Babel includes a polyfill that includes a custom regenerator runtime and core-js. This will emulate a full ES2015+ environment (no < Stage 4 proposals) and is intended to be used in an application rather than a library/tool. (this polyfill is automatically loaded when using babel-node)

这里看到**@babel/polyfill** 用core-js/stableregenerator-runtime/runtime来直接实现

 import 'core-js/stable'
 import 'regenerator-runtime/runtime' 
 
 // 等同于
 import "@babel/polyfill";

但是问题来了: 直接使用polyfill会污染全局 打包的体积会很大很多很多 我只想按需使用 减少打包的体积 怎么办呢?

看看官方给的解释

When used alongside @babel/preset-env,

  • 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.

可以通过设置useBuiltIns参数 告诉babel怎么样去配置@babel/polyfill 看看下面代码

presets: [
    [
        '@babel/preset-env',
        {
            targets: {
                browsers: ["last 2 versions", "safari >= 7"]
            },
            useBuiltIns: 'entry',
            corejs: 3
        }                              
    ],
    '@babel/react'
]
  • corejs 是指定核心版本
  • useBuiltIns 按需注入 有三个参数可选
    • entry: 根据配置的浏览器兼容 去替换成不兼容的polyfill 这里要在入口文件手动添加@babel/polyfill 注意 如果是corejs:3 那么要用'core-js/stable''regenerator-runtime/runtime'来替换引用
    • usage: 不需要手动添加@babel/polyfill,会根据配置的浏览器兼容,全自动检测
    • false: 不对polyfill做操作

好了 现在回到vue-cli文档 对于useBuiltIns: 'usage' 就能更好的理解了

默认情况下,它会把 useBuiltIns: 'usage' 传递给 @babel/preset-env,这样它会根据源代码中出现的语言特性自动检测需要的 polyfill。这确保了最终包里 polyfill 数量的最小化

(完)