nodejs 发布已有多时,版本 log 重点说明从此 nodejs 开始原生支持 ES6
,这让许多开发者都 happy 了一下。
笔者立刻将原来的一个小 server 框架改成 ES6 语法,但是:
WTF!~~~说好的全部原生支持呢?import
/ export
各种报错,加了--es_staging
,也不行,人与人之前的信任呢?
回头再查查版本 log ,Modules 那一章还是 commonjs 的引用方法,网上其它人也说这个问题,那就是妥妥的不支持了。
测试文件如下:
'use strict'; class Main { constructor() { this.parent = 'this is parent msg'; } say() { setTimeout(() => { console.log(this.parent); }, 500); } } export default Main;
简单暴力(没)有成效的解决方法
“不支持 ES6 就用 babel 转换呗~” 大多数人都是这样想的。将完全体的 ES6 通过 babel 降级转换~~~然后就 OK 了。node 运行各种顺利。
标签 es2015 转换后:
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } var Main = function () { function Main() { _classCallCheck(this, Main); this.parent = 'this is parent msg'; } _createClass(Main, [{ key: 'say', value: function say() { var _this = this; setTimeout(function () { console.log(_this.parent); }, 500); } }]); return Main; }(); exports.default = Main; //# sourceMappingURL=main.js.map
......
我差点也就中了。-_-!
看着 node V6 对其它各种 es6 特性都支持的很好,真不想经转换后一下回到解放前。
注:
其实上面一句并不是真正原因啦,node 的原生支持并不是简单暴力的内置了一个 babel,是在整个内核运行机制上进行改进,尽可能符合 es6 的语言思想。在执行流程、内存管理上都有优化。网上有不少原生 es6 运行性能的对比,有兴趣可以去看一下。
经笔者测试,以最新的 6.4 为例,好像只有 import
/ export
不能支持,因此,笔者试着找一下只对此进行降级转换的方法。
针对性的 babel 降级转换
通过查看 babel
的插件列表 ;
其中在 Modules
有一个 es2015_modules_commonjs
,应该就是将 ES6 Modules 转换成 nodejs 通用的 commonjs 形式的。
立刻试用,.babelrc
文件如下:
{ "plugins": [ "transform-es2015-modules-commonjs" ] }
如此经过转换后的文件:
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); class Main { constructor() { this.parent = 'this is parent msg'; } say() { setTimeout(() => { console.log(this.parent); }, 500); } } exports.default = Main; //# sourceMappingURL=main.js.map
执行通过 perfect!!! 要得就是这个效果。而且因为转换程度不深,速度也差不多减少了 2/3。
总结
如上只是一个经历,相信随着 nodejs 的不断发展,完美支持 es6 也是迟早的事。但新语法、新事物肯定也会随之出现,我们需要的是一个“增量式”的转换,希望对以后处理此类问题有所启发。