Babel 6更改了导出默认值的方式

ken*_*dds 193 commonjs ecmascript-6 babeljs

之前,巴贝尔会添加这条线module.exports = exports["default"].它不再这样做了.在我能做之前,这意味着什么:

var foo = require('./foo');
// use foo
Run Code Online (Sandbox Code Playgroud)

现在我必须这样做:

var foo = require('./foo').default;
// use foo
Run Code Online (Sandbox Code Playgroud)

这不是什么大不了的事(我猜它应该一直都是这样).问题是我有很多代码依赖于以前的工作方式(我可以将大部分代码转换为ES6导入,但不是全部转换).任何人都可以给我提示如何使旧的方式工作,而不必通过我的项目并解决这个问题(甚至一些关于如何编写codemod来做这个的说明将是非常光滑的).

谢谢!

例:

输入:

const foo = {}
export default foo
Run Code Online (Sandbox Code Playgroud)

使用Babel输出5

"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
var foo = {};
exports["default"] = foo;
module.exports = exports["default"];
Run Code Online (Sandbox Code Playgroud)

使用Babel 6(和es2015插件)输出:

"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
var foo = {};
exports["default"] = foo;
Run Code Online (Sandbox Code Playgroud)

请注意,输出的唯一区别是module.exports = exports["default"].


编辑

您可能对我在解决我的具体问题后写的博客文章感兴趣:误解ES6模块,升级Babel,眼泪和解决方案

log*_*yth 105

如果你想要CommonJS导出行为,你需要直接使用CommonJS(或者在另一个答案中使用插件).此行为已被删除,因为它导致混淆并导致无效的ES6语义,这是一些人依赖的例如

export default {
  a: 'foo'
};
Run Code Online (Sandbox Code Playgroud)

然后

import {a} from './foo';
Run Code Online (Sandbox Code Playgroud)

这是无效的ES6,但由于您正在描述的CommonJS互操作性行为而起作用.不幸的是,支持这两种情况是不可能的,并且允许人们编写无效的ES6是一个比让你做的更糟糕的问题.default.

另一个问题是,如果用户将来添加了一个命名导出,那么用户就会出乎意料

export default 4;
Run Code Online (Sandbox Code Playgroud)

然后

require('./mod');
// 4
Run Code Online (Sandbox Code Playgroud)

export default 4;
export var foo = 5;
Run Code Online (Sandbox Code Playgroud)

然后

require('./mod')
// {'default': 4, foo: 5}
Run Code Online (Sandbox Code Playgroud)

  • @kentcdodds我们可以写一个webpack加载器来保持这个工作(或一个babel插件).我很惊讶他们没有提供一个(或更多地宣传变化!) (4认同)

Sim*_*enB 89

您还可以使用此插件export恢复旧的行为.

  • 我用[babel-plugin-transform-es2015-modules-simple-amd](https://www.npmjs.com/package/babel-plugin-transform-es2015-modules-simple-amd)来解决这个问题同样的问题在我的项目中有AMD模块 (2认同)

Wic*_*ams 33

对于图书馆作者,您可以解决此问题.

我通常有一个入口点,index.js这是我在主域中指向的文件package.json.除了重新导出lib的实际入口点之外,它什么也没做:

export { default } from "./components/MyComponent";
Run Code Online (Sandbox Code Playgroud)

要解决babel问题,我将其更改为import语句,然后将默认值分配给module.exports:

import MyComponent from "./components/MyComponent";
module.exports = MyComponent;
Run Code Online (Sandbox Code Playgroud)

我的所有其他文件都保留为纯ES6模块,没有解决方法.所以只有入口点需要稍微改变:)

这将适用于commonjs需求,也适用于ES6导入,因为babel似乎没有丢弃反向互操作(commonjs - > es6).Babel注入以下函数来修补commonjs:

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 
Run Code Online (Sandbox Code Playgroud)

我花了好几个小时与此作斗争,所以我希望这可以节省别人的努力!