Babel 6 改变了它默认导出的方式
Babel 6 changes how it exports default
之前,babel 会添加行 module.exports = exports["default"]
。它不再这样做。这意味着在我可以做之前:
var foo = require('./foo');
// use foo
现在我必须这样做:
var foo = require('./foo').default;
// use foo
没什么大不了的(我猜这一直都是应该的)。
问题是我有很多代码取决于过去的工作方式(我可以将大部分代码转换为 ES6 导入,但不是全部)。任何人都可以给我提示如何使旧方法工作而不必通过我的项目并解决这个问题(或者甚至一些关于如何编写 codemod 来执行此操作的说明会非常巧妙)。
谢谢!
示例:
输入:
const foo = {}
export default foo
使用 Babel 5 输出
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var foo = {};
exports["default"] = foo;
module.exports = exports["default"];
使用 Babel 6(和 es2015 插件)的输出:
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var foo = {};
exports["default"] = foo;
请注意,输出中的唯一区别是 module.exports = exports["default"]
。
编辑
您可能对我在解决我的具体问题后写的这篇博文感兴趣:Misunderstanding ES6 Modules, Upgrading Babel, Tears, and a Solution
如果你想要 CommonJS 导出行为,你需要直接使用 CommonJS(或使用其他答案中的插件)。此行为已被删除,因为它会引起混淆并导致无效的 ES6 语义,而某些人曾依赖它,例如
export default {
a: 'foo'
};
然后
import {a} from './foo';
这是无效的 ES6,但由于您描述的 CommonJS 互操作性行为而有效。不幸的是,不可能同时支持这两种情况,允许人们编写无效的 ES6 比让你这样做更糟糕 .default
.
另一个问题是,如果用户以后添加命名导出,例如
export default 4;
然后
require('./mod');
// 4
但是
export default 4;
export var foo = 5;
然后
require('./mod')
// {'default': 4, foo: 5}
对于库作者,您或许可以解决此问题。
我通常有一个入口点,index.js
,这是我从package.json
中的主字段指向的文件。除了重新导出 lib 的实际入口点外,它什么都不做:
export { default } from "./components/MyComponent";
为了解决 babel 问题,我将其更改为 import
语句,然后将默认值分配给 module.exports
:
import MyComponent from "./components/MyComponent";
module.exports = MyComponent;
我的所有其他文件都保留为纯 ES6 模块,没有变通办法。所以只有入口点需要稍微改变:)
这适用于 commonjs 要求,也适用于 ES6 导入,因为 babel 似乎没有放弃反向互操作(commonjs -> es6)。 Babel 注入以下函数来修补 commonjs:
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
我已经花了几个小时来解决这个问题,所以我希望这可以节省其他人的精力!
您还可以使用 this plugin 恢复旧的 export
行为。
我遇到过这样的问题。这是我的解决方案:
//src/arithmetic.js
export var operations = {
add: function (a, b) {
return a + b;
},
subtract: function (a, b) {
return a - b;
}
};
//src/main.js
import { operations } from './arithmetic';
let result = operations.add(1, 1);
console.log(result);
之前,babel 会添加行 module.exports = exports["default"]
。它不再这样做。这意味着在我可以做之前:
var foo = require('./foo');
// use foo
现在我必须这样做:
var foo = require('./foo').default;
// use foo
没什么大不了的(我猜这一直都是应该的)。 问题是我有很多代码取决于过去的工作方式(我可以将大部分代码转换为 ES6 导入,但不是全部)。任何人都可以给我提示如何使旧方法工作而不必通过我的项目并解决这个问题(或者甚至一些关于如何编写 codemod 来执行此操作的说明会非常巧妙)。
谢谢!
示例:
输入:
const foo = {}
export default foo
使用 Babel 5 输出
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var foo = {};
exports["default"] = foo;
module.exports = exports["default"];
使用 Babel 6(和 es2015 插件)的输出:
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var foo = {};
exports["default"] = foo;
请注意,输出中的唯一区别是 module.exports = exports["default"]
。
编辑
您可能对我在解决我的具体问题后写的这篇博文感兴趣:Misunderstanding ES6 Modules, Upgrading Babel, Tears, and a Solution
如果你想要 CommonJS 导出行为,你需要直接使用 CommonJS(或使用其他答案中的插件)。此行为已被删除,因为它会引起混淆并导致无效的 ES6 语义,而某些人曾依赖它,例如
export default {
a: 'foo'
};
然后
import {a} from './foo';
这是无效的 ES6,但由于您描述的 CommonJS 互操作性行为而有效。不幸的是,不可能同时支持这两种情况,允许人们编写无效的 ES6 比让你这样做更糟糕 .default
.
另一个问题是,如果用户以后添加命名导出,例如
export default 4;
然后
require('./mod');
// 4
但是
export default 4;
export var foo = 5;
然后
require('./mod')
// {'default': 4, foo: 5}
对于库作者,您或许可以解决此问题。
我通常有一个入口点,index.js
,这是我从package.json
中的主字段指向的文件。除了重新导出 lib 的实际入口点外,它什么都不做:
export { default } from "./components/MyComponent";
为了解决 babel 问题,我将其更改为 import
语句,然后将默认值分配给 module.exports
:
import MyComponent from "./components/MyComponent";
module.exports = MyComponent;
我的所有其他文件都保留为纯 ES6 模块,没有变通办法。所以只有入口点需要稍微改变:)
这适用于 commonjs 要求,也适用于 ES6 导入,因为 babel 似乎没有放弃反向互操作(commonjs -> es6)。 Babel 注入以下函数来修补 commonjs:
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
我已经花了几个小时来解决这个问题,所以我希望这可以节省其他人的精力!
您还可以使用 this plugin 恢复旧的 export
行为。
我遇到过这样的问题。这是我的解决方案:
//src/arithmetic.js
export var operations = {
add: function (a, b) {
return a + b;
},
subtract: function (a, b) {
return a - b;
}
};
//src/main.js
import { operations } from './arithmetic';
let result = operations.add(1, 1);
console.log(result);