Решение для окна не определено в рендеринге на стороне сервера React
Я пытаюсь интегрировать рендеринг на стороне сервера React в существующее приложение React. Я использую webpack с babel для переноса кода 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;
часть сервера /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
Как я понял, эта ошибка происходит, поскольку библиотека ввода маски использует объект окна, который недоступен на сервере. Кто-нибудь может предложить какое-либо решение или любой обходной путь?
1 ответ
Вы можете попробовать использовать этот пакет для обнаружения готовности DOM (клиент / сервер)
https://github.com/JedWatson/exenv
var ExecutionEnvironment = require('exenv');
ExecutionEnvironment.canUseDOM // window object will be ready