微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

为什么 React hydration 没有加载?

如何解决为什么 React hydration 没有加载?

我正在尝试使用 React、Fastify 和 esbuild 构建我自己的服务器端渲染应用程序。捆绑过程成功运行而无需担心。但是当我尝试运行服务器时,没有加载客户端包脚本。 HTML 预计会显示在浏览器中,并且会请求客户端脚本(通过 chrome 开发工具检查 200 个响应代码)。就像脚本被请求但没有加载一样。我错过了什么吗?

显然影响任何事件监听器(onclick 等)都不会被调用。您可以在 repository

中查看完整版本的代码

src/client/index.tsx

import React from 'react';
import { hydrate } from 'react-dom';
import canUseDOM from '@bconnorwhite/can-use-dom';
import { createbrowserHistory,createMemoryHistory } from 'history';
import App from './App';

const bootstrap = (): void => {
  const root = document.getElementById('root');
  const history = canUseDOM ? createbrowserHistory() : createMemoryHistory();

  hydrate(<App history={history} />,root);
};

export default bootstrap;

src/server/index.ts

import fastify from 'fastify';
import helmet from 'fastify-helmet';
import staticAsset from 'fastify-static';
import debug from 'debug';
import { config } from 'dotenv';
import path from 'path';

import routes from './routes';
import assetParser from './decorators/assetParser';

config();

const log = debug('server:app');
const app = fastify({
  logger: true,disableRequestLogging: true,});

app.decorate('assetManifest',assetParser(log));

app.register(staticAsset,{
  root: path.join(process.cwd(),'dist'),});

app.register(helmet);
app.register(routes,{ log });

const PORT: number =
  process.env.NODE_ENV === 'development' ? Number(process.env.DEV_PORT || '') : Number(process.env.PROD_PORT || '');

const HOST: string = process.env.NODE_ENV === 'development' ? process.env.DEV_HOST || '' : process.env.PROD_HOST || '';

app.listen(PORT || 3000,HOST,(err,address) => {
  if (err) {
    log('Error bootstraping server:',err);
    app.log.error(JSON.stringify(err));

    process.exit(1);
  } else {
    log('Server listening to',address);
  }
});

builder/index.js

const path = require('path');
const debug = require('debug')('builder');
const { startService } = require('esbuild');
const { DEFAULT_CONfig } = require('./constant');

/**
 * Build function performs bundle and transpilation operation using esbuild. The function works
 * by reaching the configuration file (usually named esbuild.config.js) and parse the configuration
 * to the startService parameter.
 *
 * The function also calculates the process time using process.hrtime() and translate the result
 * into milisecond. The timer log is displayed for debugging purpose only.
 * @function build
 * @returns {void}
 */
const build = async () => {
  let config = {};

  try {
    config = await require(path.resolve(process.cwd(),'esbuild.config.js'));

    if (!config) {
      throw new Error('Config file is not defined');
    }
  } catch (error) {
    debug('Failed to read config file: ',error);
    process.exit(1);
  }

  const service = await startService();
  const startTimer = process.hrtime();

  try {
    await Promise.all(
      config.map(async (currentConfig) => {
        await service.build({
          ...DEFAULT_CONfig,...currentConfig,});
      }),);
  } catch (error) {
    debug('Error happened during build process:',error);
  } finally {
    service.stop();

    const endTimer = process.hrtime(startTimer);
    const timeInMs = (endTimer[0] * 1e9 + endTimer[1]) / 1e3;

    debug('Bundle process is finished at',timeInMs,'ms');
  }
};

(async () => {
  debug('Starting bundle process...');

  try {
    await build();
  } catch (error) {
    debug('Error happend during bundle process:',error);
  }
})();

esbuild.config.js

const path = require('path');
const { nodeExternalsPlugin } = require('esbuild-node-externals');

module.exports = [
  {
    entryPoints: [path.resolve(__dirname,'src/client/index.tsx')],outfile: './dist/index.browser.js',platform: 'browser',loader: {
      '.svg': 'file','.jpg': 'file','.png': 'file','.gif': 'file',},tsconfig: 'tsconfig.json',banner: '/* client dist */',Metafile: 'dist/asset-client-manifest.json',{
    entryPoints: [path.resolve(__dirname,'src/server/index.ts')],outfile: './dist/index.js',platform: 'node',minify: false,banner: '/* server dist */',format: 'cjs',plugins: [nodeExternalsPlugin()],];

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?