'Webpack: How to export directly to global (without .default) containing stylesheet imports?
Context
I have a webpack.config.js like this:
/* Something here */
module.exports = {
entry: {
main: './src/index.js'
},
output: {
library: 'MyClass',
libraryTarget: 'umd',
path: path.resolve(__dirname, 'lib'),
filename: `package.js`
},
...
}
My ./src/index.js looks like this:
import MyClass from 'src/myClass'
import 'src/myStyle.css'
export default MyClass
Problem
While this works fine, it exposes MyClass class to window object as:
console.log(window.MyClass)
=> Module {default: ƒ, __esModule: true, Symbol(Symbol.toStringTag): "Module"}
This way, I cannot invoke my class by using:
new MyClass();
=> TypeError: MyClass is not a constructor
I have to invoke it like:
new MyClass.default();
=> MyClass { ... }
I can solve the problem by doing something like this in my ./src/index.js:
const MyClass = require('src/myClass')
module.exports = MyClass
/* in browser */
new MyClass()
=> Good, works fine
However, this way, I cannot import my stylesheet:
const MyClass = require('src/myClass')
import 'src/myStyle.css'
module.exports = MyClass
=> TypeError: Cannot assign to read only property 'exports' of object '#<Object>'
Edit
The following way also solves the problem, but is done without an export:
/* webpack.config.js */
module.exports = {
entry: {
main: './src/index.js'
},
output: {
/* Need to remove library related props */
// library: 'MyClass',
// libraryTarget: 'window',
path: path.resolve(__dirname, 'lib'),
filename: `package.js`
},
...
}
/* ./src/index.js */
import MyClass from 'src/myClass'
import 'src/myStyle.css'
window.MyClass = MyClass
Question
Is there a way in Webpack for me to export a module directly to global without having to invoke with .default and at the same time import a stylesheet in the entry file?
Solution 1:[1]
Use output.libraryExport in your webpack.config.js. (ref)
Along with output.libraryTarget set to umd, output.libraryExport tells Webpack which property to be exported as the global variable named by the output.library.
In your case, in addition to your original configuration, set output.libraryExport to default is equivalence to append the following snippet after your compiled code.
window.MyClass /*output.library*/ = module.exports.default /*output.libraryExport*/
The configuration will be as follows.
/* Something here */
module.exports = {
entry: {
main: './src/index.js'
},
output: {
library: 'MyClass',
libraryTarget: 'umd',
libraryExport: 'default', // export the default as window.MyClass
path: path.resolve(__dirname, 'lib'),
filename: `package.js`
}
}
Have a try in the console.
> window.MyClass
class {...}
Solution 2:[2]
If your script is only designed to run in the web browser only why not just update window explicitly:
import MyClass from 'src/myClass'
import 'src/myStyle.css'
window.MyClass = MyClass;
I think this is a lot clearer than using indirection.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | momocow |
| Solution 2 | Andrew Skirrow |
