diff --git a/.gitignore b/.gitignore index cdb3a55c28..2f2ceb077c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,6 @@ +# Root Gemfile.lock (delegates to react_on_rails/Gemfile, lock is there) +/Gemfile.lock + .bundle/ /.yardoc /_yardoc/ diff --git a/packages/react-on-rails-pro/package.json b/packages/react-on-rails-pro/package.json index e35c53f244..d6834545ac 100644 --- a/packages/react-on-rails-pro/package.json +++ b/packages/react-on-rails-pro/package.json @@ -9,7 +9,7 @@ "clean": "rm -rf ./lib", "test": "pnpm run test:non-rsc && pnpm run test:rsc", "test:non-rsc": "jest tests --testPathIgnorePatterns=\".*(RSC|stream|registerServerComponent|serverRenderReactComponent|SuspenseHydration).*\"", - "test:rsc": "echo 'TODO: RSC tests disabled - jest.setup.js uses require() incompatible with ESM mode. Re-enable after converting setup to ESM.' && exit 0", + "test:rsc": "node scripts/check-react-version.cjs || NODE_CONDITIONS=react-server jest tests/*.rsc.test.*", "type-check": "tsc --noEmit --noErrorTruncation", "prepare": "[ -f lib/ReactOnRails.full.js ] || (rm -rf ./lib && tsc)", "prepublishOnly": "pnpm run build", diff --git a/packages/react-on-rails-pro/scripts/check-react-version.cjs b/packages/react-on-rails-pro/scripts/check-react-version.cjs new file mode 100644 index 0000000000..0a4ea5a12a --- /dev/null +++ b/packages/react-on-rails-pro/scripts/check-react-version.cjs @@ -0,0 +1,19 @@ +/** + * Check if React version supports RSC features (React 19+). + * Exits with code 0 if React < 19 (skip RSC tests). + * Exits with code 1 if React >= 19 (run RSC tests). + * + * This is a CommonJS file (.cjs) because it needs to use require() + * and the parent package has "type": "module". + */ +const v = require('react/package.json').version; + +const majorVersion = parseInt(v, 10); + +if (majorVersion < 19) { + console.log(`RSC tests skipped (requires React 19+, found ${v})`); + process.exit(0); +} + +// Exit with code 1 so the || chain continues to run Jest +process.exit(1); diff --git a/packages/react-on-rails-pro/tests/jest.setup.js b/packages/react-on-rails-pro/tests/jest.setup.js index 2758e3eb80..8e0487d636 100644 --- a/packages/react-on-rails-pro/tests/jest.setup.js +++ b/packages/react-on-rails-pro/tests/jest.setup.js @@ -1,3 +1,8 @@ +import { TextEncoder, TextDecoder } from 'util'; +import { Readable } from 'stream'; +import { ReadableStream, ReadableStreamDefaultReader } from 'stream/web'; +import { jest } from '@jest/globals'; + // If jsdom environment is set and TextEncoder is not defined, then define TextEncoder and TextDecoder // The current version of jsdom does not support TextEncoder and TextDecoder // The following code will tell us when jsdom supports TextEncoder and TextDecoder @@ -11,13 +16,6 @@ if (typeof window !== 'undefined' && typeof window.MessageChannel !== 'undefined } if (typeof window !== 'undefined') { - // eslint-disable-next-line global-require - const { TextEncoder, TextDecoder } = require('util'); - // eslint-disable-next-line global-require - const { Readable } = require('stream'); - // eslint-disable-next-line global-require - const { ReadableStream, ReadableStreamDefaultReader } = require('stream/web'); - // Mock the fetch function to return a ReadableStream instead of Node's Readable stream // This matches browser behavior where fetch responses have ReadableStream bodies // Node's fetch and polyfills like jest-fetch-mock return Node's Readable stream, diff --git a/script/convert b/script/convert index b99413323f..2a4b501e1e 100755 --- a/script/convert +++ b/script/convert @@ -53,12 +53,8 @@ gsub_file_content( '"test:non-rsc": "jest tests --testPathIgnorePatterns=\".*(RSC|stream|' \ 'registerServerComponent|serverRenderReactComponent|SuspenseHydration).*\"",' ) -# Make test:rsc script do nothing -gsub_file_content( - "../packages/react-on-rails-pro/package.json", - /"test:rsc": "(?:\\"|[^"])*",/, - '"test:rsc": "exit 0",' -) +# test:rsc script now automatically detects React version and skips on React 18 +# No override needed - the script checks React version and exits cleanly if < 19 # Keep modern JSX transform for React 18+ # gsub_file_content("../tsconfig.json", "react-jsx", "react") # gsub_file_content("../spec/dummy/babel.config.js", "runtime: 'automatic'", "runtime: 'classic'")