Window not defined error при использовании extract-text-webpack-plugin React

Я использую webpack для создания своих реагирующих компонентов, и я пытаюсь использовать extract-text-webpack-plugin для разделения моего css из моего сгенерированного js файла. Однако, когда я пытаюсь построить компонент, я получаю следующую ошибку: Module build failed: ReferenceError: window is not defined.

Мой файл webpack.config.js выглядит следующим образом:

var webpack = require('webpack');
var ExtractTextPlugin = require('extract-text-webpack-plugin');

module.exports = {
  entry: {
    MainComponent: './src/main.js'
  },
  output: {
    libraryTarget: 'var',
    library: 'MainComponent',
    path: './build',
    filename: '[name].js'
  },
  module: {
    loaders: [{
      test: /\.css$/, loader: ExtractTextPlugin.extract('style-loader!css-loader')
    }]
  },
  plugins: [
    new ExtractTextPlugin('styles.css')
  ]
}

Ответ 1

Вы можете использовать style-loader как аргумент before в extract.

Здесь встроенная реализация:

    ExtractTextPlugin.extract = function(before, loader, options) {
        if(typeof loader === "string") {
            return [
                ExtractTextPlugin.loader(mergeOptions({omit: before.split("!").length, extract: true, remove: true}, options)),
                before,
                loader
            ].join("!");
        } else {
            options = loader;
            loader = before;
            return [
                ExtractTextPlugin.loader(mergeOptions({remove: true}, options)),
                loader
            ].join("!");
        }
    };

Итак, основное, что вам нужно сделать:

{
    test: /\.sass$/,
    exclude: /node_modules/,
    loader: ExtractTextPlugin.extract('style-loader', 'css!sass?indentedSyntax=true&sourceMap=true')
},

если вы используете, например, sass.

Ответ 2

Не видел объяснения причины, поэтому я разместил здесь этот ответ.

Из https://github.com/webpack/extract-text-webpack-plugin#api

ExtractTextPlugin.extract([notExtractLoader], loader, [options])Создает экстрактор-загрузчик из существующего загрузчика.

notExtractLoader (необязательно) загрузчик (ы), который должен использоваться, когда css не извлекается (т.е. в > дополнительном фрагменте, когда allChunks: false)

loader загрузчик (-ы), который должен использоваться для преобразования ресурса в модуль экспорта css.

options

publicPath переопределить параметр publicPath для этого загрузчика.

Метод #extract должен получить загрузчик, который выводит css. Случилось то, что он получал style-loader, который выводит код javascript, который предназначен для ввода на веб-страницу. Этот код попытается получить доступ к window.

Вы не должны передавать строку загрузчика с style до #extract. Однако... если вы установите allChunks=false, то он не будет создавать файлы CSS для не начальных фрагментов. Поэтому он должен знать, какой загрузчик использовать для ввода на страницу.

Совет. Webpack - это инструмент, который действительно нужно понимать в глубину или вы можете столкнуться с множеством странных проблем.

Ответ 3

Webpack 2

Если вы используете Webpack 2, этот вариант работает:

    rules: [{
        test: /\.css$/,
        exclude: '/node_modules/',
        use: ExtractTextPlugin.extract({
            fallback: [{
                loader: 'style-loader',
            }],
            use: [{
                loader: 'css-loader',
                options: {
                    modules: true,
                    localIdentName: '[name]__[local]--[hash:base64:5]',
                },
            }, {
                loader: 'postcss-loader',
            }],
        }),
    }]

Новый метод извлечения больше не принимает три аргумента и указан как изменение разрыва при переходе с V1 на V2.

https://webpack.js.org/guides/migrating/#extracttextwebpackplugin-breaking-change

Ответ 4

Я выяснил решение моей проблемы:

Вместо того, чтобы переставлять погрузчики друг в друга (ExtractTextPlugin.extract('style-loader!css-loader')), вы должны передать в каждом загрузчике отдельный параметр: ExtractTextWebpackPlugin.extract('style-loader', 'css-loader')