Node 本身已经支持部分 ES6 语法, 但是 import export, 以及 async await(Node 8 已经支持)等一些语法, 我们还是无法使用. 为了能使用这些新特性, 我们就需要使用 babel 把 ES6 转成 ES5 语法.
安装 babel
NPM install babel-cli -g
基础知识
babel 的配置文件是. babelrc
{ "presets": [] }
新建一个 demo 文件夹, 文件夹下新建 1.JS
- const arr = [1, 2, 3];
- arr.map(item => item + 1);
同时新建. babelrc 配置文件
{ "presets": [] }
终端运行
babel 1.JS -o dist.JS
可以看见, 在文件夹下, 新建了一个 dist.JS, 这就是 babel 转码后的文件
但是, dist.JS 目前是没有任何变化的, 因为我们在配置文件里面没有声明转码规则, 所以 babel 无法转码
安装转码插件
NPM install --save-dev babel-preset-es2015 babel-preset-stage-0
修改配置文件
- {
- "presets": [
- "es2015",
- "stage-0"
- ]
- }
es2015 可以转码 es2015 的语法规则, stage-0 可以转码 ES7 语法(比如 async await)
再次运行终端
babel 1.JS -o dist.JS
可以看见, 箭头函数被转码了
- var arr = [1, 2, 3];
- arr.map(function (item) {
- return item + 1;
- });
我们试下 async await
- async function start() {
- const data = await test();
- console.log(data);
- }
- function test() {
- return new Promise((resolve, reject) => {
- resolve('ok');
- })
- }
转码后的文件
- 'use strict';
- var start = function () {
- var _ref = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee() {
- var data;
- return regeneratorRuntime.wrap(function _callee$(_context) {
- while (1) {
- switch (_context.prev = _context.next) {
- case 0:
- _context.next = 2;
- return test();
- case 2:
- data = _context.sent;
- console.log(data);
- case 4:
- case 'end':
- return _context.stop();
- }
- }
- }, _callee, this);
- }));
- return function start() {
- return _ref.apply(this, arguments);
- };
- }();
- function _asyncToGenerator(fn) {
- return function () {
- var gen = fn.apply(this, arguments);
- return new Promise(function (resolve, reject) {
- function step(key, arg) {
- try { var info = gen[key](arg);
- var value = info.value;
- } catch (error) {
- reject(error); return;
- } if (info.done) {
- resolve(value);
- } else {
- return Promise.resolve(value).then(function (value) {
- step("next", value);
- }, function (err) {
- step("throw", err);
- });
- }
- } return step("next");
- });
- };
- }
- function test() {
- return new Promise(function (resolve, reject) {
- resolve('ok');
- });
- }
再试下 import export
util.JS
- export default function say() {
- console.log('2333');
- }
1.JS
- import say from './util';
- say();
这次, 要把 1.JS 和 util.JS 都转码, 我们可以把整个文件夹转码
babel demo -d dist
新生成的 dist 文件夹下, 就有转码后的文件. 可以看见, 转码后, 仍然使用的是 module.exportsCMD 模块加载
babel-preset-env
上面的转码其实有个缺陷, 就是 babel 会默认把所有的代码转成 es5, 这意味着, 即使 node 支持 let 关键字, 转码后, 也会被转成 var
我们可以使用 babel-preset-env 这个插件, 它会自动检测当前 node 版本, 只转码 node 不支持的语法, 非常方便
- NPM install --save-dev babel-preset-env
- .babelrc
- {
- "presets": [
- ["env", {
- "targets": {
- "node": "current"
- }
- }]
- ]
- }
1.JS
- say() {
- }
- }
- const a = 1;
- babel 1.JS -o dist.JS
编译出来后
- "use strict";
- class F {
- say() {}
- }
- const a = 1;
可以看见, class 和 const 并没有被转码, 因为当前 node 版本 (8.9.3) 支持该语法
在实际项目中使用 ES6 语法
Koa2 需要 Node v7.6.0 以上的版本来支持 async 语法, 同时, 我们也想在 Koa2 中使用 import 模块化写法
- NPM install --save-dev babel-register
- NPM install koa --save
新建一个文件夹 App
util.JS
- export function getMessage() {
- return new Promise((resolve, reject) => {
- resolve('Hello World!');
- })
- }
App.JS
- import Koa from 'koa';
- import { getMessage } from './util'
- const App = new Koa();
- App.use(async ctx => {
- const data = await getMessage();
- ctx.body = data;
- });
- App.listen(3000);
如果直接启动文件, 肯定会报错
node App
我们需要一个入口文件, 来转码
index.JS
- require("babel-register");
- require("./app.js");
- node index
访问 http://localhost:3000 / 可以看见页面了!
babel-register 是实时转码的, 所以实际发布时, 应该先把整个 App 文件夹转码
babel App -d dist
这次, 只要启动 dist 下的 App.JS 即可
node App
来源: http://www.css88.com/qa/node-js/10848.html