【问题标题】:Solution for window is not define in React server side renderingReact 服务器端渲染中未定义窗口的解决方案
【发布时间】:2018-08-06 16:36:14
【问题描述】:

我正在尝试将 React 服务器端渲染集成到现有的 React 应用程序中。我正在使用带有 babel 的 webpack 来转译 JS 代码。

webpack.config.js

const { join, resolve } = require('path');
const webpack = require('webpack');
const nodeExternals = require('webpack-node-externals');

const projectConfig = require('../../config');

const APP_JS = 'server/index.js';

const prodConfig = {
    entry: [
        join(process.cwd(), APP_JS),
    ],

    output: {
        path: resolve(process.cwd(), 'dist'),
        filename: '[name].js',
        publicPath: '/',
    },

    target: 'node',
    externals: [nodeExternals({
        whitelist: [/^lodash-es/],
    })],

    resolve: {
        alias: {
            'Framework/Services$': resolve(process.cwd(), join('app', 'internal', 'services')),
            'Framework/UI$': resolve(process.cwd(), join('app', 'internal', 'uiComponents.js')),
            'Framework/Utils$': resolve(process.cwd(), join('app', 'internal', 'utils')),
            'Framework/Middleware$': resolve(process.cwd(), join('app', 'internal', 'middleware')),
            'Framework/Constants$': resolve(process.cwd(), join('app', 'internal', 'constants')),
            'Framework/Auth$': resolve(process.cwd(), join('app', 'modules', 'auth')),
            'Framework/System$': resolve(process.cwd(), join('app', 'modules', 'system')),
            Framework$: resolve(process.cwd(), join('app', 'internal', 'actions.js')),
            Modules$: resolve(process.cwd(), join('app', 'modules')),
            lodash: 'lodash-es',
        },
        modules: [
            'app', 'node_modules',
        ],
        extensions: [
            '.js', '.json', '.css',
        ],
    },

    plugins: [
        new webpack.ContextReplacementPlugin(/moment[/\\]locale$/, /en|fr/),

        new webpack.ContextReplacementPlugin(/react-intl[/\\]locale-data$/, /en|fr/),


        new webpack.ProvidePlugin({
            // make fetch available
            fetch: 'exports-loader?self.fetch!whatwg-fetch',
        }),

        // Always expose NODE_ENV to webpack, in order to use `process.env.NODE_ENV` inside your code for any environment checks.
        // UglifyJS will automatically drop any unreachable code.
        new webpack.DefinePlugin(projectConfig({
            'process.env': {
                NODE_ENV: JSON.stringify(process.env.NODE_ENV),
            },
            __DEV__: process.env.NODE_ENV === 'development',
        })),
    ],

    module: {
        rules: [
            {
                test: /\.js$/,
                exclude: /node_modules\/(?!lodash-es\/)/,
                use: {
                    loader: 'babel-loader',
                },
            },
            {
                // pre-process our own .css files
                test: /\.css$/,
                exclude: /node_modules/,
                use: ['style-loader', 'css-loader'],
            },
            {
                // pre-process 3rd party .css files located in node_modules
                test: /\.css$/,
                include: /node_modules/,
                use: ['style-loader', 'css-loader'],
            },
        ],
    },

};

module.exports = () => prodConfig;

server/index.js 的一部分

// Renders app component into an HTML string
const html = ReactDOMServer.renderToString(React.createElement(App));

// app.get('*', (req, res) => res.sendFile(resolve(outputPath, 'index.html')));
app.get('*', (req, res) => {
  Fs.readFile(resolve(outputPath, 'index.html'), 'utf8', (err, data) => {
    if (err) throw err;

    // Inserts the rendered React HTML into our main div
    const document = data.replace(/<div id="app"><\/div>/, `<div id="app">${html}</div>`);

    // Sends the response back to the client
    res.send(document);
  });
});

但是当我启动节点服务器时,出现以下错误。

/node_modules/inputmask/dist/inputmask/global/window.js:11
}) : "object" == typeof exports && (module.exports = window);
                                                     ^

ReferenceError: window is not defined

据我了解,发生此错误是因为 inputmask 库使用了服务器中不可用的 window 对象。 任何人都可以提出任何解决方案或解决方法吗?

【问题讨论】:

标签: reactjs webpack server-side-rendering input-mask


【解决方案1】:

你可以尝试使用这个包来检测 DOM 是否准备好(客户端/服务器)

https://github.com/JedWatson/exenv

var ExecutionEnvironment = require('exenv');

ExecutionEnvironment.canUseDOM // window object will be ready

【讨论】:

  • 感谢您的建议,但我不能使用它,因为 inputMask 是子依赖项。也好像ExecutionEnvironment.canUseDOM 检查是否有可用的DOM,它不是在服务器环境中创建DOM。
猜你喜欢
  • 2020-11-16
  • 2018-04-26
  • 2021-12-18
  • 2017-12-30
  • 1970-01-01
  • 2019-10-18
  • 1970-01-01
  • 2020-12-30
  • 1970-01-01
相关资源
最近更新 更多