window not defined error when using extract-text-webpack-plugin React

前端 未结 4 946
闹比i
闹比i 2020-12-13 01:21

I\'m using webpack to build my react components and I\'m trying to use the extract-text-webpack-plugin to separate my css from my generated js file. However, wh

相关标签:
4条回答
  • 2020-12-13 02:06

    Didn't see an explanation of the cause so I have posted this answer here.

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

    ExtractTextPlugin.extract([notExtractLoader], loader, [options]) Creates an extracting loader from an existing loader.

    notExtractLoader (optional) the loader(s) that should be used when the css is not extracted (i.e. in an > additional chunk when allChunks: false)

    loader the loader(s) that should be used for converting the resource to a css exporting module.

    options

    publicPath override the publicPath setting for this loader.

    The #extract method should receive a loader that outputs css. What was happening was that it was receiving a style-loader which outputs javascript code, which is intended to be injected into a webpage. This code would try to access window.

    You should not pass a loader string with style to #extract. However...if you set allChunks=false, then it will not build CSS files for non-initial chunks. Therefore it needs to know what loader to use to inject into the page.

    Tip: Webpack is a tool that really needs to be understood in-depth or you can run into lots of strange issues.

    0 讨论(0)
  • 2020-12-13 02:08

    You may want to use style-loader as a before argument in extract function.

    Here's the native implementation:

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

    So basicaly what you need to do is:

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

    if you for example use sass.

    0 讨论(0)
  • 2020-12-13 02:08

    Webpack 2

    If you're using Webpack 2, this variation works:

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

    The new extract method no longer takes three arguments, and is listed as a breaking change when moving from V1 to V2.

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

    0 讨论(0)
  • 2020-12-13 02:08

    I figured out the solution to my problem:

    Instead of piping the loaders into one another (ExtractTextPlugin.extract('style-loader!css-loader')), you have to pass in the each loader as a separate parameter: ExtractTextWebpackPlugin.extract('style-loader', 'css-loader')

    0 讨论(0)
提交回复
热议问题