Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Babel 系统性学习和梳理 #8

Open
sweeetcc opened this issue Oct 9, 2016 · 1 comment
Open

Babel 系统性学习和梳理 #8

sweeetcc opened this issue Oct 9, 2016 · 1 comment
Assignees

Comments

@sweeetcc
Copy link
Owner

sweeetcc commented Oct 9, 2016

Babel 系统性学习和梳理

babel

## Babel 是什么以及它出现的原因

Babel is a JavaScript Compiler

Babel 是一个 JS 编译器,它可以让我们提前使用下一代 JS 语言的新特性编写代码,并且保证在现有的 Runtime 里能够运行。不仅是 ES6,甚至是 ES7 等,Babel 都已经支持。Babel 提供了一个平台,有丰富的插件系统,让开发者可以轻松地集成自己的开发工具链。

众所周知,JS 是一门解释型语言,不同于编译型语言的是,解释型语言不需要编译。这里,Babel 做的,是**“源码到源码”**的编译,或者叫做“转译(transpiling)”。

babel-transpling

## Babel 的安装和使用入门

Babel 可以很方便地通过 Gulp、Webpack、Browserify 等工具使用,目前先从最基础的使用方法入手,与工具的集成放到后面说明。

一、安装:

通过

$ npm install --global babel-cli

可以将 Babel 的命令行工具安装到全局,但我觉得最好不要直接在全局安装,推荐新建项目或者在已有的项目中针对项目去安装:

$ npm install --save-dev babel-cli

二、基本用法:

使用 Babel 进行转码,直接在命令行执行:

$ ./node_modules/.bin/babel example.js

这样,编译的结果就会输出到命令行中:

compile-result

输出到文件中,需要指定参数 -o 或者 --out-file:

$ ./node_modules/.bin/babel example.js --out-file compiled.js

或者

$ ./node_modules/.bin/babel example.js -o compiled.js

如果需要把一整个牡蛎编译成一个新的目录,需要指定参数 --out-dir 或者 -d:

$ ./node_modules/.bin/babel src--out-file build

或者

$ ./node_modules/.bin/babel src -d build

以上命令中,全部使用 ./node_modules/.bin/babel 是因为我将 babel-cli 安装到了项目依赖中而非全局,简化命令的办法是使用 npm scripts,例如:

{
  "name": "demo",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "compile": "babel example.js -o compiled.js"
  },
  "dependencies": {
    "babel-cli": "^6.16.0",
    "babel-preset-latest": "^6.16.0"
  }
}

那么,运行 npm run compile 就会将 index.js 通过 babel 编译成 compiled.js。

Babel 使用方法

一、 babel-cli

babel-cli 的用法如上所示。

二、babel-register

babel-register 引入文件后,文件引用的 require 文件会被 babel 编译,需要注意的是这种方式不适合在正式环境中使用,部署之前预先编译好是更好的做法,用在本地环境中编写构建脚本或者其他脚本很方便。

使用方式:

$ npm install --save babel-register
// example.js
['a', 'b', 'c'].map((i) => console.log(i));

// register.js
require('babel-register');
require('./example.js');

直接运行:

$ node register.js

babel-register

### 三、 babel-node

如果想要使用 node 来运行代码,那么最便捷的方式就是使用 babel-node CLI, 它是 node CLI 的替代品。这种方法同样不适合用来在生产环境使用。

$ npm install --save babel-cli

在 package.json 的 scripts 中进行调用:

{
  "name": "demo",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "start": "babel-node example.js"
  },
  "dependencies": {
    "babel-cli": "^6.16.0",
    "babel-preset-latest": "^6.16.0"
  }
}

直接调用:

$ npm run start

即有结果输出。

四、 babel-core

如果你需要以编程的方式来使用 Babel,可以使用 babel-core 这个包。

$ npm install --save babel-core

这种方式我还没有实际运用过,可以转码字符串、文件或者是 Babel AST(抽象语法树)。

转码字符串:

babel.transform("code", options);

转码文件:

babel.transformFile("filename.js", options, function(err, result) {
  result; // => { code, map, ast }
});

// 或者

babel.transformFileSync("filename.js", options);
// => { code, map, ast }

转码 Babel AST:

babel.transformFromAst(ast, code, options);
// => { code, map, ast }

例如:

// transform.js
var babel = require('babel-core');

var code = babel.transform('[1, 2, 3].map((n) => console.log(n))', {
    presets: ['es2015']
}).code;

console.log(code);
$ node transform.js

即可输出结果:

babel-transform

## Babel 的配置

首先,可以阅读以下 官方的 Babel 配置文档

.babelrc

通过 .babelrc 来告诉 babel 编译器要做的事情。

两个概念:

  • 插件(plugins)
  • 预设(preset): 指的是一组插件。

安装 preset:

$ npm install --save babel-preset-react

然后在 .babelrc 中添加:

"presets": [
    "react"
]

另外,JavaScript 还有一些提案,正在积极通过 TC39(ECMAScript 标准背后的技术委员会)的流程成为标准的一部分。

这个流程分为 5(0-4)个阶段。 随着提案得到越多的关注就越有可能被标准采纳,于是他们就继续通过各个阶段,最终在阶段 4 被标准正式采纳。

以下是4 个不同阶段的(打包的)预设:

  • babel-preset-stage-0
  • babel-preset-stage-1
  • babel-preset-stage-2
  • babel-preset-stage-3

以上每种预设都依赖于紧随的后期阶段预设。例如,babel-preset-stage-1 依赖 babel-preset-stage-2,后者又依赖 babel-preset-stage-3。

预设同样可以通过 npm 来安装:

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

基于环境的配置:

.babelrc 中可以配置 env,在不同的环境中根据需要集成不同的 plugins 和 preset 等,例如:

{
  "presets": [
    "es2015"
  ],
  "plugins": [],
  "envs": {
    "development": {
      "plugins": []
    },
    "production": {
      "plugins": []
    }
  }
}

当前的环境变量可以用 process.env.BABEL_ENV 来获取,如果取不到就用 NODE_ENV 代替,如果仍然没有就设置为默认值 “development”。

执行 Babel 生成的代码

babel-polyfill

通过 babel 编译之后的代码并不能保证在浏览器环境执行,因为虽然 babel 会编译新的 JS 语法,但新的 JS API 并未被编译。

例如:

function addAll() {
  return Array.from(arguments).reduce((a, b) => a + b);
}

被编译成:

function addAll() {
  return Array.from(arguments).reduce(function(a, b) {
    return a + b;
  });
}

但是 Array.from 并非所有浏览器都支持。这个时候就需要我们引入兼容性补丁(polyfill)来解决。

$ npm install --save babel-polyfill

然后在文件顶部引入:

import 'babel-polyfill';

babel-runtime

在 Babel 过程中,Babel 可能会生成很多助手方法到文件的顶部,而 babel runtime 可以将这些方法移动到统一的运行时 (runtime) 中去,而不是在每一个用到的地方都打包进去。

@sweeetcc sweeetcc changed the title hello world 3 Babel 系统性学习和梳理 Oct 9, 2016
@sweeetcc sweeetcc added the js label Oct 9, 2016
@sweeetcc sweeetcc added the node label Oct 18, 2016
@sweeetcc sweeetcc self-assigned this Oct 18, 2016
@sweeetcc
Copy link
Owner Author

文中也提到了,Babel 可以结合其他构建工具、代码检测工具等共同运用,所以这部分留待后续总结。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant