помилка вікна не визначена при використанні 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')
  ]
}

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.

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

Порада: Webpack - це інструмент, який дійсно потрібно розуміти поглиблено, інакше ви можете зіткнутися з безліччю дивних питань.


Найкраще, що я коли-небудь чув про webpack.
Jide

вибачте за відсутність пояснення у моїй відповіді. Документи веб-пакета все ще писалися (і можуть все ще бути) на момент написання питання та відповіді. Але я погоджуюсь, що це потрібно досить добре розуміти.
Ganonside

1
Високоякісний контент тут. Якби документи були вдвічі нижчими від цього, я був би дуже щасливим програмістом.
Росіо Гарсія Луке

20

Веб-пакет 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')


8
Цілком впевнений, що це робив @squixy за 5 місяців до цього.
камерлен

3
Твердження "кожен навантажувач як окремий параметр" відповідає дійсності лише для двох навантажувачів і є помилковим для трьох і більше. extractФункція приймає три параметри: (before, loader, options)і ця відповідь кришки , які ідеально: stackoverflow.com/a/30982133/1346510
sompylasar

1
@sompylasar велике спасибі за цей коментар. Це вирішило мою проблему! Я припускав, що всі передані параметри будуть просто промальовані. Ми раді сказати, що якщо вам потрібно використовувати, 'style', 'css', 'sass'ви можете просто змінити його на 'style', 'css!sass'- Дякую!
Aleski

3
ЦЕ НЕПРАВИЛЬНО прочитайте вищезазначені коментарі або відповідь. Позначаючи це жирним шрифтом, оскільки хтось прочитає цю відповідь і не зрозуміє, чому ExtractTextPlugin не використовує всі їхні завантажувачі.
Дон П

Інші відповіді, здається, працюють для інших, але коли я опублікував запитання, це те, що мені підійшло, тому я позначив його.
Ganonside
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.