babel7初探 -- rollup + babel7按需加载polyfill

一、前言

babel7自从2018年下旬出来以后,一直没有仔细研究过。对于一些基本的配置过程还不是很了解。今天就来说下babel7中一个比较重要的特性–按需加载polyfill。这次乘着学习fetch,由于fetch在主流浏览器兼容性并不高,所以需要用到fetch-polyfill的机会,学习巩固一下babel7.

polyfill目前没有准确的翻译。直译是填充物的意思,即引入了对应语法的polyfill之后,在浏览器端运行的脚本可以使用浏览器不支持的es新语法和特性。最常见的就是PromiseArray.includesObject.assign,anyscawait等等新语法。在babel6以及之前,只需要在入口引入 polyfill 即可。然而这也带来了问题,一次性加载了整个 polyfill,十分冗余。 而用了 babel7 通过简单的配置就可以达成按需加载的目的,我们也不再需要手动引入 polyfill。

二、关于bable7的各个包大概说明

@babel/core

核心功能,babel从版本7开始用@开头的scope包,老版本是babel-core,其他的包都是一样的规律

@babel/plugin-***

所有的babel插件集合。

@babel/preset-***

  • preset是预先确定的一些plugin的集合,babel官方的preset目前有: @babel/preset-env、@babel/preset-flow、@babel/preset-react、@babel/preset-typescript,当然还有非官方的
  • 没有特殊要求就用babel-preset-env吧,带年份和带stage的都不建议用了
  • 可以自定义preset,不过一般使用应该不太需要

@babel/polyfill

这里就是我们今天要说的内容。其实不是必需的。如果是在写lib,不要使用@babel/polyfill,因为其中的一些实现会污染全局
兼容新特性,不会将代码编译成低版本,如果要使用,要用-S而不是-D。据说是往全局对象和内置对象的prototype上添加方法来实现的
在webpack中使用,可以这样写,每个官方的preset都有自己的选项说明,比如
https://babeljs.io/docs/en/babel-preset-react

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

三、实战

按照上述配置,使用rollup作为测试工具,配置babel7。有关rollup的配置,可以参考我的文章。只不过这一篇文章用的rollup的低版本。这里我要使用rollup的最新版本1.21.4
完整的代码可以直接去这里取。npm run build即可执行

package.json

 "devDependencies": {
    "@babel/core": "^7.6.2",
    "@babel/preset-env": "^7.6.2",
    "rollup": "^1.21.4",
    "rollup-plugin-babel": "^4.3.3",
    "rollup-plugin-commonjs": "^8.0.2",
    "rollup-plugin-json": "^2.3.0",
    "rollup-plugin-node-resolve": "^3.0.0"
  },
  "dependencies": {
    "@babel/polyfill": "^7.6.0",
    "fetch-polyfill": "^0.8.2"
  }

这里仅使用了数个核心包

babel7初探 -- rollup + babel7按需加载polyfill_第1张图片

自己install的话 rollup-plugin-babel这个包install的时候一定要用@latest安装。官网截图

rollup.config.dev.js

import babel from 'rollup-plugin-babel';
import resolve from 'rollup-plugin-node-resolve';
import commonjs from 'rollup-plugin-commonjs';
import json from 'rollup-plugin-json';

export default {

    input: 'src/index.js',
    output:{
        name:"Animals",
        file:"dist/animals.js",
        format: 'umd',
        sourcemap: true,
    },
    plugins: [
        resolve({
            browser: true,
        }),
        json(),
        commonjs(),
        babel({
            exclude: 'node_modules/**',
        }),
    ]
};

.babelrc

{
  "presets": [
    [
      "@babel/env",
      {
        "modules": false,
        "useBuiltIns": "usage"
      }
    ]
  ]
}

没错。就是引用了最简单的配置。直接用@babel/preset-env这个预制的preset,然后配置useBuiltInsusage即可。

  • false
    值为false 的时候,相当于没用,这时就得手动引入所有的 polyfill
  • entry
    使用entry 的时候,也需要手动引入 polyfill,即 import ‘@babel/polyfill’;,同时也引入了所有的 polyfill。这个配置项,总觉得没什么用,如果有老哥知道的话可以在评论区提出一起讨论。
  • usage
    值为 usage 的时候,无需引入 polyfill,babel 会自动按需加载需要的功能

当我们设置usage为false时,编译出来是这样的:

babel7初探 -- rollup + babel7按需加载polyfill_第2张图片
600行代码。对于其中使用的Promise,includes等代码没有进行polyfill。
当按照usage配置时:
babel7初探 -- rollup + babel7按需加载polyfill_第3张图片
2500行代码。没错,这多出来的代码就是为了在ie8 及不支持promise等语法的地方做的polifill。所以实际打包情况需按照实际业务运行环境决定。建议通过配置babellrc中的env.target属性。决定需要兼容哪些浏览器。

四 引入第三方polyfill

在上面的代码操作之后,我在代码中使用了fetch,发现并没有对于的polyfill。因为我安装的fetch-polyfill不在标准的@babel/polyfill中。即在任意入口文件手动引入即可:

import 'fetch-polyfill'

build之后源码中便出现了fetch-polyfill

babel7初探 -- rollup + babel7按需加载polyfill_第4张图片

引用:
babel7中 preset-env 完全使用
babel的一些包的相关总结

你可能感兴趣的:(前端技术,roll-up,babel)