admin管理员组

文章数量:1024016

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?

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?

Share Improve this question edited Apr 14, 2022 at 17:59 yqlim asked May 2, 2019 at 15:57 yqlimyqlim 7,1183 gold badges20 silver badges44 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 6

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 piled 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 {...}

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.

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?

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?

Share Improve this question edited Apr 14, 2022 at 17:59 yqlim asked May 2, 2019 at 15:57 yqlimyqlim 7,1183 gold badges20 silver badges44 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 6

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 piled 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 {...}

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.

本文标签: