Fenster nicht definiert Fehler bei Verwendung von Extract-Text-Webpack-Plugin React

82

Ich verwende Webpack, um meine Reaktionskomponenten zu erstellen, und ich versuche, extract-text-webpack-pluginmein CSS von meiner generierten JS-Datei zu trennen. Wenn ich jedoch versuche, die Komponente zu erstellen, wird der folgende Fehler angezeigt: Module build failed: ReferenceError: window is not defined .

Meine Datei webpack.config.js sieht folgendermaßen aus:

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
quelle
5
Ich habe die Antwort herausgefunden. anstatt dass ExtractTextPlugin.extract('style-loader!css-loader')Sie schreiben müssenExtractTextPlugin.extract('style-loader', 'css-loader')
Ganonside
3
Können Sie das in eine Antwort umwandeln und das gelöste Problem markieren? Vielen Dank.
Juho Vepsäläinen
Ich habe es gerade getan. Das tut mir leid.
Ganonside

Antworten:

59

Möglicherweise möchten Sie style-loaderals beforeArgument in der extractFunktion verwenden.

Hier ist die native Implementierung:

    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("!");
        }
    };

Grundsätzlich müssen Sie also Folgendes tun:

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

wenn Sie zum Beispiel verwenden sass.

Kamil Lelonek
quelle
Dies löste sich auch für mich bei der Arbeit mit Stylus auf. Danke @squixy!
Gabriel Godoy
1
Wenn Sie ein Problem mit scss not sass haben, entfernen Sie die indentedSyntax = true
Robert Leggett
43

Ich habe keine Erklärung für die Ursache gesehen, daher habe ich diese Antwort hier veröffentlicht.

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

ExtractTextPlugin.extract([notExtractLoader], loader, [options]) Erstellt einen extrahierenden Loader aus einem vorhandenen Loader.

notExtractLoader (optional) die Loader, die verwendet werden sollen, wenn das CSS nicht extrahiert wird (dh in einem> zusätzlichen Block, wenn allChunks: false)

loader die Loader, die zum Konvertieren der Ressource in ein CSS-Exportmodul verwendet werden sollen.

options

publicPath Überschreiben Sie die publicPath-Einstellung für diesen Loader.

Die #extractMethode sollte einen Loader erhalten, der ausgibt css. Was passierte war , dass es war ein Empfang , style-loaderdie Ausgänge JavaScript - Code , der in eine Webseite eingespritzt werden soll. Dieser Code würde versuchen, darauf zuzugreifenwindow .

Sie sollten keine Loader-Zeichenfolge mit styleto übergeben #extract. Jedoch ... wenn Sie einstellenallChunks=false , werden keine CSS-Dateien für nicht initiale Chunks erstellt. Daher muss bekannt sein, mit welchem ​​Loader die Seite eingefügt werden soll.

Tipp: Webpack ist ein Tool, das wirklich gründlich verstanden werden muss, da sonst viele seltsame Probleme auftreten können.

Vaughan
quelle
Die besten Dinge, die ich je über Webpack gehört habe.
Jide
Es tut mir leid, dass ich keine Erklärung in meiner Antwort habe. Die Webpack-Dokumente wurden zum Zeitpunkt der Veröffentlichung der Frage und Antwort noch geschrieben (und sind es möglicherweise noch). Aber ich stimme zu, dass es ziemlich gut verstanden werden muss.
Ganonside
1
Hochwertige Inhalte hier. Wenn die Dokumente halb so gut wären, wäre ich ein wirklich glücklicher Programmierer.
Rocío García Luque
20

Webpack 2

Wenn Sie Webpack 2 verwenden, funktioniert diese Variante:

    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',
            }],
        }),
    }]

Die neue Extraktionsmethode akzeptiert nicht mehr drei Argumente und wird beim Übergang von V1 zu V2 als wichtige Änderung aufgeführt.

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

Chris
quelle
12

Ich fand die Lösung für mein Problem heraus:

Anstatt die Lader ineinander zu leiten ( ExtractTextPlugin.extract('style-loader!css-loader')), müssen Sie jeden Lader als separaten Parameter übergeben:ExtractTextWebpackPlugin.extract('style-loader', 'css-loader')

Ganonside
quelle
8
Ich bin mir ziemlich sicher, dass @squixy dies 5 Monate zuvor getan hat.
Cchamberlain
3
Die Aussage "Jeder Lader als separater Parameter" gilt nur für zwei Lader und für drei oder mehr. Die extractFunktion nimmt drei Parameter an: (before, loader, options)und diese Antwort deckt das perfekt ab: stackoverflow.com/a/30982133/1346510
sompylasar
1
@sompylasar vielen Dank für diesen Kommentar. Es hat mein Problem gelöst! Ich nahm an, dass alle übergebenen Parameter nur gerade durchlaufen würden. Gerne sagen wir, dass Sie es bei Bedarf 'style', 'css', 'sass'einfach ändern können 'style', 'css!sass'- Danke!
Aleski
3
DAS IST FALSCH Lesen Sie die obigen Kommentare oder Antworten. Fett gedruckt, weil jemand diese Antwort liest und nicht versteht, warum ExtractTextPlugin nicht alle Lader verwendet.
Don P
Andere Antworten scheinen für andere zu funktionieren, aber als ich die Frage gestellt habe, hat dies für mich funktioniert, also habe ich sie markiert.
Ganonside