How to expose an es6 module globally
Solution 1
You should combine export default class Foo
with the library
and libraryTarget
settings in Webpack's config. Something like:
// src/Foo.js
export default class Foo { ... }
// webpack.config.json
{
"output": {
"library": "Foo",
"libraryTarget": "var"
}
}
You should be able to use the library as window.Foo
once the bundle has been loaded.
Solution 2
This is basically the same issue as Exporting a class with Webpack and Babel not working , except that you have a named export instead of a default export. Your entry file should be
import {MyMod} from './mymod';
module.exports = MyMod;
or
module.exports = require('./mymod').MyMod;
If you don't want to do any of these and keep './src/mymod.js'
as entry file, use a CommonJS export instead of an ES6 export in that file:
// mymod.js
exports.MyMod = class MyMod {
constructor(aaa) {
this.aaa = aaa;
}
toString() {
return this.aaa;
}
}
Related videos on Youtube
bldoron
Updated on September 15, 2022Comments
-
bldoron over 1 year
I need to write a module that will be available on the window global.
I'm using es6 to create the module and every single class I define has it's own file.
I'm using webpack to babelify and bundle these classes.
The entry point of my module is also the file containing the global to be exposed.I've tried every method to make this possibe, icluding:
- expose-loader
- import-loader
- expoert-loader
- output: library
- black-magic :(
Example of code I've tried:
I want to get: window.MyMod
// mymod.js export class MyMod { constructor(aaa) { this.aaa = aaa; } toString() { return this.aaa; } }
// webpack.config var entries = [ './src/mymod.js' ]; module.exports = { ..., module: { loaders: [ { test: require.resolve('./src/mymod.js'), loader: 'expose?MyMod' }, { test: /\.js$/, exclude: /node_modules/, loader: 'babel-loader', query: { presets: ['es2015'] } } ] }
This only gets me an object MyMod on the window that contains MyMod as a constructor.
Any help will be appreciated.
-
Felix Kling over 7 yearsYou might want to be more specific, otherwise it's not possible to help you.
-
bldoron over 7 yearsSorry, you're correct. Your first solution is impossible, because i'm not importing the file anywhere, I need it to be built. The second one, I did try, but this:
require.resolve('./src/mymod.js')
and thisrequire.resolve('./src/mymod.js').MyMod
resulted in the same window.MyMod.MyMod. -
bldoron over 7 yearsTried that, it didn't work. Resulted in an empty window.Foo object
-
Felix Kling over 7 years"Your first solution is impossible, because i'm not importing the file anywhere," I said you have to create a new entry file with that content, instead of using
./src/mymod.js
as entry file. I.e. create a file./src/entry.js
with the content from my answer and configure webpack to use that:var entries = [ './src/entry.js'];
-
bldoron over 7 yearsI've been trying to avoid that, it sounds like a hack. I think I'll do what jquery did and somehow wrap the class in an anonymous self invoking function returning MyMod. I'll report back with this try- though it also is a hack.
-
Felix Kling over 7 yearsWell, you are trying to make ES6 modules work together with a tool that is built for CommonJS modules. If you don't want use any of the suggestions and keep
./src/mymod.js
as entry file then you should use a CommonJS module definition instead of ES6:exports.MyMod = class MyMod {};
. Implementing a wrapper like jQuery does is completely unnecessary because that's exactly what webpack does for you. -
ssube over 7 years@bldoron did you set the
entry
in your config as well? I think that may be necessary to get a reliable global var. -
bldoron over 7 yearsWhat finally worked was: module.exports = class MyMod {...} and exposing it as I did: test: require.resolve('./src/mymod.js'), loader: 'expose?MyMod'
-
Jacob Phillips over 5 years@bidoron can you write an answer that sums up how to do this? All I get is an empty global var.