babel6はCommonJSに対応しないので、コンパイル済みのコードにmodule.exports
(requireのエントリポイント)が含まれません。これは、transform-es2015-modules-commonjsプラグインを使っても改善しませんでした。issueもしょっちゅう立ってはLockされてます。
add-module-exportsプラグインというものを作成しました。これはコード末尾にmodule.exports
文を加えます。
npm install babel-cli --save-dev
npm install babel-preset-es2015 --save-dev
npm install babel-plugin-add-module-exports --save-dev
0.1.*
系
babel@5
の動作に準拠するバージョン0.1.0
を公開しました。
このバージョンでは、export default
文のみを使用した場合にだけ、module.exports
文を追加します。
export default 'foo'
上記はmodule.exports
文を追加します。
babel index.js --presets es2015 --plugins add-module-exports
# 'use strict';
#
# Object.defineProperty(exports, "__esModule", {
# value: true
# });
# exports.default = 'foo';
# module.exports = exports['default'];
下記は追加しません。
let foo= 'bar'
export default 'baz'
export {foo}
babel index.js --presets es2015 --plugins add-module-exports
# 'use strict';
#
# Object.defineProperty(exports, "__esModule", {
# value: true
# });
# var foo = 'bar';
# exports.default = 'baz';
# exports.foo = foo;
0.0.*
系
常にmodule.exports
文を発行します。Object.assign
でマージするため、動作は破壊的です。
let foo= 'bar'
export default 'baz'
export {foo}
下記のように変換されるでしょう。
babel index.js --presets es2015 --plugins add-module-exports
# 'use strict';
#
# Object.defineProperty(exports, "__esModule", {
# value: true
# });
# var foo = 'bar';
# exports.default = 'baz';
# exports.foo = foo;
# module.exports = Object.assign(exports.default || {}, exports);
Object.assignを使用したくない場合は、polyfillに置換できるプラグインが用意されているので、これを利用して下さい。
参考
よもやま話
babel@6からプラグインの作成方法も変わったらしく、ハローワールド的な記事を探しても、5系のものがほとんどでした。その中、頼りになるのは公式の似た目的を持つプラグインの実装と日本語の5系の解説記事でした。
例えば拙作のプラグインでは、babel-templateというsebmck製モジュールに依存していますが、これは文字列からASTの生成関数を返すファクトリ関数です。
var babelTemplate= require('babel-template')
babelTemplate('var hoge="fuga"')()
// { type: 'VariableDeclaration',
// start: undefined,
// end: undefined,
// loc: undefined,
// declarations:
// [ { type: 'VariableDeclarator',
// start: undefined,
// end: undefined,
// loc: undefined,
// id: [Object],
// init: [Object],
// _fromTemplate: true } ],
// kind: 'var',
// _fromTemplate: true }
プラグインのエントリポイントは以下のようなオブジェクトを返すのが決まりですが、visitor内のトランスフォーム関数の第一引数path
がAST改変用のメソッド群を持つので、これの.pushContainer('body')
にASTの配列を渡すと、オレオレコードを追加することができました。
// Dependencies
var babelTemplate= require('babel-template')
// Public
module.exports= function(){
return {
visitor: {
Program: {
exit: function(path){
var topNodes= []
var code= 'module.exports=Object.assign(exports.default||{},exports);'
var node= babelTemplate(code)()
topNodes.push(node)
path.pushContainer('body',topNodes)// プログラム末尾に`module.exports = Object.assign(exports.default || {}, exports);`を追加する
},
},
},
}
}