一:理解 babel之配置文件.babelrc 基本配置项

1. 什么是babel? 它是干什么用的?

ES6是2015年发布的下一代javascript语言标准,它引入了新的语法和API,使我们编写js代码更加得心应手,比如class,let,for...of promise等等这样的,但是可惜的是这些js新特性只被最新版本的浏览器支持,但是低版本浏览器并不支持,那么低版本浏览器下就需要一个转换工具,把es6代码转换成浏览器能识别的代码,babel就是这样的一个工具。可以理解为 babel是javascript语法的编译器。

2. Babel编译器
在Babel执行编译的过程中,会从项目的根目录下的 .babelrc文件中读取配置。.babelrc是一个json格式的文件。
在.babelrc配置文件中,主要是对预设(presets) 和 插件(plugins) 进行配置。.babelrc配置文件一般为如下:

{
"plugins": [
[
"transform-runtime",
{
"polyfill": false
}
]
],
"presets": [
[
"env",
{
"modules": false
}
],
"stage-2",
"react"
]
}

2.1 plugins
该属性是告诉babel要使用那些插件,这些插件可以控制如何转换代码。

1. 理解 babel-polyfill 和 babel-runtime 及 babel-plugin-transform-runtime

Babel默认只转换新的javascript语法,而不转换新的API,比如 Iterator, Generator, Set, Maps, Proxy, Reflect,Symbol,Promise 等全局对象。以及一些在全局对象上的方法(比如 Object.assign)都不会转码。
比如说,ES6在Array对象上新增了Array.form方法,Babel就不会转码这个方法,如果想让这个方法运行,必须使用 babel-polyfill来转换等。

因此:babel-polyfill和babel-runtime就是为了解决新的API与这种全局对象或全局对象方法不足的问题,因此可以使用这两个插件可以转换的。

那么他们两者的区别是什么?
babel-polyfill 的原理是当运行环境中并没有实现的一些方法,babel-polyfill会做兼容。
babel-runtime 它是将es6编译成es5去执行。我们使用es6的语法来编写,最终会通过babel-runtime编译成es5.也就是说,不管浏览器是否支持ES6,只要是ES6的语法,它都会进行转码成ES5.所以就有很多冗余的代码。

babel-polyfill 它是通过向全局对象和内置对象的prototype上添加方法来实现的。比如运行环境中不支持Array.prototype.find 方法,引入polyfill, 我们就可以使用es6方法来编写了,但是缺点就是会造成全局空间污染。

babel-runtime: 它不会污染全局对象和内置对象的原型,比如说我们需要Promise,我们只需要import Promise from 'babel-runtime/core-js/promise'即可,这样不仅避免污染全局对象,而且可以减少不必要的代码。

虽然 babel-runtime 可以解决 babel-polyfill中的避免污染全局对象,但是它自己也有缺点的,比如上,如果我现在有100个文件甚至更多的话,难道我们需要一个个文件加import Promise from 'babel-runtime/core-js/promise' 吗?那这样肯定是不行的,因此这个时候出来一个 叫 babel-plugin-transform-runtime,
它就可以帮助我们去避免手动引入 import的痛苦,并且它还做了公用方法的抽离。比如说我们有100个模块都使用promise,但是promise的polyfill仅仅存在1份。
这就是 babel-plugin-transform-runtime 插件的作用。

2. 理解 babel-plugin-transform-runtime 的配置一些选项

因此通过上面的理解,我们可以对 transform-runtime 通过如下配置 plugins; 如下代码:

{
'plugins': [
[
'transform-runtime',
{
'helpers': false,
'polyfill': false,
'regenerator': true,
'moduleName': 'babel-runtime'
}
]
]
}

配置项可以看官网,查看官网

helpers: 默认值为true,表示是否开启内联的babel helpers(即babel或者环境本来存在的某些对象方法函数)如:extends,etc这样的
在调用模块名字时将被替换名字。

polyfill:默认值为true,表示是否把内置的东西(Promise, Set, Map)等转换成非全局污染的。

regenerator:默认值为true,是否开启generator函数转换成使用regenerator runtime来避免污染全局域。

moduleName:默认值为 babel-runtime,当调用辅助 设置模块(module)名字/路径.
比如如下这样设置:

{
"moduleName": "flavortown/runtime"
}

import引入文件如下这个样子:

import extends from 'flavortown/runtime/helpers/extends';

3 presets
presets属性告诉Babel要转换的源码使用了哪些新的语法特性,presets是一组Plugins的集合。

3.1 理解 babel-preset-env

比如:

babel-preset-es2015: 可以将es6的代码编译成es5.
babel-preset-es2016: 可以将es7的代码编译为es6.
babel-preset-es2017: 可以将es8的代码编译为es7.
babel-preset-latest: 支持现有所有ECMAScript版本的新特性。

举个列子,比如我们需要转换es6语法,我们可以在 .babelrc的plugins中按需引入一下插件,比如:
check-es2015-constants、es2015-arrow-functions、es2015-block-scoped-functions等等几十个不同作用的plugin:
那么配置项可能是如下方式:

// .babelrc
{
"plugins": [
"check-es2015-constants",
"es2015-arrow-functions",
"es2015-block-scoped-functions",
// ...
]
}

但是Babel团队为了方便,将同属ES2015的几十个Transform Plugins集合到babel-preset-es2015一个Preset中,这样我们只需要在.babelrc的presets加入es2015一个配置就可以完成全部ES2015语法的支持了:
如下配置:

// .babelrc
{
"presets": [
"es2015"
]
}

但是我们随着时间的推移,将来可能会有跟多的版本插件,比如 bebel-preset-es2018,.... 等等。
因此 babel-preset-env 出现了,它的功能类似于 babel-preset-latest,它会根据目标环境选择不支持的新特性来转译。

首先需要在项目中安装,如下命令:

npm install babel-preset-env --save-dev

在.babelrc配置文件中 可以如下简单的配置:

{
"presets": ['env']
}

我们还可以仅仅配置项目所支持的浏览器的配置

1. 支持每个浏览器最后两个版本和safari大于等于7版本所需的polyfill代码转换,我们可以如下配置:

{
'presets': [
['env', {
'target': {
'browsers': ['last 2 versions', 'safari >= 7']
}
}]
]
}

2. 支持市场份额超过5%的浏览器,可以如下配置:

{
'presets': [
['env', {
'target': {
'browsers': '> 5%'
}
}]
]
}

3. 指定浏览器版本,可以如下配置:

{
'presets': [
['env', {
'target': {
'chrome': 56
}
}]
]
}

Node.js
如果通过Babel编译Node.js代码的话,可以设置 "target.node" 是 'current', 含义是 支持的是当前运行版本的nodejs。
如下配置代码:

{
"presets": [
["env", {
"targets": {
"node": "current"
}
}]
]
}

理解 babel-preset-env 中的选项配置:
1. targets: {[string]: number | string }, 默认为{};
含义是支持一个运行环境的对象,比如支持node版本;可以如下配置: node: '6.0';
运行环境: chrome, opera, edge, firefox, safari, ie, ios, android, node, electron

2. targets.browsers <Array | string>
支持浏览器的配置项,该配置项使用方式可以到 browserslist来查询(https://github.com/browserslist/browserslist)
比如上面的 支持每个浏览器最后两个版本和safari大于等于7版本。如上配置。

3. modules
该参数的含义是:启用将ES6模块语法转换为另一种模块类型。将该设置为false就不会转换模块。默认为 'commonjs'.
该值可以有如下:
'amd' | 'umd' | 'systemjs' | 'commonjs' | false

我们在项目中一般会看到如下配置,设置modules: false, 如下代码配置:

"presets": [
'env',
{
'modules': false
}
]

这样做的目的是:以前我们需要使用babel来将ES6的模块语法转换为AMD, CommonJS,UMD之类的模块化标准语法,但是现在webpack都帮我做了这件事了,所以我们不需要babel来做,因此需要在babel配置项中设置modules为false,因为它默认值是commonjs, 否则的话,会产生冲突。

4. loose, 该参数值默认为false
含义是:允许它们为这个 preset 的任何插件启用”loose” 转换。

5. include: 包含一些插件,默认为 [];
比如包含箭头函数,可以如下配置:

{
"presets": [
["env", {
"targets": {
"browsers": ["last 2 versions", "safari >= 7"]
},
"include": ["transform-es2015-arrow-functions", "es6.map"]
}]
]
}

6. exclude; 排除哪些插件,默认为 [];
比如 排除生成器,可以如下配置:

{
"presets": [
["env", {
"targets": {
"browsers": ["last 2 versions", "safari >= 7"]
},
"exclude": ["transform-regenerator", "es6.set"]
}]
]
}

3.2 理解 babel-presets-stage-x
官方预设(preset), 有两种,一个是按年份(babel-preset-es2017),一个是按阶段(babel-preset-stage-0)。 这主要是根据TC39 委员会ECMASCRPIT 发布流程来制定的。因此到目前为止 有4个不同的阶段预设:

babel-preset-stage-0

babel-preset-stage-1

babel-preset-stage-2

babel-preset-stage-3

以上每种预设都依赖于紧随的后期阶段预设,数字越小,阶段越靠后,存在依赖关系。也就是说stage-0是包括stage-1的,以此类推。因此 stage-0包含stage-1/2/3的内容。所以如果我们不知道需要哪个stage-x的话,直接引入stage-0就好了。

stage0 (https://babeljs.io/docs/en/babel-preset-stage-0)只是一个美好激进的想法,一些 Babel 插件实现了对这些特性的支持 ,但是不确定是否会被定为标准.

stage1 (https://babeljs.io/docs/en/babel-preset-stage-1) 值得被纳入标准的特性.

stage2 (https://babeljs.io/docs/en/babel-preset-stage-2) 该特性规范己经被起草,将会被纳入标准里.

stage3 (https://babeljs.io/docs/en/babel-preset-stage-3)该特性规范已经定稿,大浏览器厂商和 Node.js 社区己开始着手实现.

但是在我们使用的时候只需要安装你想要的阶段就可以了:比如 babel-preset-stage-2, 安装命令如下:

npm install --save-dev babel-preset-stage-2

二:在webpack中配置babel

在上面了解了babel后,现在我们需要知道如何在webpack中使用它了。由于babel所做的事情是转换代码,所有需要使用loader去转换,因此我们需要配置babel-loader。

在安装babel-loader之前,我们需要安装babel-core, 因为babel-core是Babel编译器的核心,因此也就意味着如果我们需要使用babel-loader进行es6转码的话,我们首先需要安装 babel-core, 安装命令如下即可:

npm install --save-dev babel-core

然后我们再安装 babel-loader, 命令如下:

npm install --save-dev babel-loader

接着我们需要安装 babel-preset-env, babel-plugin-transform-runtime, babel-preset-stage-2, 如下命令安装

npm install --save-dev  babel-preset-env babel-plugin-transform-runtime babel-preset-stage-2

因此 .babelrc 配置如下即可:

{
"plugins": [
[
"transform-runtime",
{
"polyfill": false
}
]
],
"presets": [
[
"env",
{
"modules": false
}
],
"stage-2"
]
}

在做demo之前,我们还是先看下目录结构变成如下:

### 目录结构如下:
demo1 # 工程名
| |--- dist # 打包后生成的目录文件
| |--- node_modules # 所有的依赖包
| |--- js # 存放所有js文件
| | |-- demo1.js
| | |-- main.js # js入口文件
| |
| |--- webpack.config.js # webpack配置文件
| |--- index.html # html文件
| |--- styles # 存放所有的css样式文件
| |--- .gitignore
| |--- README.md
| |--- package.json
| |--- .babelrc # babel转码文件

因此webpack配置中需要添加 babel-loader 配置,如下配置:

module.exports = {
module: {
rules: [
{
test: /\.js$/,
exclude: /(node_modules)/, // 排除文件
loader: 'babel-loader'
}
]
}
}

webpack 所有配置如下代码

const path = require('path');
// 提取css的插件
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const ClearWebpackPlugin = require('clean-webpack-plugin'); module.exports = {
entry: './js/main.js',
output: {
filename: 'bundle.js',
// 将输出的文件都放在dist目录下
path: path.resolve(__dirname, 'dist'),
publicPath: '/dist'
},
mode: 'development',
module: {
rules: [
{
// 使用正则去匹配要用该loader转换的css文件
test: /\.css$/,
loaders: ExtractTextPlugin.extract({
// 转换 .css文件需要使用的Loader
use: ['css-loader']
})
},
{
test: /\.(png|jpg)$/,
loader: 'url-loader',
options: {
limit: 10000,
name: '[name].[ext]'
}
},
{
test: /\.js$/,
exclude: /(node_modules)/, // 排除文件
loader: 'babel-loader'
}
]
},
resolve: {
// modules: ['plugin', 'js']
},
externals: {
jquery: 'jQuery'
},
devtool: 'source-map',
plugins: [
// new ClearWebpackPlugin(['dist']),
new ExtractTextPlugin({
// 从js文件中提取出来的 .css文件的名称
filename: `main.css`
})
]
};

package.json 安装依赖包如下:

{
"name": "demo1",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"dev": "webpack-dev-server --progress --colors --devtool source-map --hot --inline",
"build": "webpack --progress --colors"
},
"devDependencies": {
"babel-core": "^6.26.3",
"babel-loader": "^7.1.5",
"babel-plugin-transform-runtime": "^6.23.0",
"babel-preset-env": "^1.7.0",
"babel-preset-stage-2": "^6.24.1",
"clean-webpack-plugin": "^0.1.19",
"css-loader": "^1.0.0",
"extract-text-webpack-plugin": "^4.0.0-beta.0",
"file-loader": "^1.1.11",
"path": "^0.12.7",
"style-loader": "^0.21.0",
"uglifyjs-webpack-plugin": "^1.2.7",
"url-loader": "^1.0.1",
"webpack": "^4.16.1",
"webpack-cli": "^3.0.8",
"webpack-dev-server": "^3.1.4"
},
"dependencies": {
"axios": "^0.18.0",
"jquery": "^3.3.1"
}
}

现在我们继续在 main.js 代码内 编写 Generator 函数,代码如下:

function* g() {
yield 'a';
yield 'b';
yield 'c';
return 'ending';
} var gen = g();
console.log(gen.next()); // 返回Object {value: "a", done: false} for(let a of [1,2,3,4]) {
console.log(a); // 打印出 1, 2, 3, 4
}

然后重新运行打包命令 npm run dev 后,打开浏览器运行 可以看到控制台输出 {value: "a", done: false},说明babel已经转译了。

babel配置文件.babelrc详解的更多相关文章

  1. vue-cli中的babel配置文件.babelrc详解

    本文介绍vue-cli脚手架工具根目录的babelrc配置文件 介绍 es6特性浏览器还没有全部支持,但是使用es6是大势所趋,所以babel应运而生,用来将es6代码转换成浏览器能够识别的代码 ba ...

  2. Nginx 主配置文件参数详解

    Nginx 主配置文件参数详解 Nginx 安装完毕后,会有响应的安装目录,安装目录里 nginx.conf 为 nginx 的主配置文件, ginx 主配置文件分为 4 部分,main(全局配置). ...

  3. CentOS网络接口配置文件ifcfg-eth详解

    ======CentOS网络接口配置文件ifcfg-eth详解====== 文件 /etc/sysconfig/network-scripts/ifcfg-eth0在/etc/sysconfig/ne ...

  4. Apache2 httpd.conf配置文件中文版详解

    Apache2 httpd.conf配置文件中文版详解## 基于 NCSA 服务的配置文件.##这是Apache服务器主要配置文件.#它包含服务器的影响服务器运行的配置指令.#参见以取得关于这些指令的 ...

  5. ssh2的application.xml配置文件配置详解

    ssh2的application.xml配置文件配置详解   1.导入其他的配置文件.在ssh项目中可以导入其他的配置文件,导入的格式为: <import resource="clas ...

  6. MySQL-5.5.32 配置文件优化详解

    目录 MySQL-5.5.32 配置文件优化详解 一.配置文件说明 2.my-medium.cnf 3.my-large.cnf 4.my-huge.cnf 5.my-innodb-heavy-4G. ...

  7. [转帖]SSH远程登录配置文件sshd_config详解

    SSH远程登录配置文件sshd_config详解 2016年06月02日 17:42:25 Field_Yang 阅读数 61386   版权声明:本文为博主原创文章,遵循CC 4.0 by-sa版权 ...

  8. mysql数据库my.ini配置文件中文详解

    mysql数据库my.ini配置文件中文详解 mysqld程序–目录和文件 basedir = path 使用给定目录作为根目录(安装目录). character-sets-dir = path 给出 ...

  9. 史上最全web.xml配置文件元素详解

    一.web.xml配置文件常用元素及其意义预览 <web-app> <!--定义了WEB应用的名字--> <display-name></display-na ...

随机推荐

  1. python的with用法(转载)

    原文地址:https://www.cnblogs.com/wanglei-xiaoshitou1/p/9238275.html 一.with语句是什么? 有一些任务,可能事先需要设置,事后做清理工作. ...

  2. flask启动常见问题1:sqlalchemy.exc.ArgumentError: Mapper mapped class UserCode->data_system_user_email could not assemble any primary key columns for mapped table 'data_system_user_email'

    我的描述:当我编辑好flask以后,ORM映射数据库完成,启动项目时,发生现象: 解决: 看字面的意思是主键导致的错误,于是我查看了data_system_user_email的键参数配置,发现表没有 ...

  3. TKMybatis

    TKMybatis与Mybatis-plus都是mybatis的扩展,有相同的地方,也有不同的地方. 1.导入坐标 <!--mybatis依赖--> <dependency> ...

  4. Java8 关于stream.foreach()和stream.peek()的区别解析

    该思考来源于日常工作中,特记此心得. 思考:如何快速将list中的每个item内部属性值改变并进行其他流体操作呢? 下面做个测试:如何先在list中统一改变某属性的值,然后再根据某个属性取出该属性值最 ...

  5. 水墨屏开发设备,旧 Kindle 改造而成

    原文地址:Turning an old Amazon Kindle into a eink development platform 原文作者:adq 译者 & 校正:HelloGitHub- ...

  6. 使用Docker创建MongoDb服务

    使用Docker创建MongoDb服务 1.先拉mongodb镜像 docker pull mongodb:4.2.5 2.创建映射目录 创建mongo映射目录,用于存放后面的相关东西. mkdir ...

  7. DRF 三大认证之身份认证

    目录 路由组件补充 三大认证 一.身份认证 1.如何进行身份认证 2.jwt认证规则原理 3.jwt的组成 4.jwt的使用方法 4.1 签发算法 4.2 校验算法 4.3 刷新算法 二.权限认证 三 ...

  8. 五. SpringCloud服务降级和熔断

    1. Hystrix断路器概述 1.1 分布式系统面临的问题 复杂分布式体系结构中的应用程序有数十个依赖关系,每个依赖关系在某些时候将不可避免地失败.这就造成有可能会发生服务雪崩.那么什么是服务雪崩呢 ...

  9. 基于keras实现的中文实体识别

    1.简介 NER(Named Entity Recognition,命名实体识别)又称作专名识别,是自然语言处理中常见的一项任务,使用的范围非常广.命名实体通常指的是文本中具有特别意义或者指代性非常强 ...

  10. 如何理解JavaScript中的函数

    转: 如何理解JavaScript中的函数 JS中的函数简介 JS中的函数是一种通过调用来完成具体业务的一段代码块.最核心的目的是将可重复执行的操作进行封装,然后供调用方无限制的调用. JS中的函数的 ...