1

I have a project that uses React and server side rendering. For the development, I use webpack -w && nodemon server.js. It will build the files watch for any changes to build and monitor the server for any change. But this is the error that I got upon running nodemon server.js:

ReferenceError: document is not defined
at insertStyleElement (webpack:///./node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js?:93:15)
at addStyle (webpack:///./node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js?:208:13)
at modulesToDom (webpack:///./node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js?:81:18)
at module.exports (webpack:///./node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js?:239:25)
at eval (webpack:///./src/shared/css/home-style.css?:15:14)

As you can see, the error has something to do with webpack style-loader that I use. And indeed, when I remove style-loader from my webpack.config.js, the error is gone. But this approach is not ideal if you want to bundle your css referenced by your react <App/ >. How do I resolve this error?

Below is my files:

index.js (that will be built by webpack into server.js, which does the server-side rendering)

import React from 'react';
import express from 'express';
import cors from 'cors';
import { renderToString } from 'react-dom/server';
import App from '../shared/Components/App';
import serialize from 'serialize-javascript';

const app = express();

app.use(cors());

app.use(express.static('public'));

app.get('*', (req, res, next) => {
    const markup = renderToString(
        
            <App />
        
    );

    res.status(200).send(
        `<!DOCTYPE html>
        <html lang="">
        <head>
            <meta http-equiv="X-UA-Compatible" content="IE=edge" />
            <meta charset="utf-8" />
            <title>Welcome to Banding-Bandingz</title>
            <meta name="viewport" content="width=device-width, initial-scale=1">
            <script src='/bundle.js' defer></script>

        </head>
        <body>
            <div id="app">${markup}</div>
        </body>
        </html>`
    );
});

app.listen(3000, () => {
    console.log('server is listening on port 3000...');
});

package.json

"scripts": {
    "start": "webpack -w && node server.js",
    "watch:server": "nodemon server.js",
    "watch:build": "webpack -w",
    "test": "echo \"Error: no test specified\" && exit 1"
},
"babel": {
    "presets": [
        "@babel/preset-env",
        "@babel/preset-react"
    ],
    "plugins": [
        "@babel/plugin-proposal-object-rest-spread",
        "@babel/plugin-proposal-class-properties"
    ]
},
"devDependencies": {
    "@babel/core": "^7.3.4",
    "@babel/plugin-proposal-class-properties": "^7.10.4",
    "@babel/plugin-proposal-object-rest-spread": "^7.9.0",
    "@babel/preset-env": "^7.3.4",
    "@babel/preset-react": "^7.0.0",
    "babel-loader": "^8.1.0",
    "concurrently": "^5.3.0",
    "css-loader": "^4.2.1",
    "file-loader": "^6.0.0",
    "nodemon": "^2.0.4",
    "style-loader": "^1.2.1",
    "url-loader": "^4.1.0",
    "webpack": "^4.42.1",
    "webpack-cli": "^3.3.11",
    "webpack-node-externals": "^1.7.2"
},
"dependencies": {
    "cors": "^2.8.5",
    "express": "^4.17.1",
    "isomorphic-fetch": "^2.2.1",
    "jsdom": "^16.4.0",
    "npm-run-all": "^4.1.5",
    "pure-react-carousel": "^1.27.1",
    "react": "^16.13.1",
    "react-dom": "^16.13.1",
    "react-router-dom": "4.4.0-beta.8",
    "serialize-javascript": "^3.0.0"
}

webpack.config.js

var path = require('path');
var webpack = require('webpack');
var nodeExternals = require('webpack-node-externals');

var browserConfig = {
    entry: './src/browser/index.js',
    output: {
        path: path.resolve(__dirname, 'public'),
        filename: 'bundle.js',
        publicPath: '/',
    },
    module: {
        rules: [
            { test: /\.(js)$/, use: 'babel-loader' },
            {
                test: /\.css$/,
                use: ['style-loader', 'css-loader'],
            },
            {
                test: /\.(jpg|png|PNG|svg|jpe?g)$/,
                use: [
                    {
                        loader: 'file-loader',
                        options: {
                            outputPath: 'img/',
                            publicPath: 'img/',
                        },
                    },
                ],
            },
        ],
    },
    mode: 'production',
    plugins: [
        new webpack.DefinePlugin({
            __isBrowser__: 'true',
        }),
    ],
    performance: {
        maxEntrypointSize: 512000,
        maxAssetSize: 512000,
    },
};

var serverConfig = {
    entry: './src/server/index.js',
    target: 'node',
    externals: [nodeExternals()],
    output: {
        path: __dirname,
        filename: 'server.js',
        publicPath: '/',
    },
    module: {
        rules: [
            { test: /\.(js)$/, use: 'babel-loader' },
            {
                test: /\.css$/,
                use: ['style-loader', 'css-loader'],
            },
            {
                test: /\.(jpg|png|PNG|svg|jpe?g)$/,
                use: [
                    {
                        loader: 'file-loader',
                        options: {
                            outputPath: 'img/',
                            publicPath: 'img/',
                        },
                    },
                ],
            },
        ],
    },
    mode: 'development',
    plugins: [
        new webpack.DefinePlugin({
            __isBrowser__: 'false',
        }),
    ],
    performance: {
        maxEntrypointSize: 512000,
        maxAssetSize: 512000,
    },
};

module.exports = [browserConfig, serverConfig];
kabison33
  • 101
  • 2
  • 10
  • Does this answer your question? [How can I use style-loader in react SSR (Server Side Rendering)?](https://stackoverflow.com/questions/51570134/how-can-i-use-style-loader-in-react-ssr-server-side-rendering) – segFault Aug 16 '20 at 13:11
  • Or rather this one? ['window is not defined' error when using style-loader with webpack](https://stackoverflow.com/questions/53951861/window-is-not-defined-error-when-using-style-loader-with-webpack) – segFault Aug 16 '20 at 13:13
  • Hey @segFault your suggested page directed me to a isomorphic-style-loader library that when included, fixes the error message. So thanks for that! I have been looking for the solution for long. Do you know whether I should configure anything else? Because I still cannot see the styling on the page when it is requested.. – kabison33 Aug 16 '20 at 14:30
  • I would check [the documentation for that plugin here](https://github.com/kriasoft/isomorphic-style-loader), I am not all too familiar with this library. – segFault Aug 16 '20 at 14:34

1 Answers1

0

I would check if style-loader can be used server-side. I believe not, because the error you get is typically the case where your script is trying to find a 'document' to inject a 'style' tag in it

Marcelo Viana
  • 314
  • 1
  • 5