Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initial Implementation of RSC #1573

Closed
wants to merge 1 commit into from
Closed

Initial Implementation of RSC #1573

wants to merge 1 commit into from

Conversation

KhaledEmaraDev
Copy link

@KhaledEmaraDev KhaledEmaraDev commented Aug 10, 2023

Summary

This is an initial implementation of React Server Components (RSC). In this PR:

  1. I add the necessary code to render to the RSC wire format using Node.js Streams.
  2. I add a hook useRSC() and a React Component that extends react-router-dom's Route named RSCRoute to be used to route to RSC components.
  3. I make sure to separate Server and Client functions because sometimes Server code requires somethings only available to Node.

Related to

https://github.com/shakacode/react_on_rails_pro/pull/346

Pull Request checklist

Remove this line after checking all the items here. If the item is not applicable to the PR, both check it out and wrap it by ~.

  • Add/update test to cover these changes
  • Update documentation
  • Update CHANGELOG file
    Add the CHANGELOG entry at the top of the file.

Other Information

Remove this paragraph and mention any other important and relevant information such as benchmarks.


This change is Reviewable

try {
const path = require('path');
const { readFileSync } = require('fs');
const reactClientManifest = readFileSync(path.resolve(__dirname, 'react-client-manifest.json'), 'utf8');
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should only be read once and cached.
Shared across workers is better.


import useRSC from './useRSC';

import type { RSCRouteProps } from './types/index';
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't include /index here.

@@ -241,6 +244,16 @@ ctx.ReactOnRails = {
return serverRenderReactComponent(options);
},

/**
* Used for React Server Components by Rails
* @param options
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't leave a comment like this empty.

import ComponentRegistry from './ComponentRegistry';
import buildConsoleReplay from './buildConsoleReplay';
import handleError from './handleError';
import type { RenderParams, RenderResult, RenderingError } from './types/index';
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Move line 3 import here (and remove /index).

import handleError from './handleError';
import type { RenderParams, RenderResult, RenderingError } from './types/index';

import { Writable } from 'node:stream';
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And this should be above the local imports.

try {
const componentObj = ComponentRegistry.get(name);
const { component } = componentObj;
const reactRenderingResult = React.createElement(component as ReactComponent, props);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are a lot of casts here, can we minimize them?

* @param {*} other headers
* @returns {*} header
*/

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Extra line.

@@ -28,13 +29,13 @@ export interface RailsContext {
httpAcceptLanguage: string;
}

type AuthenticityHeaders = {[id: string]: string} & {'X-CSRF-Token': string | null; 'X-Requested-With': string};
type AuthenticityHeaders = { [id: string]: string } & { 'X-CSRF-Token': string | null; 'X-Requested-With': string };
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Better to remove & and just do

type AuthenticityHeaders = {
  [id: string]: string;
  'X-CSRF-Token': string | null; 
  'X-Requested-With': string;
};

if we are changing this place anyway.


useEffect(() => {
setContent(createFromFetch(fetch(
'/rsc/' + encodeURIComponent(componentName) + '?props=' + encodeURIComponent(JSON.stringify(props))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use a template string (or URI class).

@@ -0,0 +1,15 @@
// @ts-ignore
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fix before merging (or better, don't even start with this).

@@ -0,0 +1,2 @@
declare module 'react-server-dom-webpack/server.node';
declare module 'react-server-dom-webpack/client.browser';
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should there be something in these declarations?

Signed-off-by: Khaled Emara <[email protected]>
@ahangarha
Copy link
Contributor

ahangarha commented Oct 13, 2023

Is this PR ready for review? If yes, May you please update the description to reflect the state of the PR?
(Maybe a revert commit was a better approach)

@justin808
Copy link
Member

@KhaledEmaraDev close this one?

@KhaledEmaraDev
Copy link
Author

@justin808 No, it's needed for the Pro version to work. I think it could be accepted as-is. I will not introduce new changes to it.

"homepage": "https://github.com/shakacode/react_on_rails#readme",
"husky": {
"hooks": {
"pre-commit": "yalc check"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why is this needed pre-commit?

@@ -32,6 +32,7 @@
"eslint-plugin-jsx-a11y": "^6.7.1",
"eslint-plugin-prettier": "^3.4.1",
"eslint-plugin-react": "^7.32.1",
"husky": "^4.3.6",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

husky and yalc should be separate PRs.

"exports": {
".": "./node_package/lib/ReactOnRails.js",
"./*": "./node_package/lib/*.js"
},
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@KhaledEmaraDev can you explain this?

Seems odd to start exporting everything from package.json

Why not add what's necessary to the current exports?

We already have:
https://github.com/shakacode/react_on_rails/blob/master/node_package/src/ReactOnRails.ts#L292-L293

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this file should not be changing, right?

@justin808 justin808 closed this Jan 9, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants