如何讓 node 執行 es6 模組檔案,及其原理

2021-09-03 01:43:24 字數 4246 閱讀 7388

最新版的node支援最新版ecmascript幾乎所有特性,但有乙個特性卻一直到現在都還沒有支援,那就是從es2015開始定義的模組化機制。而現在我們很多專案都是用es6的模組化規範來寫**的,包括node專案,所以,node不能執行es6模組檔案就會很不便。

node執行es6模組檔案的方式有兩種:

轉碼es6模組為commonjs模組

hooknoderequire機制,直接讓noderequire載入import/export因為node支援幾乎所有除import/export外的語法,所以我們只需要將import/export轉碼成require/exports,而不需要轉碼其他語法。

比如下面的專案:

- package.json

- src/

- index.js

- print.js

- ...

# package.json

# src/index.js

import print from './print';

print('index');

export default print;

# src/print.js

export default str => ;

因為src目錄下的原始檔都是es6模組化規範的,node並不能直接執行,所以需要轉碼成commonjs規範的**。

這個過程有兩個方案:

如果不會單獨使用src目錄下的某個檔案,而僅僅是以src/index.js為入口檔案使用,可以把src目錄下的檔案打包成乙個檔案到lib/index.js:這種方式推薦使用工具 rollup

如果需要單獨使用src目錄下的檔案,那就需要把src目錄下的檔案一對一的轉碼到lib目錄下:這種方式推薦使用工具 gulp + babel

# rollup.config.js

export default ,

};# package.json

, "devdependencies":

}

執行命令:

npm run build
結果:

# lib/index.js

'use strict';

var print = str => ;

print('index');

module.exports = print;

# build.js

const gulp = require('gulp');

const babel = require('gulp-babel');

gulp.task('babel', () =>

gulp.src('src/**/*.js')

.pipe(babel())

.pipe(gulp.dest('lib'))

);gulp.series('babel')();

# package.json

, "devdependencies":

}

執行命令:

npm run build
結果:

# lib/index.js

"use strict";

object.defineproperty(exports, "__esmodule", );

exports.default = void 0;

var _print = _interoprequiredefault(require("./print"));

function _interoprequiredefault(obj) ; }

(0, _print.default)('index');

var _default = _print.default;

exports.default = _default;

# lib/print.js

"use strict";

object.defineproperty(exports, "__esmodule", );

exports.default = void 0;

var _default = str => ;

exports.default = _default;

這種機制一般是通過對noderequire機制進行hook,劫持require抓取的原始檔**,把源**轉碼成commonjs規範之後,再傳送給require機制原本的**流中。

pirates 之類的第三方npm包提供了這種新增hook的功能。

babel-register 便是使用這種方式達到node執行es6模組檔案的目的的。

示例目錄:

- package.json

- src/

- entry.js # 這裡多了乙個入口檔案,專門用於註冊 babel-register

- index.js

- print.js

- ...

# package.json

, "devdependencies":

}# src/entry.js # 入口檔案必須使用 commonjs 規範來寫,因為還沒有註冊 hook

require('@babel/register')();

require('./index');

# src/index.js

import print from './print';

print('index');

# src/print.js

export default str => ;

執行:

npm run run
結果:

# 命令列列印

print: index

這種方式因為中間轉碼會有額外的效能損耗,所以不建議在生產環境下使用,只建議在開發模式下使用。

babel-node 對 babel-register 進行了封裝,提供了在命令列直接執行es6模組檔案的便捷方式。

示例目錄:

- package.json

- src/

- index.js

- print.js

- ...

# package.json

, "devdependencies":

}# src/index.js

import print from './print';

print('index');

# src/print.js

export default str => ;

執行:

npm run run
結果:

# 命令列列印

print: index

這種方式也不建議在生產環境下使用,只建議在開發模式下使用。

到寫這篇文章為止,已發布了ecmascript 2018

更多部落格,檢視

如何讓引入ES6的html檔案執行起來

這段時間,學習了一點關於es6新規範的知識,然後心血來潮,想嘗試一下用es6編寫的 在瀏覽器中跑起來。說幹就幹,先說下我的實現步驟 沒想到有坑!把es6 轉譯成es5 html檔案引入轉譯後的es5 然後在瀏覽器環境中執行 在node環境中執行 然後下面是我的一些目錄結構,大致預覽一下。src,es...

es6模組暴露

es6模組匯入和匯出 匯出 export,export default 可以匯出變數,函式,物件,檔案,模組 匯入 import function add 1 export add 匯入 import from add.js 匯入時要加,呼叫 add 可以匯出多個,加 export export a...

es6模組命令

es6的模組命令分為export命令和import命令,其中export命令用於匯出變數,import命令用於引入變數。1.1a檔案 export var name name export var age 1 以上a檔案中使用export命令匯出了name和age變數。下面,將在b檔案中使用impo...