ошибка окна не определяется при использовании extract-text-webpack-plugin React

83

Я использую 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')
  ]
}
Ganonside
источник
5
я понял ответ. вместо ExtractTextPlugin.extract('style-loader!css-loader')того, чтобы писать,ExtractTextPlugin.extract('style-loader', 'css-loader')
Ganonside
3
Можете ли вы преобразовать это в ответ и отметить решенную проблему? Благодарю.
Юхо Вепсяляйнен
Я только что сделал. Прости за это.
Ganonside

Ответы:

60

Вы можете использовать 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.

Камиль Лелонек
источник
Это решило и для меня, работая со Stylus. Спасибо, @squixy!
Габриэль Годой
1
Если у вас проблема с scss not sass, удалите indentedSyntax = true
Роберт Леггетт
43

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

С 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.

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

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

Vaughan
источник
Лучшее, что я когда-либо слышал о webpack.
Jide
извините за то, что в моем ответе нет объяснения. Документы по веб-пакету еще писались (и, возможно, еще пишут) в то время, когда я разместил вопрос и ответ. Но я согласен, что это нужно хорошо понимать.
Ganonside
1
Здесь качественный контент. Если бы документы были наполовину так хороши, я был бы действительно счастливым программистом.
Росио Гарсиа Луке
20

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

Крис
источник
12

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

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

Ganonside
источник
8
Совершенно уверен, что это то, что @squixy сказал сделать 5 месяцев назад.
cchamberlain
3
Утверждение «каждый загрузчик как отдельный параметр» верно только для двух загрузчиков и неверно для трех и более. extractФункция принимает три параметра: (before, loader, options)и этот ответ крышки , которые идеально: stackoverflow.com/a/30982133/1346510
sompylasar
1
@sompylasar большое спасибо за этот комментарий. Это решило мою проблему! Я предполагал, что все переданные параметры будут просто пропущены. Рад сообщить, что если вам нужно использовать, 'style', 'css', 'sass'вы можете просто изменить его на 'style', 'css!sass'- Спасибо!
Алески
3
ЭТО НЕПРАВИЛЬНО прочтите приведенные выше комментарии или ответьте. Выделите это жирным шрифтом, потому что кто-то прочитает этот ответ и не поймет, почему ExtractTextPlugin не использует все свои загрузчики.
Don P
Другие ответы, похоже, работают для других, но когда я разместил вопрос, это сработало для меня, поэтому я отметил его.
Ganonside