Skip to content

Commit

Permalink
Unify ReactOnServer.node and .full
Browse files Browse the repository at this point in the history
  • Loading branch information
alexeyr committed Feb 26, 2025
1 parent fc42b26 commit d814643
Show file tree
Hide file tree
Showing 10 changed files with 45 additions and 56 deletions.
6 changes: 1 addition & 5 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,9 @@ Please follow the recommendations outlined at [keepachangelog.com](http://keepac
### [Unreleased]
Changes since the last non-beta release.

#### Breaking
- Reduced bundle size [PR 1697](https://github.com/shakacode/react_on_rails/pull/1697) by [Romex91](https://github.com/Romex91)
- Migrated from CJS to ESM for more compact modules (~1KB improvement). **Breaking change:** Dropped CJS support. All projects running `require('react-on-rails')` will need to update to ESM `import ReactOnRails from 'react-on-rails'`.
- Add export option 'react-on-rails/client' to avoid shipping server-rendering code to browsers (~14KB improvement).

#### 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 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.server.ts!'],
project: ['node_package/src/**/*.[jt]s!', 'node_package/tests/**/*.[jt]s'],
babel: {
config: ['node_package/babel.config.js'],
Expand Down
4 changes: 2 additions & 2 deletions node_package/src/ReactOnRails.client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,7 @@ ctx.ReactOnRails = {
* @param options
*/
serverRenderReactComponent(): null | string | Promise<RenderResult> {
throw new Error('serverRenderReactComponent is not available in "react-on-rails/client". Import "react-on-rails" server-side.');
throw new Error('serverRenderReactComponent is not available in "react-on-rails.client". Import "react-on-rails" server-side.');
},

/**
Expand All @@ -256,7 +256,7 @@ ctx.ReactOnRails = {
* @param options
*/
handleError(): string | undefined {
throw new Error('handleError is not available in "react-on-rails/client". Import "react-on-rails" server-side.');
throw new Error('handleError is not available in "react-on-rails.client". Import "react-on-rails" server-side.');
},

/**
Expand Down
28 changes: 0 additions & 28 deletions node_package/src/ReactOnRails.full.ts

This file was deleted.

7 changes: 0 additions & 7 deletions node_package/src/ReactOnRails.node.ts

This file was deleted.

18 changes: 18 additions & 0 deletions node_package/src/ReactOnRails.server.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import handleError from './handleError';
import serverRenderReactComponent from './serverRenderReactComponent';
import streamServerRenderedReactComponent from './streamServerRenderedReactComponent';

import ReactOnRails from './ReactOnRails.client';

if (typeof window !== 'undefined') {
console.log("This file shouldn't be loaded in the browser, your configuration may be wrong");
}

ReactOnRails.handleError = handleError;

ReactOnRails.serverRenderReactComponent = serverRenderReactComponent;

ReactOnRails.streamServerRenderedReactComponent = streamServerRenderedReactComponent;

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
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.full.js ] ||
[ -f node_package/lib/ReactOnRails.server.js ] ||
(npm run build >/dev/null 2>&1 || true) &&
[ -f node_package/lib/ReactOnRails.full.js ] ||
[ -f node_package/lib/ReactOnRails.server.js ] ||
{ echo 'Building react-on-rails seems to have failed!'; }
format:
Expand Down
10 changes: 6 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@
"description": "react-on-rails JavaScript for react_on_rails Ruby gem",
"exports": {
".": {
"node": "./node_package/lib/ReactOnRails.node.js",
"default": "./node_package/lib/ReactOnRails.full.js"
},
"./client": "./node_package/lib/ReactOnRails.client.js"
"react-server": "./node_package/lib/ReactOnRails.server.js",
"server": "./node_package/lib/ReactOnRails.server.js",
"node": "./node_package/lib/ReactOnRails.server.js",
"browser": "./node_package/lib/ReactOnRails.client.js",
"default": "./node_package/lib/ReactOnRails.server.js"
}
},
"directories": {
"doc": "docs"
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.push('server');
} else {
// '...' uses the default conditions
serverWebpackConfig.resolve.conditionNames = ['...', 'server'];
}

return serverWebpackConfig;
};

Expand Down

0 comments on commit d814643

Please sign in to comment.