With Rollup I can output an ES module by simply setting the format
option to 'es'
. How can I do the same with webpack? If it's not possible now, does webpack have any plans to add it?
The only thing I've found in the documentation for output.libraryTarget
that mentions ES modules is this:
libraryTarget: "commonjs-module"
- Expose it using themodule.exports
object (output.library
is ignored),__esModule
is defined (it's threaded as ES2015 Module in interop mode)
However, it's rather unclear to me. Is it the same as libraryTarget: "commonjs2"
with the only difference that __esModule
is defined? What is "interop mode"?
Firstly I would like to state the difference between the commonJS
and commonJS2
CommonJS
doesn't support the use of module.exports = function() {}
which is used by node.js
and many other commonJS
implementations.
Webpack2
employs the concept of the bundling the library code and for the widespread use of it and to make it compatible of working in different environments we use the --libraryTarget option
Now the part here will answer both your questions
The possible library options supported in webpack2
are
libraryTarget: "umd", // enum
libraryTarget: "umd-module", // ES2015 module wrapped in UMD
libraryTarget: "commonjs-module", // ES2015 module wrapped in CommonJS
libraryTarget: "commonjs2", // exported with module.exports
libraryTarget: "commonjs", // exported as properties to exports
libraryTarget: "amd", // defined with AMD defined method
libraryTarget: "this", // property set on this
libraryTarget: "var", // variable defined in root scope
Interlop has the following meaning
In order to encourage the use of CommonJS and ES6 modules, when exporting a
default export
with no otherexports
module.exports
will be set in addition toexports["default"]
as shown in the following example
export default test;
exports["default"] = test;
module.exports = exports["default"];
So basically it means that the commonJS-module
can be used by exposing it as module.exports
by using the interloping
with ES2015 module wrapped in commonJS
More info about the interloping
can be found in this blogpost and the stackoverflow link to it.
The basic idea is in ES6
runtime export and import properties cannot be changed but in commonJS
this works fine as the require changes happen at runtime therefore it has ES2015 is interloped with the commonJS.
Update
Webpack 2 gives the option of creating the library which can be bundled and included.
If you want your module to be used in different environments then you can bundle it as a library by adding the library options and output it to your specific environment. Procedure mentioned in the docs.
Another simple example on how to use commonjs-module
Important point to note here is babel
adds exports.__esModule = true
to each es6 module
and on importing it calls for the _interopRequire
to check that property.
__esModule = true
need to be set only on library export. It need to be set on the exports
of the entry module. Inner modules don't need __esModule
, it's just a babel hack.
As mentioned in the docs
__esModule
is defined (it's threaded as ES2015 Module in interop mode)
Usage as mentioned in the test cases
export * from "./a";
export default "default-value";
export var b = "b";
import d from "library";
import { a, b } from "library";