babel学习

Posted 做枚温婉的妹纸吧哈哈

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了babel学习相关的知识,希望对你有一定的参考价值。

.babelrc文件

babel可以将ES6编写的代码转码成你所需要的编码格式。前提是要指定希望的转码方式,即指定要用的插件并安装(否则babel什么也不做,输出源码)。可以在.balbelrc 中进行指定:


    "presets": ["es2015"],
    "plugins": ["transform-es2015-modules-umd"]

presets 表示一组插件构成的集合,相当于一个大包好的插件大礼包,可以通过参数配置进行,决定使用其中的某个插件?例如:


    "presets": [
       ["es2015", "modules": "amd"]
    ]

可以将代码转成amd格式的:

define(["exports"], function (exports) 
    "use strict";
    Object.defineProperty(exports, "__esModule", 
        value: true
    );
    function core() 
        console.log("core");
    
    exports.default = core;
);

此时需要安装requirejs 包才能在浏览器中正常使用。

plugins 中就可以单独指定你需要哪些插件。
babel会根据在该文件中的配置来决定转码方式。

babel-cli包

如果想通过命令行来进行转码,需要安装该包:

npm install --save babel-cli

如果加了--global 参数,可以直接在终端进行转码:

babel test.js

此时转码后的文件直接输出在终端。
或者仅是本地安装的话也可以在package.jsonscript 字段来进行命令的指定:

"script": 
    "jsnext": "mkdir -p js; babel jsnext -d js --source-maps inline --watch"

plugins

es6代码要转成什么样子完全依赖你所指定的插件,例如有这样一个core.js文件:

function core() 
    console.log("core");

export default core;

如果我们进行了这样的配置:


    "presets": [
        "es2015"
    ]
  

转码后的代码为:

"use strict";

Object.defineProperty(exports, "__esModule", 
    value: true
);
function core() 
    console.log("core");

exports.default = core;

此时如果有一个test.html 文件:

<script src="js/core.js"></script>
<script>
    core();
</script> 

像这样调用会报错,因为浏览器环境识别不了exports对象。如果我们对.babelrc 文件进行更改,指定输出为umd 格式:


    "presets": [
       ["es2015", "modules": "umd"]
    ]

此时转码成了:

(function (global, factory) 
    if (typeof define === "function" && define.amd) 
        define(["exports"], factory);
     else if (typeof exports !== "undefined") 
        factory(exports);
     else 
        var mod = 
            exports: 
        ;
        factory(mod.exports);
        global.core = mod.exports;
    
)(this, function (exports) 
    "use strict";

    Object.defineProperty(exports, "__esModule", 
        value: true
    );
    function core() 
        console.log("core");
    
    exports.default = core;
);

可以看到,mod.exports.default 指向函数core,而global.core 指向 mod.exports 对象。global 在浏览器中就是window 对象,window对象上的core属性(该属性就是模块名,即js文件名)是一个对象,该对象有个方法default 指向之前定义的core 函数。因此在test.html 中要这样来引用:

core.default();

如果es6代码中用这样的输出方式:

export 
    core
;

那么转码后只有此处不同:

exports.core = core;

也就是说default被一个真实的名字取代了,test.html 中要这样引用:

core.core();
  • 插件babel-plugin-transform-es2015-modules-amd

如果把配置项改为:


    "presets": [],
    "plugins": [
        "transform-es2015-modules-amd"
    ]

进行转码后的结果是:

define(["exports"], function (exports) 
    "use strict";

    Object.defineProperty(exports, "__esModule", 
        value: true
    );
    function core() 
        console.log("core");
    
    exports.core = core; //以exportcore形式输出,如果是export default core,则此处是 exports.default = core
);

这和配置为


    "presets": [
       ["es2015", "modules": "amd"]
    ]

是一样的,umd也类似。设置成amd或者umd格式的就可以同requirejs库配合使用了。
test.html

<script src="../common/js/require.js"></script>
<script>
    requirejs.config(
        baseUrl: 'js'
    );
</script>
<script>
require(['core'], function(module) 
    module.core(); //如果以default形式输出,此处应为module.default()
);

export default functionName 相当于是将整个模块作为一个方法输出,即
module.exports = functionName

  • .babelrc配置:

  "presets": ["es2015"],
   "plugins": [
        "transform-es2015-modules-umd"
    ]
  1. 输出:
export pagination;

编译结果:

exports.pagination = pagination;

以requirejs方式进行引用:

require(['core'], function(module) 
    module.pagination(document.getElementById('pagination1'), 
        total_items: 100
    );
);

rollup打包:
输出:

factory((global.pagination = global.pagination || ))

function (exports) 
    //...
    exports.pagination = pagination;

global.pagination 是指向模块,有一个属性是pagination 指向方法pagination。因此应该这样引用:

<script>
    pagination.pagination(document.getElementById('pagination1'), 
        total_items: 100
    );
</script>

但这不是我们想要的引用方式,最好是pagination 函数直接作为全局变量window的属性。

  1. 如果输出形式改为:
exports default pagination;

意思是整个模块就是一个方法???
babel编译结果为:

exports.default = pagination;

requirejs引用:

require(['core'], function(module) 
    module.default(document.getElementById('pagination1'), 
        total_items: 100
    );
);

rollup打包:

global.pagination = factory()

function () 
    return pagination;

此时,pagination作为全局变量window的属性,且指向函数pagination
页面引用:

    pagination(document.getElementById('pagination1'), 
        total_items: 100
    );

是我们想要的形式。

  • 如果配置项改为:

  "presets": ["es2015"],
   "plugins": [
        "add-module-exports",
        "transform-es2015-modules-umd"
    ]

babel-plugin-add-module-exports

1.输出:

export patination

编译结果为exports.pagination = pagination; 与之前一样。
2. 输出:

export default pagination;

编译:

    exports.default = pagination;
    module.exports = exports['default'];

可以看出增加了module.exports 并直接指向函数pagination
因此requirejs时应当这样:

require(['core'], function(pagination) 
    pagination(document.getElementById('pagination1'), 
        total_items: 100
    );
);

可以避免之前的.default() 这种丑陋的写法。
rollup后也和之前是没有区别的。
因此决定采用配置:

```

  "presets": ["es2015"],
   "plugins": [
        "transform-es2015-modules-umd"
    ]

“`
并已default形式输出。

以上是关于babel学习的主要内容,如果未能解决你的问题,请参考以下文章

Babel 只编译我的 Vue 项目的 js 文件,而不是整个项目

关于ES6的打包编译,

传统web项目搭建学习

大包网卡缓存满

tar大包压缩进一步了解

node.js学习笔记之babel使用