【发布时间】:2016-02-14 05:10:40
【问题描述】:
Babel 的第 6 版更改了 export default 的功能,尤其是它与 commonjs require 的关系。
总结一下,直到 babel5,require('module') 给出模块的默认导出,它现在总是返回包含模块所有导出的模块对象。
如果只想要默认值,他/她必须使用require('module').default。
As explained here, there is very good reasons behind this,这个问题的目的不是破坏或破解这种行为。
但是,如果一个人正在构建一个库,他/她通常不想分发一个模块,而是他的库的导出值(例如,一个函数,无论内部使用什么模块系统)。
当使用commonjs 或AMD 时,webpack 和output.library 配置可以很好地解决这个问题。因为之前的 babel 版本允许 commonjs 需要默认导出,所以 babel 也兼容这种机制。然而现在已经不是这样了:这个库现在总是提供一个 es6 模块对象。
这是一个例子。
src/main.js
export default "my lib content";
webpack.config.js
var path = require("path");
var webpack = require("webpack");
module.exports = {
entry: {
lib: [ path.resolve(__dirname, "src/main.js") ],
},
output: {
path: path.join(__dirname, "dist"),
filename: "mylib-build.js",
library: 'myLib'
},
module: {
loaders: [
{
test: /\.js$/,
loader: "babel",
include: path.join(__dirname, "src"),
query: { presets: ['es2015'] }
}
]
}
};
test.html
<html>
<head></head>
<body>
<script src="dist/mylib-build.js"></script>
<!-- `myLib` will be attached to `window` -->
<script>
console.log(JSON.stringify(myLib)); // { default: "my lib content" }
</script>
</body>
</html>
这是一个非常简单的示例,但我显然希望 mylib 的导出为字符串 "my lib content" 而不是 { default: "my lib content" }。
一种解决方案是在 commonjs 中创建一个导出源文件来执行转换:
module.exports = require('./main').default;
但是我发现这个解决方案很差。应该能够在编译级别解决它,而无需更改源代码。 有什么想法吗?
【问题讨论】:
-
“应该能够解决它有一个编译选项,而无需更新源代码。有什么想法吗?” 不太确定您期望什么样的答案。如果您认为这应该是一个编译选项,那么您应该向开发人员推荐它。
-
Webpack 配置非常强大。所有加载器都有许多不同的插件和许多不同的参数。
-
例如,如果一个人只使用默认导出,他可以使用babel-plugin-transform-es2015-modules-commonjs并将他所有的es6包转换为commonjs。
-
您将以错误的方式进行操作。 Babel 改变了它的行为以更符合规范,你想再次打破它。现在你可以在 ES6 和 CommonJS 之间建立一个隐式的桥梁。那件事
module.exports = require('./main').default,导致更少的错误和WTF,而不是以前偷偷摸摸的module.exports = exports.default -
@vvo 不幸的是还没有......所以我不得不使用导出解决方案来给 webpack 一个 commonjs 模块。
标签: javascript ecmascript-6 webpack babeljs