Skip to content
Closed

Temp PR #1701

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ yalc.lock

# IDE
.idea/
.vscode/

# TypeScript
*.tsbuildinfo
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ Changes since the last non-beta release.

#### Fixed
- Fix obscure errors by introducing FULL_TEXT_ERRORS [PR 1695](https://github.com/shakacode/react_on_rails/pull/1695) by [Romex91](https://github.com/Romex91).
- Remove server-side-only functions from client bundles [PR 1697](https://github.com/shakacode/react_on_rails/pull/1697) by [Romex91](https://github.com/Romex91).

### [14.1.1] - 2025-01-15

Expand Down
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
* After updating code via Git, to prepare all examples:
```sh
cd react_on_rails/
bundle && yarn && rake examples:gen_all && rake node_package && rake
bundle && yarn && rake shakapacker_examples:gen_all && rake node_package && rake
```

See [Dev Initial Setup](#dev-initial-setup) below for, well... initial setup,
Expand Down
2 changes: 1 addition & 1 deletion knip.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ const config: KnipConfig = {
// ! at the end means files are used in production
workspaces: {
'.': {
entry: ['node_package/src/ReactOnRails.ts!', 'node_package/src/ReactOnRails.node.ts!'],
entry: ['node_package/src/ReactOnRails.node.ts!'],
project: ['node_package/src/**/*.[jt]s!', 'node_package/tests/**/*.[jt]s'],
babel: {
config: ['node_package/babel.config.js'],
Expand Down
Original file line number Diff line number Diff line change
@@ -1,20 +1,16 @@
import type { ReactElement } from 'react';

import * as ClientStartup from './clientStartup';
import handleError from './handleError';
import ComponentRegistry from './ComponentRegistry';
import StoreRegistry from './StoreRegistry';
import serverRenderReactComponent from './serverRenderReactComponent';
import buildConsoleReplay from './buildConsoleReplay';
import createReactOutput from './createReactOutput';
import Authenticity from './Authenticity';
import context from './context';
import type {
RegisteredComponent,
RenderParams,
RenderResult,
RenderReturnType,
ErrorOptions,
ReactComponentOrRenderFunction,
AuthenticityHeaders,
Store,
Expand Down Expand Up @@ -243,8 +239,8 @@ ctx.ReactOnRails = {
* Used by server rendering by Rails
* @param options
*/
serverRenderReactComponent(options: RenderParams): null | string | Promise<RenderResult> {
return serverRenderReactComponent(options);
serverRenderReactComponent(): null | string | Promise<RenderResult> {
throw new Error('serverRenderReactComponent is not available in "react-on-rails.client". Import "react-on-rails" server-side.');
},

/**
Expand All @@ -259,8 +255,8 @@ ctx.ReactOnRails = {
* Used by Rails to catch errors in rendering
* @param options
*/
handleError(options: ErrorOptions): string | undefined {
return handleError(options);
handleError(): string | undefined {
throw new Error('handleError is not available in "react-on-rails.client". Import "react-on-rails" server-side.');
},

/**
Expand Down
6 changes: 3 additions & 3 deletions node_package/src/ReactOnRails.node.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import ReactOnRails from './ReactOnRails';
import ReactOnRails from './ReactOnRails.server';
import streamServerRenderedReactComponent from './streamServerRenderedReactComponent';

ReactOnRails.streamServerRenderedReactComponent = streamServerRenderedReactComponent;

export * from './ReactOnRails';
export { default } from './ReactOnRails';
export * from './ReactOnRails.server';
export { default } from './ReactOnRails.server';
14 changes: 14 additions & 0 deletions node_package/src/ReactOnRails.server.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import handleError from './handleError';
import serverRenderReactComponent from './serverRenderReactComponent';

import ReactOnRails from './ReactOnRails.client';

if (typeof window !== 'undefined') {
console.log("This file shouldn't be loaded in the client. If your Webpack target is 'web' (default), add 'server' to 'resolve.conditionNames'.");
}

ReactOnRails.handleError = handleError;
ReactOnRails.serverRenderReactComponent = serverRenderReactComponent;

export * from "./types";
export default ReactOnRails;
13 changes: 6 additions & 7 deletions node_package/src/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,23 +47,23 @@ type RenderFunctionResult = ReactComponent | ServerRenderResult | Promise<string
/**
* Render functions are used to create dynamic React components or server-rendered HTML with side effects.
* They receive two arguments: props and railsContext.
*
*
* @param props - The component props passed to the render function
* @param railsContext - The Rails context object containing environment information
* @returns A string, React component, React element, or a Promise resolving to a string
*
*
* @remarks
* To distinguish a render function from a React Function Component:
* 1. Ensure it accepts two parameters (props and railsContext), even if railsContext is unused, or
* 2. Set the `renderFunction` property to `true` on the function object.
*
*
* If neither condition is met, it will be treated as a React Function Component,
* and ReactDOMServer will attempt to render it.
*
*
* @example
* // Option 1: Two-parameter function
* const renderFunction = (props, railsContext) => { ... };
*
*
* // Option 2: Using renderFunction property
* const anotherRenderFunction = (props) => { ... };
* anotherRenderFunction.renderFunction = true;
Expand All @@ -82,7 +82,6 @@ export type { // eslint-disable-line import/prefer-default-export
ReactComponent,
AuthenticityHeaders,
RenderFunction,
RenderFunctionResult,
Store,
StoreGenerator,
CreateReactOutputResult,
Expand Down Expand Up @@ -131,7 +130,7 @@ export interface ErrorOptions {
serverSide: boolean;
}

export type RenderingError = Pick<Error, 'message' | 'stack'>;
type RenderingError = Pick<Error, 'message' | 'stack'>;

export interface RenderResult {
html: string | null;
Expand Down
2 changes: 1 addition & 1 deletion node_package/tests/Authenticity.test.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import ReactOnRails from '../src/ReactOnRails';
import ReactOnRails from '../src/ReactOnRails.client';

const testToken = 'TEST_CSRF_TOKEN';

Expand Down
2 changes: 1 addition & 1 deletion node_package/tests/ReactOnRails.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import { createStore } from 'redux';
import React from 'react';
import createReactClass from 'create-react-class';
import ReactOnRails from '../src/ReactOnRails';
import ReactOnRails from '../src/ReactOnRails.client';

describe('ReactOnRails', () => {
expect.assertions(14);
Expand Down
4 changes: 2 additions & 2 deletions package-scripts.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@ scripts:
# 3. Check if the project is built now;
# 4. If it failed, print an error message (still follow https://docs.npmjs.com/cli/v8/using-npm/scripts#best-practices).
script: >
[ -f node_package/lib/ReactOnRails.js ] ||
[ -f node_package/lib/ReactOnRails.server.js ] ||
(npm run build >/dev/null 2>&1 || true) &&
[ -f node_package/lib/ReactOnRails.js ] ||
[ -f node_package/lib/ReactOnRails.server.js ] ||
{ echo 'Building react-on-rails seems to have failed!'; }

format:
Expand Down
5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@
"exports": {
".": {
"node": "./node_package/lib/ReactOnRails.node.js",
"default": "./node_package/lib/ReactOnRails.js"
"react-server": "./node_package/lib/ReactOnRails.server.js",
"server": "./node_package/lib/ReactOnRails.server.js",
"browser": "./node_package/lib/ReactOnRails.client.js",
"default": "./node_package/lib/ReactOnRails.server.js"
}
},
"directories": {
Expand Down
9 changes: 9 additions & 0 deletions spec/dummy/config/webpack/serverWebpackConfig.js
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,15 @@ const configureServer = () => {
// If using the React on Rails Pro node server renderer, uncomment the next line
// serverWebpackConfig.target = 'node'

// Needed to load the server version of ReactOnRails (see "exports" in <root>/package.json).
// Implied by serverWebpackConfig.target = 'node' and can be removed you use the Node renderer.
if (serverWebpackConfig.resolve.conditionNames !== undefined) {
serverWebpackConfig.resolve.conditionNames.unshift('server');
} else {
// '...' uses the default conditions
serverWebpackConfig.resolve.conditionNames = ['server', '...'];
}

return serverWebpackConfig;
};

Expand Down
6 changes: 3 additions & 3 deletions tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@
"allowJs": true,
"esModuleInterop": true,
"jsx": "react-jsx",
"lib": ["dom", "es2015"],
"module": "CommonJS",
"lib": ["dom", "es2020"],
"module": "node16",
"noImplicitAny": true,
"outDir": "node_package/lib",
"strict": true,
"incremental": true,
"target": "es5"
"target": "es2020"
},
"include": ["node_package/src/**/*"]
}
Loading