zoukankan      html  css  js  c++  java
  • 前端工程化-webpack篇之babel-polyfill与babel-runtime(三)

    关于 Babel

    如果我们没有配置一些规则,Babel 默认只转换新的 JavaScript 句法(syntax),而不转换新的 API,比如 Iterator、Generator、Set、Maps、Proxy、Reflect、Symbol、Promise 等全局对象,以及一些定义在全局对象上的方法(比如 Object.assign )都不会转码。 所以,当这样的代码出现时:

    const key = 'babel'  
    const obj = {  
        [key]: 'foo',
    }
    

    Babel 默认会编译成下面的代码

    function _defineProperty(obj, key, value) {  
        if (key in obj) {
            Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true });
        } else {
            obj[key] = value;
        }
        return obj;
    }
    
    var key = 'babel';  
    var obj = _defineProperty({}, key, Object.assign({}, { key: 'foo' }));  
    

    我们可以看到代码中多了一个名为_defineProperty的帮助函数,但是这个帮助函数仅仅在当前模块中生效,因此其他模块中如果用到了同样的语法,编译后就会出现大量的重复代码。

    babel-polyfill

    原理是当运行环境中并没有实现的一些方法,babel-polyfill 会给其做兼容。 但是这样做也有一个缺点,就是会污染全局变量,而且项目打包以后体积会增大很多,因为把整个依赖包也搭了进去。所以并不推荐在一些方法类库中去使用。

    用法

    1. `npm install --save babel-polyfill`
    2. 在应用的入口引用,以确保它能够最先加载:
    `import "babel-polyfill";` 或者
    `require("babel-polyfill");`
    

    babel-runtime

    为了不污染全局对象和内置的对象原型,但是又想体验使用新鲜语法的快感。就可以配合使用babel-runtimebabel-plugin-transform-runtime。 比如当前运行环境不支持promise,可以通过引入babel-runtime/core-js/promise来获取promise, 或者通过babel-plugin-transform-runtime自动重写你的promise。也许有人会奇怪,为什么会有两个runtime插件,其实是有历史原因的:刚开始开始只有babel-runtime插件,但是用起来很不方便,在代码中直接引入helper 函数,意味着不能共享,造成最终打包出来的文件里有很多重复的helper代码。所以,Babel又开发了babel-plugin-transform-runtime,这个模块会将我们的代码重写,如将Promise重写成_Promise(只是打比方),然后引入_Promise helper函数。这样就避免了重复打包代码和手动引入模块的痛苦。

    用法

    1. `npm install --save-dev babel-plugin-transform-runtime`
    2. `npm install --save babel-runtime`
    3. 写入 `.babelrc`
    
    {
      "plugins": ["transform-runtime"]
    }
    

    启用插件babel-plugin-transform-runtime后,Babel就会使用babel-runtime下的工具函数,转译代码如下:

    'use strict';
    
    var _defineProperty2 = require('babel-runtime/helpers/defineProperty');
    
    var _defineProperty3 = _interopRequireDefault(_defineProperty2);
    
    function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
    
    var key = 'babel';  
    var obj = (0, _defineProperty3.default)({}, key, 'foo');  
    

    不足

    babel-runtime 不能转码实例方法,比如这样的代码:

    '!!!'.repeat(3);  
    'hello'.includes('h');  
    

    这只能通过 babel-polyfill 来转码,因为 babel-polyfill 是直接在原型链上增加方法。

  • 相关阅读:
    request.getParameter() 、 request.getInputStream()和request.getReader() 使用体会
    HTTP之Content-Length
    关于spring3中No Session found for current thread!and Transaction的配置和管理(转)
    Java数据类型和MySql数据类型对应一览
    Spring MVC 解读——View,ViewResolver(转)
    LeetCode 441. Arranging Coins
    LeetCode 415. Add Strings
    LeetCode 400. Nth Digit
    LeetCode 367. Valid Perfect Square
    LeetCode 326. Power of Three
  • 原文地址:https://www.cnblogs.com/raind/p/9017817.html
Copyright © 2011-2022 走看看