使用extract-text-webpack-plugin React时未定义窗口错误


82

我正在使用webpack构建我的React组件,并且试图使用extract-text-webpack-plugin来从生成的js文件中分离出CSS。但是,当我尝试构建组件时,出现以下错误: 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
您可以将其转换为答案并标记已解决的问题吗?谢谢。
JuhoVepsäläinen2015年

我已经做了。对于那个很抱歉。
Ganonside 2015年

Answers:


59

您可能想在函数中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
Robert Leggett

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

您不应将loader字符串传递style#extract。但是...如果您设置allChunks=false,那么它将不会为非初始块构建CSS文件。因此,它需要知道要使用哪种加载器来注入页面。

提示:Webpack是真正需要深入了解的工具,否则您可能会遇到很多奇怪的问题。


我听说过有关webpack的最好的事情。
杰德

抱歉,我的回答没有解释。我发布问题和答案时,webpack文档仍在编写(可能仍在编写)。但我同意确实需要对其进行很好的理解。
Ganonside '16

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')


8
可以肯定的是,@ squixy说的是5个月前要做的。
cchamberlain

3
语句“每个加载程序作为单独的参数”仅对两个加载程序有效,而对于三个或更多错误。该extract函数具有三个参数:(before, loader, options),并且此答案完美地涵盖了这一点:stackoverflow.com/a/30982133/1346510
sompylasar 2016年

1
@sompylasar非常感谢您的评论。它解决了我的问题!我以为所有传入的参数都将直接循环通过。很高兴地说,如果您需要使用,'style', 'css', 'sass'则可以将其更改为'style', 'css!sass'-谢谢!
Aleski '16

3
这是错误的阅读上面的评论或答案。用粗体表示,因为有人会阅读此答案,但不明白为什么ExtractTextPlugin未使用所有加载程序。
Don P

其他答案似乎对其他人也有用,但是当我发布问题时,这对我有用,因此我将其标记出来。
Ganonside '16
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.