Pesquisa de site

javascript - Webpack: Como exportar diretamente para o global (sem .default) contendo importações de estilos?


Contexto

Eu tenho um webpack.config.js assim:

/* Something here */

module.exports = {
  entry: {
    main: './src/index.js'
  },
  output: {
    library: 'MyClass',
    libraryTarget: 'umd',
    path: path.resolve(__dirname, 'lib'),
    filename: `package.js`
  },
  ...
}

Meu ./src/index.js é assim:

import MyClass from 'src/myClass'
import 'src/myStyle.css'

export default MyClass

Problema

Embora isso funcione bem, ele expõe a classe MyClass ao objeto window da seguinte forma:

console.log(window.MyClass)
=> Module {default: ƒ, __esModule: true, Symbol(Symbol.toStringTag): "Module"}

Dessa forma, não posso invocar minha classe usando:

new MyClass();
=> TypeError: MyClass is not a constructor

Eu tenho que invocá-lo assim:

new MyClass.default();
=> MyClass { ... }

Posso resolver o problema fazendo algo assim no meu ./src/index.js:

const MyClass = require('src/myClass')
module.exports = MyClass

/* in browser */
new MyClass()
=> Good, works fine

No entanto, desta forma, não posso importar minha folha de estilos:

const MyClass = require('src/myClass')
import 'src/myStyle.css'

module.exports = MyClass
=> TypeError: Cannot assign to read only property 'exports' of object '#<Object>'

Editar

A seguinte maneira também resolve o problema, mas é feita sem um 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

Pergunta

Existe uma maneira no Webpack de eu exportar um módulo diretamente para o global sem ter que invocar com .default e ao mesmo tempo importar uma folha de estilos no arquivo de entrada?

Resposta #1

Use output.libraryExport em seu webpack.config.js. (ref)

Junto com output.libraryTarget definido como umd, output.libraryExport informa ao Webpack qual propriedade deve ser exportada como a variável global nomeada pelo output.library.

No seu caso, além da sua configuração original, definir output.libraryExport como default é equivalente a anexar o seguinte trecho após o seu código compilado.

window.MyClass /*output.library*/ = module.exports.default /*output.libraryExport*/

A configuração será a seguinte.

/* 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`
  }
}

Tente no console.

> window.MyClass
class {...}

Resposta #2

Se o seu script foi projetado para rodar apenas no navegador, por que não atualizar window explicitamente:

import MyClass from 'src/myClass'
import 'src/myStyle.css'

window.MyClass = MyClass;

Eu acho que isso é muito mais claro do que usar indireção.