Javascript 制作网页包';s库输出与babel6兼容

Javascript 制作网页包';s库输出与babel6兼容,javascript,ecmascript-6,webpack,babeljs,Javascript,Ecmascript 6,Webpack,Babeljs,的第6个版本更改了导出默认值的功能,特别是它与commonjsrequire的关系 总之,在babel5之前,require('module')提供模块的默认导出,现在它总是返回包含模块所有导出的模块对象。 如果只需要默认值,则必须使用require('module')。默认值。 这个问题的目的不是要破坏或破坏这种行为 但是,如果一个人正在构建一个库,他/她通常不希望分发模块,而是希望分发其库的导出值(例如,函数,内部使用的任何模块系统)。 当使用或时,output.library配置可以很好地

的第6个版本更改了导出默认值的功能,特别是它与commonjs
require
的关系

总之,在babel5之前,
require('module')
提供模块的默认导出,现在它总是返回包含模块所有导出的模块对象。 如果只需要默认值,则必须使用
require('module')。默认值
。 这个问题的目的不是要破坏或破坏这种行为

但是,如果一个人正在构建一个库,他/她通常不希望分发模块,而是希望分发其库的导出值(例如,函数,内部使用的任何模块系统)。 当使用或时,
output.library
配置可以很好地处理这一问题。因为之前的babel版本允许commonjs需要默认导出,所以babel也与此机制兼容。然而,情况不再如此:库现在总是提供es6模块对象

这里有一个例子

src/main.js

export default "my lib content";
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'] }
      }
    ]
  }
};
webpack.config.js

export default "my lib content";
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>
然而,我发现这个解决方案很差。人们应该能够在编译级别解决它,而无需更改源代码。 有什么想法吗?

您可以使用此解决方案(这更像是一种变通方法,但它允许您保持源代码不变):

有一个加载程序叫做。它允许您在构建时通过调用回调并放置结果来更改源代码。换句话说,您可以将所有
require('module')
转换为
require('module')。默认值是在构建时自动转换的

以下是您的配置:

var webpackConfig = {
    module: {
        loaders: [
            { test: /\.js$/, exclude: /node_modules/, loader: 'callback' },
            ...
        ]
    },
    ...
    callbackLoader: {
        require: function() {
            return 'require("' + Array.prototype.join.call(arguments, ',') + '").default';
        }
    }
};

我自己就这么做了。无论你喜欢称之为变通方法还是解决方案,似乎有一个巴别塔插件“解决它”

使用中引用的插件

示例配置

var webpackOptions = {
    entry: {
        Lib1: './src/Lib1.js',
        Lib2: './src/Lib2.js'
    },
    output: {
        filename: "Master.[name].js",
        library: ["Master","[name]"],
        libraryTarget: "var"
    },
    module: {
        loaders: [
            {
                loader: 'babel',
                query: {
                    presets: ['es2015'],
                    plugins: ["add-module-exports"]
                }
            }
        ]
    }
};
这使得
Master.Lib1
成为Lib1,而不是
Master.Lib1。默认值现在支持es6模块,部分解决了此问题。这是相对无痛的。我们只需要记住要让这一切顺利进行:

.babelrc

{
  "presets": [
    ["es2015", {"modules": false}]
  ]
}
然而,不幸的是,它不能在导出默认值下正常工作(但是,希望最终会发布一个解决方案)

编辑

好消息!Webpack 3支持可用于直接公开默认导出的选项:

var path = require("path");
var webpack = require("webpack");

module.exports = {
  entry: {
    lib: [ path.resolve(__dirname, "src/main.js") ],
  },
  output: {
    path: path.resolve(__dirname, "dist"),
    filename: "mylib-build.js",
    library: "myLib",
    // Expose the default export.
    libraryExport: "default"
  },
  module: {
    loaders: [
      {
        test: /\.js$/,
        loader: "babel",
        include: path.resolve(__dirname, "src")
      }
    ]
  }
};

“一个人应该能够通过编译选项来解决这个问题,而不必更新源代码。你知道吗?”我不太确定你希望得到什么样的答案。如果您认为这应该是一个编译选项,那么您应该向开发人员建议。Webpack配置非常强大。有许多不同的插件,所有加载程序都有许多不同的参数。例如,如果一个人只使用默认导出,他可能会使用所有es6包并将其转换为commonjs。你将以错误的方式进行。巴贝尔改变了它的行为,使之更符合规范,你想再次破坏它。现在,您可以在ES6和CommonJS之间建立一个隐式的桥梁。那东西
module.exports=require('./main')。默认值
,导致的错误和WTF更少,而不是以前鬼鬼祟祟的
module.exports=exports。默认值
@vvo还没有。。。所以我不得不使用导出解决方案为webpack提供一个commonjs模块。很抱歉,它不起作用。这改变了模块的加载方式,而不是导出方式。我想这是一个足够好的解决方法。但是,我认为它应该只适用于入口点。完全恢复巴别塔的旧行为似乎是个坏主意。