nodejs v6+ 不兼容 ES6 import/export 優雅解決方法

nodejs 發佈已有多時,版本 log 重點說明今後 nodejs 開始原生支持 ES6,這讓許多開發者都 happy 了一下。javascript

筆者馬上將原來的一個小 server 框架改爲 ES6 語法,可是: java

clipboard.png

WTF!~~~說好的所有原生支持呢?import / export各類報錯,加了--es_staging,也不行,人與人以前的信任呢?node

回頭再查查版本 log ,Modules 那一章仍是 commonjs 的引用方法,網上其它人也說這個問題,那就是妥妥的不支持了。es6

測試文件以下:json

'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 運行各類順利。babel

標籤 es2015 轉換後:app

'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 的插件列表 http://babeljs.io/docs/plugins/;

clipboard.png

其中在 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 也是早晚的事。但新語法、新事物確定也會隨之出現,咱們須要的是一個「增量式」的轉換,但願對之後處理此類問題有所啓發。

相關文章
相關標籤/搜索