Compare commits

..

1 Commits

Author SHA1 Message Date
Tianyu Yao d2737de6ef Add test case 2023-02-13 17:28:46 -08:00
951 changed files with 61859 additions and 60743 deletions

View File

@ -7,11 +7,40 @@ aliases:
- &environment
TZ: /usr/share/zoneinfo/America/Los_Angeles
- &restore_yarn_cache
restore_cache:
name: Restore yarn cache
keys:
- v1-yarn_cache-{{ arch }}-{{ checksum "yarn.lock" }}
- v1-yarn_cache-{{ arch }}-
- v1-yarn_cache-
- &yarn_install
run:
name: Install dependencies
command: yarn install --frozen-lockfile --cache-folder ~/.cache/yarn
- &yarn_install_retry
run:
name: Install dependencies (retry)
when: on_fail
command: yarn install --frozen-lockfile --cache-folder ~/.cache/yarn
- &save_yarn_cache
save_cache:
name: Save yarn cache
key: v1-yarn_cache-{{ arch }}-{{ checksum "yarn.lock" }}
paths:
- ~/.cache/yarn
- &restore_yarn_cache_fixtures_dom
restore_cache:
name: Restore yarn cache for fixtures/dom
keys:
- v2-yarn_cache-{{ arch }}-{{ checksum "yarn.lock" }}-fixtures/dom
- v1-yarn_cache-{{ arch }}-{{ checksum "yarn.lock" }}-fixtures/dom
- v1-yarn_cache-{{ arch }}-{{ checksum "yarn.lock" }}
- v1-yarn_cache-{{ arch }}-
- v1-yarn_cache-
- &yarn_install_fixtures_dom
run:
@ -29,36 +58,51 @@ aliases:
- &save_yarn_cache_fixtures_dom
save_cache:
name: Save yarn cache for fixtures/dom
key: v2-yarn_cache-{{ arch }}-{{ checksum "yarn.lock" }}-fixtures/dom
key: v1-yarn_cache-{{ arch }}-{{ checksum "yarn.lock" }}-fixtures/dom
paths:
- ~/.cache/yarn
- &save_node_modules
save_cache:
name: Save node_modules cache
# Cache only for the current revision to prevent cache injections from
# malicious PRs.
key: v1-node_modules-{{ arch }}-{{ .Revision }}
paths:
- node_modules
- packages/eslint-plugin-react-hooks/node_modules
- packages/react-art/node_modules
- packages/react-client/node_modules
- packages/react-devtools-core/node_modules
- packages/react-devtools-extensions/node_modules
- packages/react-devtools-inline/node_modules
- packages/react-devtools-shared/node_modules
- packages/react-devtools-shell/node_modules
- packages/react-devtools-timeline/node_modules
- packages/react-devtools/node_modules
- packages/react-dom/node_modules
- packages/react-interactions/node_modules
- packages/react-native-renderer/node_modules
- packages/react-reconciler/node_modules
- packages/react-server-dom-relay/node_modules
- packages/react-server-dom-webpack/node_modules
- packages/react-server-native-relay/node_modules
- packages/react-server/node_modules
- packages/react-test-renderer/node_modules
- packages/react/node_modules
- packages/scheduler/node_modules
- &restore_node_modules
restore_cache:
name: Restore node_modules cache
keys:
- v1-node_modules-{{ arch }}-{{ .Revision }}
- &TEST_PARALLELISM 20
- &attach_workspace
at: build
commands:
setup_node_modules:
description: "Restore node_modules"
steps:
- restore_cache:
name: Restore yarn cache
keys:
- v2-yarn_cache-{{ arch }}-{{ checksum "yarn.lock" }}
- run:
name: Install dependencies
command: |
yarn install --frozen-lockfile --cache-folder ~/.cache/yarn
if [ $? -ne 0 ]; then
yarn install --frozen-lockfile --cache-folder ~/.cache/yarn
fi
- save_cache:
name: Save yarn cache
key: v2-yarn_cache-{{ arch }}-{{ checksum "yarn.lock" }}
paths:
- ~/.cache/yarn
# The CircleCI API doesn't yet support triggering a specific workflow, but it
# does support triggering a pipeline. So as a workaround you can triggger the
# entire pipeline and use parameters to disable everything except the workflow
@ -71,13 +115,28 @@ parameters:
default: ''
jobs:
setup:
docker: *docker
environment: *environment
steps:
- checkout
- run:
name: NodeJS Version
command: node --version
- *restore_yarn_cache
- *restore_node_modules
- *yarn_install
- *yarn_install_retry
- *save_yarn_cache
- *save_node_modules
yarn_lint:
docker: *docker
environment: *environment
steps:
- checkout
- setup_node_modules
- *restore_node_modules
- run: node ./scripts/prettier/index
- run: node ./scripts/tasks/eslint
- run: ./scripts/circleci/check_license.sh
@ -91,7 +150,7 @@ jobs:
steps:
- checkout
- setup_node_modules
- *restore_node_modules
- run: node ./scripts/tasks/flow-ci
scrape_warning_messages:
@ -100,7 +159,7 @@ jobs:
steps:
- checkout
- setup_node_modules
- *restore_node_modules
- run:
command: |
mkdir -p ./build
@ -110,14 +169,14 @@ jobs:
paths:
- build
yarn_build:
yarn_build_combined:
docker: *docker
environment: *environment
parallelism: 40
steps:
- checkout
- setup_node_modules
- run: yarn build
- *restore_node_modules
- run: yarn build-combined
- persist_to_workspace:
root: .
paths:
@ -131,7 +190,7 @@ jobs:
type: string
steps:
- checkout
- setup_node_modules
- *restore_node_modules
- run:
name: Download artifacts for revision
command: |
@ -148,36 +207,14 @@ jobs:
environment: *environment
steps:
- checkout
- setup_node_modules
- *restore_node_modules
- run:
name: Download artifacts for base revision
# TODO: The download-experimental-build.js script works by fetching
# artifacts from CI. CircleCI recently updated this endpoint to
# require an auth token. This is a problem for PR branches, where
# sizebot needs to run, because we don't want to leak the token to
# arbitrary code written by an outside contributor.
#
# This only affects PR branches. CI workflows that run on the main
# branch are allowed to access environment variables, because only those
# with push access can land code in main.
#
# As a temporary workaround, we'll fetch the assets from a mirror.
# Need to figure out a longer term solution for this.
#
# Original code
#
# command: |
# git fetch origin main
# cd ./scripts/release && yarn && cd ../../
# scripts/release/download-experimental-build.js --commit=$(git merge-base HEAD origin/main) --allowBrokenCI
# mv ./build ./base-build
#
# Workaround. Fetch the artifacts from react-builds.vercel.app. This
# is the same app that hosts the sizebot diff previews.
command: |
curl -L --retry 60 --retry-delay 10 --retry-max-time 600 https://react-builds.vercel.app/api/commits/$(git merge-base HEAD origin/main)/artifacts/build.tgz | tar -xz
git fetch origin main
cd ./scripts/release && yarn && cd ../../
scripts/release/download-experimental-build.js --commit=$(git merge-base HEAD origin/main) --allowBrokenCI
mv ./build ./base-build
- run:
# TODO: The `download-experimental-build` script copies the npm
# packages into the `node_modules` directory. This is a historical
@ -198,7 +235,7 @@ jobs:
- checkout
- attach_workspace:
at: .
- setup_node_modules
- *restore_node_modules
- run: echo "<< pipeline.git.revision >>" >> build/COMMIT_SHA
# Compress build directory into a single tarball for easy download
- run: tar -zcvf ./build.tgz ./build
@ -217,7 +254,7 @@ jobs:
- attach_workspace:
at: .
- run: echo "<< pipeline.git.revision >>" >> build/COMMIT_SHA
- setup_node_modules
- *restore_node_modules
- run:
command: node ./scripts/tasks/danger
@ -228,7 +265,7 @@ jobs:
- checkout
- attach_workspace:
at: .
- setup_node_modules
- *restore_node_modules
- run:
environment:
RELEASE_CHANNEL: experimental
@ -243,7 +280,7 @@ jobs:
- checkout
- attach_workspace:
at: .
- setup_node_modules
- *restore_node_modules
- run:
name: Playwright install deps
command: |
@ -265,7 +302,7 @@ jobs:
- checkout
- attach_workspace:
at: .
- setup_node_modules
- *restore_node_modules
- run: ./scripts/circleci/download_devtools_regression_build.js << parameters.version >> --replaceBuild
- run: node ./scripts/jest/jest-cli.js --build --project devtools --release-channel=experimental --reactVersion << parameters.version >> --ci
@ -280,7 +317,7 @@ jobs:
- checkout
- attach_workspace:
at: .
- setup_node_modules
- *restore_node_modules
- run:
name: Playwright install deps
command: |
@ -304,7 +341,7 @@ jobs:
- checkout
- attach_workspace:
at: .
- setup_node_modules
- *restore_node_modules
- run: yarn lint-build
yarn_check_release_dependencies:
@ -314,7 +351,7 @@ jobs:
- checkout
- attach_workspace:
at: .
- setup_node_modules
- *restore_node_modules
- run: yarn check-release-dependencies
@ -324,7 +361,7 @@ jobs:
steps:
- checkout
- attach_workspace: *attach_workspace
- setup_node_modules
- *restore_node_modules
- run:
name: Search build artifacts for unminified errors
command: |
@ -337,7 +374,7 @@ jobs:
steps:
- checkout
- attach_workspace: *attach_workspace
- setup_node_modules
- *restore_node_modules
- run:
name: Confirm generated inline Fizz runtime is up to date
command: |
@ -353,7 +390,7 @@ jobs:
type: string
steps:
- checkout
- setup_node_modules
- *restore_node_modules
- run: yarn test <<parameters.args>> --ci
yarn_test_build:
@ -367,7 +404,7 @@ jobs:
- checkout
- attach_workspace:
at: .
- setup_node_modules
- *restore_node_modules
- run: yarn test --build <<parameters.args>> --ci
RELEASE_CHANNEL_stable_yarn_test_dom_fixtures:
@ -377,7 +414,7 @@ jobs:
- checkout
- attach_workspace:
at: .
- setup_node_modules
- *restore_node_modules
- *restore_yarn_cache_fixtures_dom
- *yarn_install_fixtures_dom
- *yarn_install_fixtures_dom_retry
@ -388,7 +425,7 @@ jobs:
RELEASE_CHANNEL: stable
working_directory: fixtures/dom
command: |
yarn predev
yarn prestart
yarn test --maxWorkers=2
test_fuzz:
@ -396,7 +433,7 @@ jobs:
environment: *environment
steps:
- checkout
- setup_node_modules
- *restore_node_modules
- run:
name: Run fuzz tests
command: |
@ -415,7 +452,7 @@ jobs:
environment: *environment
steps:
- checkout
- setup_node_modules
- *restore_node_modules
- run:
name: Run publish script
command: |
@ -426,30 +463,29 @@ jobs:
scripts/release/publish.js --ci --tags << parameters.dist_tag >>
workflows:
version: 2
# New workflow that will replace "stable" and "experimental"
build_and_test:
unless: << pipeline.parameters.prerelease_commit_sha >>
jobs:
- setup:
filters:
branches:
ignore:
- builds/facebook-www
- yarn_flow:
filters:
branches:
ignore:
- builds/facebook-www
requires:
- setup
- check_generated_fizz_runtime:
filters:
branches:
ignore:
- builds/facebook-www
requires:
- setup
- yarn_lint:
filters:
branches:
ignore:
- builds/facebook-www
requires:
- setup
- yarn_test:
filters:
branches:
ignore:
- builds/facebook-www
requires:
- setup
matrix:
parameters:
args:
@ -472,23 +508,19 @@ workflows:
# TODO: Test more persistent configurations?
- '-r=stable --env=development --persistent'
- '-r=experimental --env=development --persistent'
- yarn_build:
filters:
branches:
ignore:
- builds/facebook-www
- yarn_build_combined:
requires:
- setup
- scrape_warning_messages:
filters:
branches:
ignore:
- builds/facebook-www
requires:
- setup
- process_artifacts_combined:
requires:
- scrape_warning_messages
- yarn_build
- yarn_build_combined
- yarn_test_build:
requires:
- yarn_build
- yarn_build_combined
matrix:
parameters:
args:
@ -519,7 +551,8 @@ workflows:
branches:
ignore:
- main
- builds/facebook-www
requires:
- setup
- sizebot:
filters:
branches:
@ -527,22 +560,22 @@ workflows:
- main
requires:
- download_base_build_for_sizebot
- yarn_build
- yarn_build_combined
- yarn_lint_build:
requires:
- yarn_build
- yarn_build_combined
- yarn_check_release_dependencies:
requires:
- yarn_build
- yarn_build_combined
- check_error_codes:
requires:
- yarn_build
- yarn_build_combined
- RELEASE_CHANNEL_stable_yarn_test_dom_fixtures:
requires:
- yarn_build
- yarn_build_combined
- build_devtools_and_process_artifacts:
requires:
- yarn_build
- yarn_build_combined
- run_devtools_e2e_tests:
requires:
- build_devtools_and_process_artifacts
@ -558,7 +591,10 @@ workflows:
only:
- main
jobs:
- test_fuzz
- setup
- test_fuzz:
requires:
- setup
devtools_regression_tests:
unless: << pipeline.parameters.prerelease_commit_sha >>
@ -571,7 +607,10 @@ workflows:
only:
- main
jobs:
- setup
- download_build:
requires:
- setup
revision: << pipeline.git.revision >>
- build_devtools_and_process_artifacts:
requires:
@ -603,21 +642,14 @@ workflows:
publish_preleases:
when: << pipeline.parameters.prerelease_commit_sha >>
jobs:
- setup
- publish_prerelease:
name: Publish to Canary channel
name: Publish to Next channel
requires:
- setup
commit_sha: << pipeline.parameters.prerelease_commit_sha >>
release_channel: stable
# The tags to use when publishing canaries. The main one we should
# always include is "canary" but we can use multiple (e.g. alpha,
# beta, rc). To declare multiple, use a comma-separated string, like
# this:
# dist_tag: "canary,alpha,beta,rc"
#
# TODO: We currently tag canaries with "next" in addition to "canary"
# because this used to be called the "next" channel and some
# downstream consumers might still expect that tag. We can remove this
# after some time has elapsed and the change has been communicated.
dist_tag: "canary,next"
dist_tag: "next"
- publish_prerelease:
name: Publish to Experimental channel
requires:
@ -625,7 +657,7 @@ workflows:
# will sometimes fail if you try to concurrently publish two
# different versions of the same package, even if they use different
# dist tags.
- Publish to Canary channel
- Publish to Next channel
commit_sha: << pipeline.parameters.prerelease_commit_sha >>
release_channel: experimental
dist_tag: experimental
@ -642,11 +674,14 @@ workflows:
only:
- main
jobs:
- setup
- publish_prerelease:
name: Publish to Canary channel
name: Publish to Next channel
requires:
- setup
commit_sha: << pipeline.git.revision >>
release_channel: stable
dist_tag: "canary,next"
dist_tag: "next"
- publish_prerelease:
name: Publish to Experimental channel
requires:
@ -654,7 +689,7 @@ workflows:
# will sometimes fail if you try to concurrently publish two
# different versions of the same package, even if they use different
# dist tags.
- Publish to Canary channel
- Publish to Next channel
commit_sha: << pipeline.git.revision >>
release_channel: experimental
dist_tag: experimental

View File

@ -1,7 +1,7 @@
{
"packages": ["packages/react", "packages/react-dom", "packages/scheduler"],
"buildCommand": "download-build-in-codesandbox-ci",
"node": "18",
"node": "14",
"publishDirectory": {
"react": "build/oss-experimental/react",
"react-dom": "build/oss-experimental/react-dom",

View File

@ -236,14 +236,7 @@ module.exports = {
'no-inner-declarations': [ERROR, 'functions'],
'no-multi-spaces': ERROR,
'no-restricted-globals': [ERROR].concat(restrictedGlobals),
'no-restricted-syntax': [
ERROR,
'WithStatement',
{
selector: 'MemberExpression[property.name=/^(?:substring|substr)$/]',
message: 'Prefer string.slice() over .substring() and .substr().',
},
],
'no-restricted-syntax': [ERROR, 'WithStatement'],
'no-shadow': ERROR,
'no-unused-vars': [ERROR, {args: 'none'}],
'no-use-before-define': OFF,
@ -332,7 +325,6 @@ module.exports = {
'packages/react-native-renderer/**/*.js',
'packages/eslint-plugin-react-hooks/**/*.js',
'packages/jest-react/**/*.js',
'packages/internal-test-utils/**/*.js',
'packages/**/__tests__/*.js',
'packages/**/npm/*.js',
],
@ -416,6 +408,7 @@ module.exports = {
{
files: [
'packages/react-native-renderer/**/*.js',
'packages/react-server-native-relay/**/*.js',
],
globals: {
nativeFabricUIManager: 'readonly',
@ -441,6 +434,7 @@ module.exports = {
es6: true,
node: true,
jest: true,
jasmine: true,
},
globals: {
@ -455,9 +449,6 @@ module.exports = {
$ReadOnlyArray: 'readonly',
$Shape: 'readonly',
AnimationFrameID: 'readonly',
// For Flow type annotation. Only `BigInt` is valid at runtime.
bigint: 'readonly',
BigInt: 'readonly',
Class: 'readonly',
ClientRect: 'readonly',
CopyInspectedElementPath: 'readonly',

View File

@ -9,7 +9,7 @@
3. If you've fixed a bug or added code that should be tested, add tests!
4. Ensure the test suite passes (`yarn test`). Tip: `yarn test --watch TestName` is helpful in development.
5. Run `yarn test --prod` to test in the production environment. It supports the same options as `yarn test`.
6. If you need a debugger, run `yarn test --debug --watch TestName`, open `chrome://inspect`, and press "Inspect".
6. If you need a debugger, run `yarn debug-test --watch TestName`, open `chrome://inspect`, and press "Inspect".
7. Format your code with [prettier](https://github.com/prettier/prettier) (`yarn prettier`).
8. Make sure your code lints (`yarn lint`). Tip: `yarn linc` to only check changed files.
9. Run the [Flow](https://flowtype.org/) type checks (`yarn flow`).

View File

@ -1,29 +1,24 @@
name: Commit Artifacts for Meta WWW and fbsource
name: Commit Artifacts for Facebook WWW
on:
push:
branches: [main, meta-www, meta-fbsource]
branches: [main]
jobs:
download_artifacts:
runs-on: ubuntu-latest
outputs:
www_branch_count: ${{ steps.check_branches.outputs.www_branch_count }}
fbsource_branch_count: ${{ steps.check_branches.outputs.fbsource_branch_count }}
steps:
- uses: actions/checkout@v3
- name: "Check branches"
id: check_branches
run: |
echo "www_branch_count=$(git ls-remote --heads origin "refs/heads/meta-www" | wc -l)" >> "$GITHUB_OUTPUT"
echo "fbsource_branch_count=$(git ls-remote --heads origin "refs/heads/meta-fbsource" | wc -l)" >> "$GITHUB_OUTPUT"
- uses: actions/setup-node@v3
with:
node-version: 18.x
- run: npm init -y
- run: npm install node-fetch@2
- name: Download and unzip artifacts
uses: actions/github-script@v6
env:
CIRCLECI_TOKEN: ${{secrets.CIRCLECI_TOKEN_DIFFTRAIN}}
with:
script: |
const cp = require('child_process');
const fetch = require('node-fetch');
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
@ -69,10 +64,10 @@ jobs:
const ciBuildId = /\/facebook\/react\/([0-9]+)/.exec(
status.target_url,
)[1];
console.log(`CircleCI build id found: ${ciBuildId}`);
if (Number.parseInt(ciBuildId, 10) + '' === ciBuildId) {
artifactsUrl =
`https://circleci.com/api/v1.1/project/github/facebook/react/${ciBuildId}/artifacts`;
console.log(`Found artifactsUrl: ${artifactsUrl}`);
break spinloop;
} else {
throw new Error(`${ciBuildId} isn't a number`);
@ -91,21 +86,13 @@ jobs:
await sleep(60_000);
}
if (artifactsUrl != null) {
const {CIRCLECI_TOKEN} = process.env;
const res = await fetch(artifactsUrl, {
headers: {
'Circle-Token': CIRCLECI_TOKEN
}
});
const res = await fetch(artifactsUrl);
const data = await res.json();
if (!Array.isArray(data) && data.message != null) {
throw `CircleCI returned: ${data.message}`;
}
for (const artifact of data) {
if (artifact.path === 'build.tgz') {
console.log(`Downloading and unzipping ${artifact.url}`);
await execHelper(
`curl -L ${artifact.url} -H "Circle-Token: ${CIRCLECI_TOKEN}" | tar -xvz`
`curl -L ${artifact.url} | tar -xvz`
);
}
}
@ -115,9 +102,9 @@ jobs:
- name: Strip @license from eslint plugin and react-refresh
run: |
sed -i -e 's/ @license React*//' \
build/oss-experimental/eslint-plugin-react-hooks/cjs/eslint-plugin-react-hooks.development.js \
build/oss-experimental/react-refresh/cjs/react-refresh-babel.development.js
- name: Move relevant files for React in www into compiled
build/oss-stable/eslint-plugin-react-hooks/cjs/eslint-plugin-react-hooks.development.js \
build/oss-stable/react-refresh/cjs/react-refresh-babel.development.js
- name: Move relevant files into compiled
run: |
mkdir -p ./compiled
mkdir -p ./compiled/facebook-www
@ -130,7 +117,7 @@ jobs:
mv build/WARNINGS ./compiled/facebook-www/WARNINGS
# Copy eslint-plugin-react-hooks into facebook-www
mv build/oss-experimental/eslint-plugin-react-hooks/cjs/eslint-plugin-react-hooks.development.js \
mv build/oss-stable/eslint-plugin-react-hooks/cjs/eslint-plugin-react-hooks.development.js \
./compiled/facebook-www/eslint-plugin-react-hooks.js
# Copy unstable_server-external-runtime.js into facebook-www
@ -138,46 +125,21 @@ jobs:
./compiled/facebook-www/unstable_server-external-runtime.js
# Copy react-refresh-babel.development.js into babel-plugin-react-refresh
mv build/oss-experimental/react-refresh/cjs/react-refresh-babel.development.js \
mv build/oss-stable/react-refresh/cjs/react-refresh-babel.development.js \
./compiled/babel-plugin-react-refresh/index.js
ls -R ./compiled
- name: Move relevant files for React in fbsource into compiled-rn
run: |
BASE_FOLDER='compiled-rn/facebook-fbsource/xplat/js'
mkdir -p ${BASE_FOLDER}/react-native-github/Libraries/Renderer/
mkdir -p ${BASE_FOLDER}/RKJSModules/vendor/{scheduler,react,react-is,react-test-renderer}/
# Move React Native renderer
mv build/react-native/implementations/ $BASE_FOLDER/react-native-github/Libraries/Renderer/
mv build/react-native/shims/ $BASE_FOLDER/react-native-github/Libraries/Renderer/
mv build/facebook-react-native/scheduler/cjs/ $BASE_FOLDER/RKJSModules/vendor/scheduler/
mv build/facebook-react-native/react/cjs/ $BASE_FOLDER/RKJSModules/vendor/react/
mv build/facebook-react-native/react-is/cjs/ $BASE_FOLDER/RKJSModules/vendor/react-is/
mv build/facebook-react-native/react-test-renderer/cjs/ $BASE_FOLDER/RKJSModules/vendor/react-test-renderer/
# Delete OSS renderer. OSS renderer is synced through internal script.
RENDERER_FOLDER=$BASE_FOLDER/react-native-github/Libraries/Renderer/implementations/
rm $RENDERER_FOLDER/ReactFabric-{dev,prod,profiling}.js
rm $RENDERER_FOLDER/ReactNativeRenderer-{dev,prod,profiling}.js
ls -R ./compiled
- name: Add REVISION file
- name: Add REVISION files
run: |
echo ${{ github.sha }} >> ./compiled/facebook-www/REVISION
echo ${{ github.sha }} >> ./compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/REVISION
cp ./compiled/facebook-www/REVISION ./compiled/facebook-www/REVISION_TRANSFORMS
- uses: actions/upload-artifact@v3
with:
name: compiled
path: compiled/
- uses: actions/upload-artifact@v3
with:
name: compiled-rn
path: compiled-rn/
commit_www_artifacts:
commit_artifacts:
needs: download_artifacts
if: ${{ (github.ref == 'refs/heads/main' && needs.download_artifacts.outputs.www_branch_count == '0') || github.ref == 'refs/heads/meta-www' }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
@ -190,59 +152,15 @@ jobs:
name: compiled
path: compiled/
- run: git status -u
- name: Check if only the REVISION file has changed
id: check_should_commit
run: |
if git status --porcelain | grep -qv '/REVISION$'; then
echo "should_commit=true" >> "$GITHUB_OUTPUT"
else
echo "should_commit=false" >> "$GITHUB_OUTPUT"
fi
- name: Commit changes to branch
if: steps.check_should_commit.outputs.should_commit == 'true'
uses: stefanzweifel/git-auto-commit-action@v4
with:
commit_message: |
${{ github.event.head_commit.message }}
DiffTrain build for [${{ github.sha }}](https://github.com/facebook/react/commit/${{ github.sha }})
[View git log for this commit](https://github.com/facebook/react/commits/${{ github.sha }})
branch: builds/facebook-www
commit_user_name: ${{ github.actor }}
commit_user_email: ${{ github.actor }}@users.noreply.github.com
create_branch: true
commit_fbsource_artifacts:
needs: download_artifacts
runs-on: ubuntu-latest
if: ${{ (github.ref == 'refs/heads/main' && needs.download_artifacts.outputs.fbsource_branch_count == '0') || github.ref == 'refs/heads/meta-fbsource' }}
steps:
- uses: actions/checkout@v3
with:
ref: main
repository: facebook/react-fbsource-import
token: ${{secrets.FBSOURCE_SYNC_PUSH_TOKEN}}
- name: Ensure clean directory
run: rm -rf compiled-rn
- uses: actions/download-artifact@v3
with:
name: compiled-rn
path: compiled-rn/
- run: git status -u
- name: Check if only the REVISION file has changed
id: check_should_commit
run: |
if git status --porcelain | grep -qv '/REVISION$'; then
echo "should_commit=true" >> "$GITHUB_OUTPUT"
else
echo "should_commit=false" >> "$GITHUB_OUTPUT"
fi
- name: Commit changes to branch
if: steps.check_should_commit.outputs.should_commit == 'true'
uses: stefanzweifel/git-auto-commit-action@v4
with:
commit_message: |
${{ github.event.head_commit.message }}
DiffTrain build for commit https://github.com/facebook/react/commit/${{ github.sha }}.
commit_user_name: ${{ github.actor }}
commit_user_email: ${{ github.actor }}@users.noreply.github.com

2
.nvmrc
View File

@ -1 +1 @@
v16.19.1
v14.17.6

View File

@ -1,4 +1,4 @@
# [React](https://reactjs.org/) &middot; [![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/facebook/react/blob/main/LICENSE) [![npm version](https://img.shields.io/npm/v/react.svg?style=flat)](https://www.npmjs.com/package/react) [![CircleCI Status](https://circleci.com/gh/facebook/react.svg?style=shield)](https://circleci.com/gh/facebook/react) [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](https://reactjs.org/docs/how-to-contribute.html#your-first-pull-request)
# [React](https://reactjs.org/) &middot; [![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/facebook/react/blob/main/LICENSE) [![npm version](https://img.shields.io/npm/v/react.svg?style=flat)](https://www.npmjs.com/package/react) [![CircleCI Status](https://circleci.com/gh/facebook/react.svg?style=shield&circle-token=:circle-token)](https://circleci.com/gh/facebook/react) [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](https://reactjs.org/docs/how-to-contribute.html#your-first-pull-request)
React is a JavaScript library for building user interfaces.

View File

@ -7,12 +7,12 @@
//
// The @latest channel uses the version as-is, e.g.:
//
// 18.3.0
// 18.0.0
//
// The @canary channel appends additional information, with the scheme
// The @next channel appends additional information, with the scheme
// <version>-<label>-<commit_sha>, e.g.:
//
// 18.3.0-canary-a1c2d3e4
// 18.0.0-alpha-a1c2d3e4
//
// The @experimental channel doesn't include a version, only a date and a sha, e.g.:
//
@ -20,13 +20,9 @@
const ReactVersion = '18.3.0';
// The label used by the @canary channel. Represents the upcoming release's
// stability. Most of the time, this will be "canary", but we may temporarily
// choose to change it to "alpha", "beta", "rc", etc.
//
// It only affects the label used in the version string. To customize the
// npm dist tags used during publish, refer to .circleci/config.yml.
const canaryChannelLabel = 'canary';
// The label used by the @next channel. Represents the upcoming release's
// stability. Could be "alpha", "beta", "rc", etc.
const nextChannelLabel = 'next';
const stablePackages = {
'eslint-plugin-react-hooks': '5.0.0',
@ -44,14 +40,14 @@ const stablePackages = {
scheduler: '0.24.0',
};
// These packages do not exist in the @canary or @latest channel, only
// These packages do not exist in the @next or @latest channel, only
// @experimental. We don't use semver, just the commit sha, so this is just a
// list of package names instead of a map.
const experimentalPackages = [];
module.exports = {
ReactVersion,
canaryChannelLabel,
nextChannelLabel,
stablePackages,
experimentalPackages,
};

View File

@ -5,13 +5,12 @@
"@babel/preset-env": "^7.10.4",
"@babel/preset-react": "^7.10.4",
"babel-loader": "^8.1.0",
"react": "^18.2.0",
"react-art": "^18.2.0",
"react-dom": "^18.2.0",
"react": "link:../../build/node_modules/react",
"react-art": "link:../../build/node_modules/react-art/",
"react-dom": "link:../../build/node_modules/react-dom",
"webpack": "^1.14.0"
},
"scripts": {
"prebuild": "cp -r ../../build/oss-experimental/* ./node_modules/",
"build": "webpack app.js bundle.js"
}
}

View File

@ -1007,11 +1007,6 @@ arrify@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d"
art@^0.10.1:
version "0.10.3"
resolved "https://registry.yarnpkg.com/art/-/art-0.10.3.tgz#b01d84a968ccce6208df55a733838c96caeeaea2"
integrity sha512-HXwbdofRTiJT6qZX/FnchtldzJjS3vkLJxQilc3Xj+ma2MXjY4UAyQ0ls1XZYVnDvVIBiFZbC6QsvtW86TD6tQ==
asn1@~0.2.3:
version "0.2.3"
resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.3.tgz#dac8787713c9966849fc8180777ebe9c1ddf3b86"
@ -1291,14 +1286,6 @@ core-util-is@~1.0.0:
version "1.0.2"
resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
create-react-class@^15.6.2:
version "15.7.0"
resolved "https://registry.yarnpkg.com/create-react-class/-/create-react-class-15.7.0.tgz#7499d7ca2e69bb51d13faf59bd04f0c65a1d6c1e"
integrity sha512-QZv4sFWG9S5RUvkTYWbflxeZX+JG7Cz0Tn33rQBJ+WFQTqTfUTjMjiv9tnfXazjsO5r0KhPs+AqCjyrQX6h2ng==
dependencies:
loose-envify "^1.3.1"
object-assign "^4.1.1"
cryptiles@2.x.x:
version "2.0.5"
resolved "https://registry.yarnpkg.com/cryptiles/-/cryptiles-2.0.5.tgz#3bdfecdc608147c1c67202fa291e7dca59eaa3b8"
@ -1774,7 +1761,7 @@ js-tokens@^3.0.0:
version "3.0.1"
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.1.tgz#08e9f132484a2c45a30907e9dc4d5567b7f114d7"
"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0:
js-tokens@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499"
integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==
@ -1910,13 +1897,6 @@ loose-envify@^1.0.0:
dependencies:
js-tokens "^3.0.0"
loose-envify@^1.1.0, loose-envify@^1.3.1:
version "1.4.0"
resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf"
integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==
dependencies:
js-tokens "^3.0.0 || ^4.0.0"
make-dir@^2.0.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-2.1.0.tgz#5f0310e18b8be898cc07009295a30ae41e91e6f5"
@ -2086,10 +2066,9 @@ oauth-sign@~0.8.1:
version "0.8.2"
resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.8.2.tgz#46a6ab7f0aead8deae9ec0565780b7d4efeb9d43"
object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1:
object-assign@^4.0.1, object-assign@^4.1.0:
version "4.1.1"
resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==
object-keys@^1.0.11, object-keys@^1.0.12:
version "1.1.1"
@ -2272,30 +2251,17 @@ rc@^1.1.7:
minimist "^1.2.0"
strip-json-comments "~2.0.1"
react-art@^18.2.0:
version "18.2.0"
resolved "https://registry.yarnpkg.com/react-art/-/react-art-18.2.0.tgz#73b3929b1a0ce781b088bce76186d3793f0106c5"
integrity sha512-HfSK9OBtPIpkdI4QZAyWSxCIbM/I7+nqjybxp2FLmiFS7RN+eCEvOY0KdPw+6//B1oIU31t2o35s5EEhe0Fodw==
dependencies:
art "^0.10.1"
create-react-class "^15.6.2"
loose-envify "^1.1.0"
scheduler "^0.23.0"
"react-art@link:../../build/node_modules/react-art":
version "0.0.0"
uid ""
react-dom@^18.2.0:
version "18.2.0"
resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-18.2.0.tgz#22aaf38708db2674ed9ada224ca4aa708d821e3d"
integrity sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==
dependencies:
loose-envify "^1.1.0"
scheduler "^0.23.0"
"react-dom@link:../../build/node_modules/react-dom":
version "0.0.0"
uid ""
react@^18.2.0:
version "18.2.0"
resolved "https://registry.yarnpkg.com/react/-/react-18.2.0.tgz#555bd98592883255fa00de14f1151a917b5d77d5"
integrity sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==
dependencies:
loose-envify "^1.1.0"
"react@link:../../build/node_modules/react":
version "0.0.0"
uid ""
"readable-stream@^2.0.0 || ^1.1.13", readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.5, readable-stream@^2.1.4, readable-stream@^2.2.6:
version "2.2.6"
@ -2475,13 +2441,6 @@ safe-buffer@~5.1.1:
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d"
integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==
scheduler@^0.23.0:
version "0.23.0"
resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.23.0.tgz#ba8041afc3d30eb206a487b6b384002e4e61fdfe"
integrity sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==
dependencies:
loose-envify "^1.1.0"
schema-utils@^2.6.5:
version "2.7.0"
resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-2.7.0.tgz#17151f76d8eae67fbbf77960c33c676ad9f4efc7"

View File

@ -1998,7 +1998,7 @@
| `colSpan=(null)`| (initial, ssr error, ssr mismatch)| `<number: 1>` |
| `colSpan=(undefined)`| (initial, ssr error, ssr mismatch)| `<number: 1>` |
## `content` (on `<meta>` inside `<head>`)
## `content` (on `<meta>` inside `<div>`)
| Test Case | Flags | Result |
| --- | --- | --- |
| `content=(string)`| (changed)| `"a string"` |
@ -5123,7 +5123,7 @@
| `htmlFor=(null)`| (initial)| `<empty string>` |
| `htmlFor=(undefined)`| (initial)| `<empty string>` |
## `http-equiv` (on `<meta>` inside `<head>`)
## `http-equiv` (on `<meta>` inside `<div>`)
| Test Case | Flags | Result |
| --- | --- | --- |
| `http-equiv=(string)`| (changed, warning)| `"a string"` |
@ -5148,7 +5148,7 @@
| `http-equiv=(null)`| (initial, warning)| `<empty string>` |
| `http-equiv=(undefined)`| (initial, warning)| `<empty string>` |
## `httpEquiv` (on `<meta>` inside `<head>`)
## `httpEquiv` (on `<meta>` inside `<div>`)
| Test Case | Flags | Result |
| --- | --- | --- |
| `httpEquiv=(string)`| (changed)| `"a string"` |
@ -6198,31 +6198,6 @@
| `lang=(null)`| (initial)| `<empty string>` |
| `lang=(undefined)`| (initial)| `<empty string>` |
## `lang` (on `<html>` inside `<document>`)
| Test Case | Flags | Result |
| --- | --- | --- |
| `lang=(string)`| (changed, ssr mismatch)| `"a string"` |
| `lang=(empty string)`| (initial)| `<empty string>` |
| `lang=(array with string)`| (changed, ssr mismatch)| `"string"` |
| `lang=(empty array)`| (initial)| `<empty string>` |
| `lang=(object)`| (changed, ssr mismatch)| `"result of toString()"` |
| `lang=(numeric string)`| (changed, ssr mismatch)| `"42"` |
| `lang=(-1)`| (changed, ssr mismatch)| `"-1"` |
| `lang=(0)`| (changed, ssr mismatch)| `"0"` |
| `lang=(integer)`| (changed, ssr mismatch)| `"1"` |
| `lang=(NaN)`| (changed, warning, ssr mismatch)| `"NaN"` |
| `lang=(float)`| (changed, ssr mismatch)| `"99.99"` |
| `lang=(true)`| (initial, warning)| `<empty string>` |
| `lang=(false)`| (initial, warning)| `<empty string>` |
| `lang=(string 'true')`| (changed, ssr mismatch)| `"true"` |
| `lang=(string 'false')`| (changed, ssr mismatch)| `"false"` |
| `lang=(string 'on')`| (changed, ssr mismatch)| `"on"` |
| `lang=(string 'off')`| (changed, ssr mismatch)| `"off"` |
| `lang=(symbol)`| (initial, warning)| `<empty string>` |
| `lang=(function)`| (initial, warning)| `<empty string>` |
| `lang=(null)`| (initial)| `<empty string>` |
| `lang=(undefined)`| (initial)| `<empty string>` |
## `length` (on `<div>` inside `<div>`)
| Test Case | Flags | Result |
| --- | --- | --- |
@ -11398,56 +11373,6 @@
| `transform=(null)`| (initial)| `[]` |
| `transform=(undefined)`| (initial)| `[]` |
## `transform-origin` (on `<svg>` inside `<div>`)
| Test Case | Flags | Result |
| --- | --- | --- |
| `transform-origin=(string)`| (changed, warning)| `"a string"` |
| `transform-origin=(empty string)`| (changed, warning)| `<empty string>` |
| `transform-origin=(array with string)`| (changed, warning)| `"string"` |
| `transform-origin=(empty array)`| (changed, warning)| `<empty string>` |
| `transform-origin=(object)`| (changed, warning)| `"result of toString()"` |
| `transform-origin=(numeric string)`| (changed, warning)| `"42"` |
| `transform-origin=(-1)`| (changed, warning)| `"-1"` |
| `transform-origin=(0)`| (changed, warning)| `"0"` |
| `transform-origin=(integer)`| (changed, warning)| `"1"` |
| `transform-origin=(NaN)`| (changed, warning)| `"NaN"` |
| `transform-origin=(float)`| (changed, warning)| `"99.99"` |
| `transform-origin=(true)`| (initial, warning)| `<null>` |
| `transform-origin=(false)`| (initial, warning)| `<null>` |
| `transform-origin=(string 'true')`| (changed, warning)| `"true"` |
| `transform-origin=(string 'false')`| (changed, warning)| `"false"` |
| `transform-origin=(string 'on')`| (changed, warning)| `"on"` |
| `transform-origin=(string 'off')`| (changed, warning)| `"off"` |
| `transform-origin=(symbol)`| (initial, warning)| `<null>` |
| `transform-origin=(function)`| (initial, warning)| `<null>` |
| `transform-origin=(null)`| (initial, warning)| `<null>` |
| `transform-origin=(undefined)`| (initial, warning)| `<null>` |
## `transformOrigin` (on `<svg>` inside `<div>`)
| Test Case | Flags | Result |
| --- | --- | --- |
| `transformOrigin=(string)`| (changed)| `"a string"` |
| `transformOrigin=(empty string)`| (changed)| `<empty string>` |
| `transformOrigin=(array with string)`| (changed)| `"string"` |
| `transformOrigin=(empty array)`| (changed)| `<empty string>` |
| `transformOrigin=(object)`| (changed)| `"result of toString()"` |
| `transformOrigin=(numeric string)`| (changed)| `"42"` |
| `transformOrigin=(-1)`| (changed)| `"-1"` |
| `transformOrigin=(0)`| (changed)| `"0"` |
| `transformOrigin=(integer)`| (changed)| `"1"` |
| `transformOrigin=(NaN)`| (changed, warning)| `"NaN"` |
| `transformOrigin=(float)`| (changed)| `"99.99"` |
| `transformOrigin=(true)`| (initial, warning)| `<null>` |
| `transformOrigin=(false)`| (initial, warning)| `<null>` |
| `transformOrigin=(string 'true')`| (changed)| `"true"` |
| `transformOrigin=(string 'false')`| (changed)| `"false"` |
| `transformOrigin=(string 'on')`| (changed)| `"on"` |
| `transformOrigin=(string 'off')`| (changed)| `"off"` |
| `transformOrigin=(symbol)`| (initial, warning)| `<null>` |
| `transformOrigin=(function)`| (initial, warning)| `<null>` |
| `transformOrigin=(null)`| (initial)| `<null>` |
| `transformOrigin=(undefined)`| (initial)| `<null>` |
## `type` (on `<button>` inside `<div>`)
| Test Case | Flags | Result |
| --- | --- | --- |
@ -12551,23 +12476,23 @@
## `viewTarget` (on `<view>` inside `<svg>`)
| Test Case | Flags | Result |
| --- | --- | --- |
| `viewTarget=(string)`| (changed)| `"a string"` |
| `viewTarget=(empty string)`| (changed)| `<empty string>` |
| `viewTarget=(array with string)`| (changed)| `"string"` |
| `viewTarget=(empty array)`| (changed)| `<empty string>` |
| `viewTarget=(object)`| (changed)| `"result of toString()"` |
| `viewTarget=(numeric string)`| (changed)| `"42"` |
| `viewTarget=(-1)`| (changed)| `"-1"` |
| `viewTarget=(0)`| (changed)| `"0"` |
| `viewTarget=(integer)`| (changed)| `"1"` |
| `viewTarget=(NaN)`| (changed, warning)| `"NaN"` |
| `viewTarget=(float)`| (changed)| `"99.99"` |
| `viewTarget=(string)`| (changed, ssr mismatch)| `"a string"` |
| `viewTarget=(empty string)`| (changed, ssr mismatch)| `<empty string>` |
| `viewTarget=(array with string)`| (changed, ssr mismatch)| `"string"` |
| `viewTarget=(empty array)`| (changed, ssr mismatch)| `<empty string>` |
| `viewTarget=(object)`| (changed, ssr mismatch)| `"result of toString()"` |
| `viewTarget=(numeric string)`| (changed, ssr mismatch)| `"42"` |
| `viewTarget=(-1)`| (changed, ssr mismatch)| `"-1"` |
| `viewTarget=(0)`| (changed, ssr mismatch)| `"0"` |
| `viewTarget=(integer)`| (changed, ssr mismatch)| `"1"` |
| `viewTarget=(NaN)`| (changed, warning, ssr mismatch)| `"NaN"` |
| `viewTarget=(float)`| (changed, ssr mismatch)| `"99.99"` |
| `viewTarget=(true)`| (initial, warning)| `<null>` |
| `viewTarget=(false)`| (initial, warning)| `<null>` |
| `viewTarget=(string 'true')`| (changed)| `"true"` |
| `viewTarget=(string 'false')`| (changed)| `"false"` |
| `viewTarget=(string 'on')`| (changed)| `"on"` |
| `viewTarget=(string 'off')`| (changed)| `"off"` |
| `viewTarget=(string 'true')`| (changed, ssr mismatch)| `"true"` |
| `viewTarget=(string 'false')`| (changed, ssr mismatch)| `"false"` |
| `viewTarget=(string 'on')`| (changed, ssr mismatch)| `"on"` |
| `viewTarget=(string 'off')`| (changed, ssr mismatch)| `"off"` |
| `viewTarget=(symbol)`| (initial, warning)| `<null>` |
| `viewTarget=(function)`| (initial, warning)| `<null>` |
| `viewTarget=(null)`| (initial)| `<null>` |

View File

@ -8,7 +8,7 @@
## Instructions
`yarn build --type=UMD_DEV react/index,react-dom && cd fixtures/attribute-behavior && yarn install && yarn dev`
`yarn build --type=UMD_DEV react/index,react-dom && cd fixtures/attribute-behavior && yarn install && yarn start`
## Interpretation

View File

@ -11,9 +11,9 @@
"react-virtualized": "^9.9.0"
},
"scripts": {
"predev":
"cp ../../build/oss-experimental/react/umd/react.development.js public/ && cp ../../build/oss-experimental/react-dom/umd/react-dom.development.js public/ && cp ../../build/oss-experimental/react-dom/umd/react-dom-server-legacy.browser.development.js public/",
"dev": "react-scripts start",
"prestart":
"cp ../../build/node_modules/react/umd/react.development.js public/ && cp ../../build/node_modules/react-dom/umd/react-dom.development.js public/ && cp ../../build/node_modules/react-dom/umd/react-dom-server-legacy.browser.development.js public/",
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test --env=jsdom",
"eject": "react-scripts eject"

View File

@ -237,8 +237,6 @@ function getRenderedAttributeValue(
return document.createElementNS('http://www.w3.org/2000/svg', 'svg');
} else if (containerTagName === 'document') {
return document.implementation.createHTMLDocument('');
} else if (containerTagName === 'head') {
return document.implementation.createHTMLDocument('').head;
} else {
return document.createElement(containerTagName);
}
@ -284,12 +282,12 @@ function getRenderedAttributeValue(
try {
let container = createContainer();
renderer.render(react.createElement(tagName, baseProps), container);
defaultValue = read(container.lastChild);
defaultValue = read(container.firstChild);
canonicalDefaultValue = getCanonicalizedValue(defaultValue);
container = createContainer();
renderer.render(react.createElement(tagName, props), container);
result = read(container.lastChild);
result = read(container.firstChild);
canonicalResult = getCanonicalizedValue(result);
didWarn = _didWarn;
didError = false;
@ -310,12 +308,6 @@ function getRenderedAttributeValue(
);
container = createContainer();
container.innerHTML = html;
} else if (containerTagName === 'head') {
const html = serverRenderer.renderToString(
react.createElement(tagName, props)
);
container = createContainer();
container.innerHTML = html;
} else {
const html = serverRenderer.renderToString(
react.createElement(
@ -772,7 +764,7 @@ class App extends React.Component {
ReactDOMStable:
'https://unpkg.com/react-dom@latest/umd/react-dom.development.js',
ReactDOMServerStable:
'https://unpkg.com/react-dom@latest/umd/react-dom-server-legacy.browser.development.js',
'https://unpkg.com/react-dom@latest/umd/react-dom-server.browser.development.js',
ReactNext: '/react.development.js',
ReactDOMNext: '/react-dom.development.js',
ReactDOMServerNext: '/react-dom-server-legacy.browser.development.js',

View File

@ -356,7 +356,7 @@ const attributes = [
},
{name: 'cols', tagName: 'textarea'},
{name: 'colSpan', containerTagName: 'tr', tagName: 'td'},
{name: 'content', containerTagName: 'head', tagName: 'meta'},
{name: 'content', tagName: 'meta'},
{name: 'contentEditable'},
{
name: 'contentScriptType',
@ -934,13 +934,8 @@ const attributes = [
{name: 'href', tagName: 'a', overrideStringValue: 'https://reactjs.com'},
{name: 'hrefLang', read: getAttribute('hreflang')},
{name: 'htmlFor', tagName: 'label'},
{
name: 'http-equiv',
containerTagName: 'head',
tagName: 'meta',
read: getProperty('httpEquiv'),
},
{name: 'httpEquiv', containerTagName: 'head', tagName: 'meta'},
{name: 'http-equiv', tagName: 'meta', read: getProperty('httpEquiv')},
{name: 'httpEquiv', tagName: 'meta'},
{name: 'icon', tagName: 'command', read: getAttribute('icon')},
{name: 'id'},
{name: 'ID', read: getProperty('id')},
@ -1081,7 +1076,6 @@ const attributes = [
{name: 'label', tagName: 'track'},
{name: 'LANG', read: getProperty('lang')},
{name: 'lang'},
{name: 'lang', containerTagName: 'document', tagName: 'html'},
{name: 'length', read: getAttribute('length')},
{
name: 'lengthAdjust',
@ -1987,16 +1981,6 @@ const attributes = [
overrideStringValue:
'translate(-10,-20) scale(2) rotate(45) translate(5,10)',
},
{
name: 'transform-origin',
tagName: 'svg',
read: getSVGAttribute('transform-origin'),
},
{
name: 'transformOrigin',
tagName: 'svg',
read: getSVGAttribute('transform-origin'),
},
{name: 'type', tagName: 'button', overrideStringValue: 'reset'},
{
name: 'type',

1
fixtures/blocks/.env Normal file
View File

@ -0,0 +1 @@
SKIP_PREFLIGHT_CHECK=true

77
fixtures/blocks/db.json Normal file
View File

@ -0,0 +1,77 @@
{
"posts": [
{
"id": 1,
"userId": 2,
"title": "Welcome",
"body": "Hello, world!"
},
{
"id": 2,
"userId": 3,
"title": "A Guide to useEffect",
"body": "Let me tell you everything about useEffect"
},
{
"id": 3,
"userId": 1,
"title": "Here and There",
"body": "Browsers are smart"
}
],
"comments": [
{
"id": 1,
"body": "Hey there",
"postId": 1,
"userId": 1
},
{
"id": 2,
"body": "Welcome to the chat",
"postId": 1,
"userId": 2
},
{
"id": 3,
"body": "What editor/font are you using?",
"postId": 2,
"userId": 2
},
{
"id": 4,
"body": "It's always been hard",
"postId": 3,
"userId": 1
},
{
"id": 5,
"body": "It's still easy",
"postId": 3,
"userId": 2
}
],
"users": [{
"id": 1,
"name": "Sebastian",
"bioId": 10
}, {
"id": 2,
"name": "Sophie",
"bioId": 20
}, {
"id": 3,
"name": "Dan",
"bioId": 30
}],
"bios": [{
"id": 10,
"text": "I like European movies"
}, {
"id": 20,
"text": "I like math puzzles"
}, {
"id": 30,
"text": "I like reading twitter"
}]
}

14
fixtures/blocks/delay.js Normal file
View File

@ -0,0 +1,14 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
module.exports = (req, res, next) => {
if (req.query.delay) {
setTimeout(next, Number(req.query.delay));
} else {
next();
}
};

View File

@ -0,0 +1,37 @@
{
"name": "blocks",
"version": "0.1.0",
"private": true,
"proxy": "http://localhost:3001/",
"dependencies": {
"concurrently": "^5.2.0",
"json-server": "^0.16.1",
"react": "^16.13.1",
"react-dom": "^16.13.1",
"react-scripts": "3.4.1"
},
"scripts": {
"prestart": "cp -r ../../build/node_modules/* ./node_modules/",
"prebuild": "cp -r ../../build/node_modules/* ./node_modules/",
"start": "concurrently \"npm run start:client\" \"npm run start:api\"",
"start:api": "json-server --watch db.json --port 3001 --delay 1000 --middlewares delay.js",
"start:client": "react-scripts start",
"build": "react-scripts build",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": "react-app"
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
}
}

View File

@ -0,0 +1,12 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Blocks Fixture</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
</body>
</html>

View File

@ -0,0 +1,105 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import React, {
useReducer,
useEffect,
unstable_useTransition as useTransition,
useCallback,
useMemo,
Suspense,
} from 'react';
import {createCache, CacheProvider} from 'react/unstable-cache';
import {RouterProvider} from './client/RouterContext';
// TODO: can't really import a server component on the client.
import App from './server/App';
const initialUrl = window.location.pathname;
const initialState = {
// TODO: use this for invalidation.
cache: createCache(),
url: initialUrl,
pendingUrl: initialUrl,
root: <App route={initialUrl} />,
};
function reducer(state, action) {
switch (action.type) {
case 'startNavigation':
return {
...state,
pendingUrl: action.url,
};
case 'completeNavigation':
// TODO: cancel previous fetch?
return {
...state,
url: action.url,
pendingUrl: action.url,
root: action.root,
};
default:
throw new Error();
}
}
function Router() {
const [state, dispatch] = useReducer(reducer, initialState);
const [startTransition, isPending] = useTransition({
timeoutMs: 1500,
});
useEffect(() => {
document.body.style.cursor = isPending ? 'wait' : '';
}, [isPending]);
const navigate = useCallback(
url => {
startTransition(() => {
// TODO: Here, There, and Everywhere.
// TODO: Instant Transitions, somehow.
dispatch({
type: 'completeNavigation',
root: <App route={url} />,
url,
});
});
dispatch({
type: 'startNavigation',
url,
});
},
[startTransition]
);
useEffect(() => {
const listener = () => {
navigate(window.location.pathname);
};
window.addEventListener('popstate', listener);
return () => window.removeEventListener('popstate', listener);
}, [navigate]);
const routeContext = useMemo(
() => ({
pendingUrl: state.pendingUrl,
url: state.url,
navigate,
}),
[state.url, state.pendingUrl, navigate]
);
return (
<Suspense fallback={<h2>Loading...</h2>}>
<CacheProvider value={state.cache}>
<RouterProvider value={routeContext}>{state.root}</RouterProvider>
</CacheProvider>
</Suspense>
);
}
export default Router;

View File

@ -0,0 +1,25 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import * as React from 'react';
import {useRouter} from './RouterContext';
export default function Link({to, children, ...rest}) {
const {navigate} = useRouter();
return (
<a
href={to}
onClick={e => {
e.preventDefault();
window.history.pushState(null, null, to);
navigate(to);
}}
{...rest}>
{children}
</a>
);
}

View File

@ -0,0 +1,21 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
/* eslint-disable import/first */
import * as React from 'react';
import {TabBar, TabLink} from '../client/TabNav';
export default function ProfileNav({userId}) {
// TODO: Don't hardcode ID.
return (
<TabBar>
<TabLink to={`/profile/${userId}`}>Timeline</TabLink>
<TabLink to={`/profile/${userId}/bio`}>Bio</TabLink>
</TabBar>
);
}

View File

@ -0,0 +1,9 @@
import {createContext, useContext} from 'react';
const RouterContext = createContext(null);
export const RouterProvider = RouterContext.Provider;
export function useRouter() {
return useContext(RouterContext);
}

View File

@ -0,0 +1,31 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import * as React from 'react';
import {TabBar, TabLink} from './TabNav';
// TODO: Error Boundaries.
function MainTabNav() {
return (
<TabBar>
<TabLink to="/">Home</TabLink>
<TabLink to="/profile/3" partial={true}>
Profile
</TabLink>
</TabBar>
);
}
export default function Shell({children}) {
return (
<>
<MainTabNav />
{children}
</>
);
}

View File

@ -0,0 +1,50 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import * as React from 'react';
import Link from './Link';
import {useRouter} from './RouterContext';
export function TabBar({children}) {
return (
<div
style={{
border: '1px solid #aaa',
padding: 20,
marginBottom: 20,
width: 500,
}}>
{children}
</div>
);
}
export function TabLink({to, partial, children}) {
const {pendingUrl: activeUrl} = useRouter();
const active = partial ? activeUrl.startsWith(to) : activeUrl === to;
if (active) {
return (
<b
style={{
display: 'inline-block',
marginRight: 20,
}}>
{children}
</b>
);
}
return (
<Link
style={{
display: 'inline-block',
marginRight: 20,
}}
to={to}>
{children}
</Link>
);
}

View File

@ -0,0 +1,8 @@
body {
font-family: Helvetica;
padding-left: 10px;
}
* {
box-sizing: border-box;
}

View File

@ -0,0 +1,13 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import React from 'react';
import {createRoot} from 'react-dom/client';
import './index.css';
import Router from './Router';
createRoot(document.getElementById('root')).render(<Router />);

View File

@ -0,0 +1,28 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
/* eslint-disable import/first */
import * as React from 'react';
import {matchRoute} from './ServerRouter';
import FeedPage from './FeedPage';
import ProfilePage from './ProfilePage';
// TODO: Replace with asset reference.
import Shell from '../client/Shell';
// TODO: Router component?
const AppRoutes = {
'/': props => <FeedPage {...props} key="home" />,
'/profile/:userId/*': props => (
<ProfilePage {...props} key={`profile-${props.userId}`} />
),
};
export default function App(props) {
const match = matchRoute(props, AppRoutes);
return <Shell>{match}</Shell>;
}

View File

@ -0,0 +1,31 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
/* eslint-disable import/first */
import * as React from 'react';
import {fetch} from 'react-fetch';
// TODO: Replace with asset reference.
import Link from '../client/Link';
export default function Comments({postId}) {
const comments = fetch(`/comments?postId=${postId}&_expand=user`).json();
return (
<>
<h5>Comments</h5>
<ul>
{comments.slice(0, 5).map(comment => (
<li key={comment.id}>
{comment.body}
{' • '}
<Link to={`/profile/${comment.user.id}`}>{comment.user.name}</Link>
</li>
))}
</ul>
</>
);
}

View File

@ -0,0 +1,21 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
/* eslint-disable import/first */
import * as React from 'react';
import {fetch} from 'react-fetch';
import PostList from './PostList';
export default function Feed() {
const posts = fetch('/posts?_expand=user').json();
return (
<>
<h2>Feed</h2>
<PostList posts={posts} />
</>
);
}

View File

@ -0,0 +1,20 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
/* eslint-disable import/first */
import * as React from 'react';
import {Suspense} from 'react';
import PostGlimmer from './PostGlimmer';
import Feed from './Feed';
export default function FeedPage() {
return (
<Suspense fallback={<PostGlimmer />}>
<Feed />
</Suspense>
);
}

View File

@ -0,0 +1,39 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
/* eslint-disable import/first */
import * as React from 'react';
import {Suspense} from 'react';
import Comments from './Comments';
// TODO: Replace with asset reference.
import Link from '../client/Link';
export default function Post({post}) {
return (
<div
style={{
border: '1px solid #aaa',
borderRadius: 10,
marginBottom: 20,
padding: 20,
maxWidth: 500,
}}>
<h4 style={{marginTop: 0}}>
{post.title}
{' by '}
<Link to={`/profile/${post.user.id}`}>{post.user.name}</Link>
</h4>
<p>{post.body}</p>
<Suspense
fallback={<h5>Loading comments...</h5>}
unstable_avoidThisFallback={true}>
<Comments postId={post.id} />
</Suspense>
</div>
);
}

View File

@ -0,0 +1,56 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
/* eslint-disable import/first */
import * as React from 'react';
export default function PostGlimmer() {
return (
<div
style={{
border: '1px solid #aaa',
borderRadius: 10,
marginBottom: 20,
padding: 20,
maxWidth: 500,
height: 180,
}}>
<div
style={{
marginBottom: 20,
width: '50%',
height: 20,
background: '#ddd',
}}
/>
<div
style={{
marginBottom: 20,
width: '60%',
height: 20,
background: '#eee',
}}
/>
<div
style={{
marginBottom: 20,
width: '50%',
height: 20,
background: '#eee',
}}
/>
<div
style={{
marginBottom: 20,
width: '60%',
height: 20,
background: '#eee',
}}
/>
</div>
);
}

View File

@ -0,0 +1,28 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
/* eslint-disable import/first */
import * as React from 'react';
import {Suspense, unstable_SuspenseList as SuspenseList} from 'react';
import {preload} from 'react-fetch';
import PostGlimmer from './PostGlimmer';
import Post from './Post';
export default function PostList({posts}) {
return (
<SuspenseList revealOrder="forwards" tail="collapsed">
{posts.map(post => {
preload(`/comments?postId=${post.id}&_expand=user`);
return (
<Suspense key={post.id} fallback={<PostGlimmer />}>
<Post post={post} />
</Suspense>
);
})}
</SuspenseList>
);
}

View File

@ -0,0 +1,21 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
/* eslint-disable import/first */
import * as React from 'react';
import {fetch} from 'react-fetch';
export default function ProfileBio({userId}) {
const user = fetch(`/users/${userId}`).json();
const bio = fetch(`/bios/${user.bioId}`).json().text;
return (
<>
<h3>{user.name}'s Bio</h3>
<p>{bio}</p>
</>
);
}

View File

@ -0,0 +1,34 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import * as React from 'react';
import {Suspense} from 'react';
import {fetch} from 'react-fetch';
import {matchRoute} from './ServerRouter';
import ProfileTimeline from './ProfileTimeline';
import ProfileBio from './ProfileBio';
// TODO: Replace with asset reference.
import ProfileNav from '../client/ProfileNav';
// TODO: Router component?
const ProfileRoutes = {
'/': props => <ProfileTimeline {...props} key="timeline" />,
'/bio': props => <ProfileBio {...props} key="bio" />,
};
export default function ProfilePage(props) {
const user = fetch(`/users/${props.userId}`).json();
const match = matchRoute(props, ProfileRoutes);
return (
<>
<h2>{user.name}</h2>
<ProfileNav userId={user.id} />
<Suspense fallback={<h3>Loading...</h3>}>{match}</Suspense>
</>
);
}

View File

@ -0,0 +1,16 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
/* eslint-disable import/first */
import * as React from 'react';
import {fetch} from 'react-fetch';
import PostList from './PostList';
export default function ProfileTimeline({userId}) {
const posts = fetch(`/posts?userId=${userId}&_expand=user`).json();
return <PostList posts={posts} />;
}

View File

@ -0,0 +1,54 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
/* eslint-disable import/first */
function tryMatch(props, def) {
const defSegments = def.split('/').filter(Boolean);
const routeSegments = props.route.split('/').filter(Boolean);
let innerProps = {...props};
while (routeSegments.length > 0) {
if (defSegments.length === 0) {
return null;
}
const urlSegment = routeSegments.shift();
const defSegment = defSegments.shift();
if (urlSegment === defSegment) {
continue;
}
if (defSegment[0] === ':') {
innerProps[defSegment.slice(1)] = urlSegment;
continue;
}
if (defSegment === '*') {
innerProps.route = '/' + urlSegment + routeSegments.join('/');
return innerProps;
}
return null;
}
if (defSegments.length === 0) {
return innerProps;
}
if (defSegments.length === 1 && defSegments[0] === '*') {
innerProps.route = '/';
return innerProps;
}
return null;
}
export function matchRoute(props, defs) {
for (let def in defs) {
if (!defs.hasOwnProperty(def)) {
continue;
}
const innerProps = tryMatch(props, def);
if (innerProps) {
const match = defs[def](innerProps);
return match;
}
}
throw Error('Not found.');
}

11154
fixtures/blocks/yarn.lock Normal file

File diff suppressed because it is too large Load Diff

View File

@ -11,8 +11,8 @@
"victory": "^0.25.6"
},
"scripts": {
"copy-source": "cp -r ../../../build/oss-experimental/* ./node_modules/",
"dev": "react-scripts start",
"copy-source": "cp -r ../../../build/node_modules/* ./node_modules/",
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test --env=jsdom",
"eject": "react-scripts eject"

View File

@ -22,7 +22,7 @@ class App extends PureComponent {
}
const multiplier = input.length !== 0 ? input.length : 1;
const complexity =
(parseInt(window.location.search.slice(1), 10) / 100) * 25 || 25;
(parseInt(window.location.search.substring(1), 10) / 100) * 25 || 25;
const data = _.range(5).map(t =>
_.range(complexity * multiplier).map((j, i) => {
return {

View File

@ -15,8 +15,8 @@
<script src="https://unpkg.com/scheduler@canary/umd/scheduler-tracing.development.js"></script>
<script src="https://unpkg.com/react@canary/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@canary/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/react-cache@canary/umd/react-cache.development.js"></script>
<script src="https://unpkg.com/react-cache@next/umd/react-cache.development.js"></script>
<!-- Don't use this in production: -->
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
</head>
@ -38,4 +38,4 @@
Learn more at https://reactjs.org/docs/getting-started.html
-->
</body>
</html>
</html>

View File

@ -11,12 +11,12 @@
__REACT_DEVTOOLS_GLOBAL_HOOK__ = parent.__REACT_DEVTOOLS_GLOBAL_HOOK__;
</script>
<script src="https://unpkg.com/scheduler@canary/umd/scheduler.development.js"></script>
<script src="https://unpkg.com/scheduler@canary/umd/scheduler-tracing.development.js"></script>
<script src="https://unpkg.com/react@canary/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@canary/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/react-cache@canary/umd/react-cache.development.js"></script>
<script src="https://unpkg.com/scheduler@next/umd/scheduler.development.js"></script>
<script src="https://unpkg.com/scheduler@next/umd/scheduler-tracing.development.js"></script>
<script src="https://unpkg.com/react@next/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@next/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/react-cache@next/umd/react-cache.development.js"></script>
<!-- Don't use this in production: -->
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
</head>
@ -38,4 +38,4 @@
Learn more at https://reactjs.org/docs/getting-started.html
-->
</body>
</html>
</html>

View File

@ -1,4 +1,4 @@
/* eslint-disable react/react-in-jsx-scope, react/jsx-no-undef */
/* eslint-disable no-fallthrough, react/react-in-jsx-scope, react/jsx-no-undef */
/* global React ReactCache ReactDOM SchedulerTracing ScheduleTracing */
const apps = [];

View File

@ -18,7 +18,7 @@ const DEPENDENCIES = [
['react-dom/umd/react-dom.development.js', 'react-dom.js'],
];
const BUILD_DIRECTORY = '../../../build/oss-experimental/';
const BUILD_DIRECTORY = '../../../build/node_modules/';
const DEPENDENCIES_DIRECTORY = 'dependencies';
function initDependencies() {

View File

@ -334,11 +334,6 @@
},
});
class Foo {
flag = false;
object = {a: {b: {c: {d: 1}}}}
}
function UnserializableProps() {
return (
<ChildComponent
@ -348,7 +343,6 @@
setOfSets={setOfSets}
typedArray={typedArray}
immutable={immutable}
classInstance={new Foo()}
/>
);
}

View File

@ -11,7 +11,7 @@
"classnames": "^2.2.5",
"codemirror": "^5.40.0",
"core-js": "^2.4.1",
"jest-diff": "^29.4.1",
"jest-diff": "^25.1.0",
"prop-types": "^15.6.0",
"query-string": "^4.2.3",
"react": "^15.4.1",
@ -19,8 +19,8 @@
"semver": "^5.5.0"
},
"scripts": {
"dev": "react-scripts start",
"predev": "cp ../../build/oss-stable/scheduler/umd/scheduler-unstable_mock.development.js ../../build/oss-stable/scheduler/umd/scheduler-unstable_mock.production.min.js ../../build/oss-stable/react/umd/react.development.js ../../build/oss-stable/react-dom/umd/react-dom.development.js ../../build/oss-stable/react/umd/react.production.min.js ../../build/oss-stable/react-dom/umd/react-dom.production.min.js ../../build/oss-stable/react-dom/umd/react-dom-server.browser.development.js ../../build/oss-stable/react-dom/umd/react-dom-server.browser.production.min.js ../../build/oss-stable/react-dom/umd/react-dom-test-utils.development.js ../../build/oss-stable/react-dom/umd/react-dom-test-utils.production.min.js public/ && cp -a ../../build/oss-stable/. node_modules",
"start": "react-scripts start",
"prestart": "cp ../../build/oss-stable/scheduler/umd/scheduler-unstable_mock.development.js ../../build/oss-stable/scheduler/umd/scheduler-unstable_mock.production.min.js ../../build/oss-stable/react/umd/react.development.js ../../build/oss-stable/react-dom/umd/react-dom.development.js ../../build/oss-stable/react/umd/react.production.min.js ../../build/oss-stable/react-dom/umd/react-dom.production.min.js ../../build/oss-stable/react-dom/umd/react-dom-server.browser.development.js ../../build/oss-stable/react-dom/umd/react-dom-server.browser.production.min.js ../../build/oss-stable/react-dom/umd/react-dom-test-utils.development.js ../../build/oss-stable/react-dom/umd/react-dom-test-utils.production.min.js public/ && cp -a ../../build/oss-stable/. node_modules",
"build": "react-scripts build && cp build/index.html build/200.html",
"test": "react-scripts test --env=jsdom",
"eject": "react-scripts eject"

View File

@ -11,7 +11,7 @@ import semver from 'semver';
function parseQuery(qstr) {
var query = {};
var a = qstr.slice(1).split('&');
var a = qstr.substr(1).split('&');
for (var i = 0; i < a.length; i++) {
var b = a[i].split('=');

View File

@ -1,7 +1,7 @@
// copied from scripts/jest/matchers/toWarnDev.js
'use strict';
const {diff: jestDiff} = require('jest-diff');
const jestDiff = require('jest-diff').default;
const util = require('util');
function shouldIgnoreConsoleError(format, args) {

View File

@ -7,17 +7,47 @@
resolved "https://registry.yarnpkg.com/@babel/standalone/-/standalone-7.12.10.tgz#f77f6750d0ab88c7c23234dd2d2f3800f170a573"
integrity sha512-e3sJ7uwwjiGWv7qeATKrP+Mjltr6JEurPh3yR0dBb9ie2YDnKl52lO82f+Ha+HAtyxTHfsPIXwgFmWKsCT2zOQ==
"@jest/schemas@^29.4.0":
version "29.4.0"
resolved "https://registry.yarnpkg.com/@jest/schemas/-/schemas-29.4.0.tgz#0d6ad358f295cc1deca0b643e6b4c86ebd539f17"
integrity sha512-0E01f/gOZeNTG76i5eWWSupvSHaIINrTie7vCyjiYFKgzNdyEGd12BUv4oNBFHOqlHDbtoJi3HrQ38KCC90NsQ==
"@jest/types@^25.5.0":
version "25.5.0"
resolved "https://registry.yarnpkg.com/@jest/types/-/types-25.5.0.tgz#4d6a4793f7b9599fc3680877b856a97dbccf2a9d"
integrity sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==
dependencies:
"@sinclair/typebox" "^0.25.16"
"@types/istanbul-lib-coverage" "^2.0.0"
"@types/istanbul-reports" "^1.1.1"
"@types/yargs" "^15.0.0"
chalk "^3.0.0"
"@sinclair/typebox@^0.25.16":
version "0.25.21"
resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.25.21.tgz#763b05a4b472c93a8db29b2c3e359d55b29ce272"
integrity sha512-gFukHN4t8K4+wVC+ECqeqwzBDeFeTzBXroBTqE6vcWrQGbEUpHO7LYdG0f4xnvYq4VOEwITSlHlp0JBAIFMS/g==
"@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0":
version "2.0.3"
resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz#4ba8ddb720221f432e443bd5f9117fd22cfd4762"
integrity sha512-sz7iLqvVUg1gIedBOvlkxPlc8/uVzyS5OwGz1cKjXzkl3FpL3al0crU8YGU1WoHkxn0Wxbw5tyi6hvzJKNzFsw==
"@types/istanbul-lib-report@*":
version "3.0.0"
resolved "https://registry.yarnpkg.com/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz#c14c24f18ea8190c118ee7562b7ff99a36552686"
integrity sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==
dependencies:
"@types/istanbul-lib-coverage" "*"
"@types/istanbul-reports@^1.1.1":
version "1.1.2"
resolved "https://registry.yarnpkg.com/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz#e875cc689e47bce549ec81f3df5e6f6f11cfaeb2"
integrity sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw==
dependencies:
"@types/istanbul-lib-coverage" "*"
"@types/istanbul-lib-report" "*"
"@types/yargs-parser@*":
version "15.0.0"
resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-15.0.0.tgz#cb3f9f741869e20cce330ffbeb9271590483882d"
integrity sha512-FA/BWv8t8ZWJ+gEOnLLd8ygxH/2UFbAvgEonyfN6yWGLKc7zVjbpl2Y4CTjid9h2RfgPP6SEt6uHwEOply00yw==
"@types/yargs@^15.0.0":
version "15.0.11"
resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-15.0.11.tgz#361d7579ecdac1527687bcebf9946621c12ab78c"
integrity sha512-jfcNBxHFYJ4nPIacsi3woz1+kvUO6s1CyeEhtnDHBjHUMNj5UlW2GynmnSgiJJEdNg9yW5C8lfoNRZrHGv5EqA==
dependencies:
"@types/yargs-parser" "*"
abab@^1.0.3:
version "1.0.4"
@ -154,6 +184,11 @@ ansi-regex@^3.0.0:
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998"
integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=
ansi-regex@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.0.tgz#388539f55179bf39339c81af30a654d69f87cb75"
integrity sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==
ansi-styles@^2.2.1:
version "2.2.1"
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe"
@ -166,18 +201,13 @@ ansi-styles@^3.0.0, ansi-styles@^3.2.1:
dependencies:
color-convert "^1.9.0"
ansi-styles@^4.1.0:
ansi-styles@^4.0.0, ansi-styles@^4.1.0:
version "4.3.0"
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937"
integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==
dependencies:
color-convert "^2.0.1"
ansi-styles@^5.0.0:
version "5.2.0"
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-5.2.0.tgz#07449690ad45777d1924ac2abb2fc8895dba836b"
integrity sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==
anymatch@^1.3.0:
version "1.3.2"
resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-1.3.2.tgz#553dcb8f91e3c889845dfdba34c77721b90b9d7a"
@ -1625,10 +1655,10 @@ chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.4.1:
escape-string-regexp "^1.0.5"
supports-color "^5.3.0"
chalk@^4.0.0:
version "4.1.2"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01"
integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==
chalk@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-3.0.0.tgz#3f73c2bf526591f574cc492c51e2456349f844e4"
integrity sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==
dependencies:
ansi-styles "^4.1.0"
supports-color "^7.1.0"
@ -2379,10 +2409,10 @@ detect-port-alt@1.1.6:
address "^1.0.1"
debug "^2.6.0"
diff-sequences@^29.3.1:
version "29.3.1"
resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-29.3.1.tgz#104b5b95fe725932421a9c6e5b4bef84c3f2249e"
integrity sha512-hlM3QR272NXCi4pq+N4Kok4kOp6EsgOM3ZSpJI7Da3UAs+Ttsi8MRmB6trM/lhyzUxGfOgnpkHtgqm5Q/CTcfQ==
diff-sequences@^25.2.6:
version "25.2.6"
resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-25.2.6.tgz#5f467c00edd35352b7bca46d7927d60e687a76dd"
integrity sha512-Hq8o7+6GaZeoFjtpgvRBUknSXNeJiCx7V9Fr94ZMljNiCr9n9L8H8aJqgWOQiDDGdyn29fRNcDdRVJ5fdyihfg==
diff@^3.2.0:
version "3.5.0"
@ -4569,15 +4599,15 @@ jest-diff@^20.0.3:
jest-matcher-utils "^20.0.3"
pretty-format "^20.0.3"
jest-diff@^29.4.1:
version "29.4.1"
resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-29.4.1.tgz#9a6dc715037e1fa7a8a44554e7d272088c4029bd"
integrity sha512-uazdl2g331iY56CEyfbNA0Ut7Mn2ulAG5vUaEHXycf1L6IPyuImIxSz4F0VYBKi7LYIuxOwTZzK3wh5jHzASMw==
jest-diff@^25.1.0:
version "25.5.0"
resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-25.5.0.tgz#1dd26ed64f96667c068cef026b677dfa01afcfa9"
integrity sha512-z1kygetuPiREYdNIumRpAHY6RXiGmp70YHptjdaxTWGmA085W3iCnXNx0DhflK3vwrKmrRWyY1wUpkPMVxMK7A==
dependencies:
chalk "^4.0.0"
diff-sequences "^29.3.1"
jest-get-type "^29.2.0"
pretty-format "^29.4.1"
chalk "^3.0.0"
diff-sequences "^25.2.6"
jest-get-type "^25.2.6"
pretty-format "^25.5.0"
jest-docblock@^20.0.3:
version "20.0.3"
@ -4601,10 +4631,10 @@ jest-environment-node@^20.0.3:
jest-mock "^20.0.3"
jest-util "^20.0.3"
jest-get-type@^29.2.0:
version "29.2.0"
resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-29.2.0.tgz#726646f927ef61d583a3b3adb1ab13f3a5036408"
integrity sha512-uXNJlg8hKFEnDgFsrCjznB+sTxdkuqiCL6zMgA75qEbAJjJYTs9XPrvDctrEig2GDow22T/LvHgO57iJhXB/UA==
jest-get-type@^25.2.6:
version "25.2.6"
resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-25.2.6.tgz#0b0a32fab8908b44d508be81681487dbabb8d877"
integrity sha512-DxjtyzOHjObRM+sM1knti6or+eOgcGU4xVSb2HNP1TqO4ahsT+rqZg+nyqHWJSvWgKC5cG3QjGFBqxLghiF/Ig==
jest-haste-map@^20.0.4:
version "20.0.5"
@ -6329,14 +6359,15 @@ pretty-format@^20.0.3:
ansi-regex "^2.1.1"
ansi-styles "^3.0.0"
pretty-format@^29.4.1:
version "29.4.1"
resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-29.4.1.tgz#0da99b532559097b8254298da7c75a0785b1751c"
integrity sha512-dt/Z761JUVsrIKaY215o1xQJBGlSmTx/h4cSqXqjHLnU1+Kt+mavVE7UgqJJO5ukx5HjSswHfmXz4LjS2oIJfg==
pretty-format@^25.5.0:
version "25.5.0"
resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-25.5.0.tgz#7873c1d774f682c34b8d48b6743a2bf2ac55791a"
integrity sha512-kbo/kq2LQ/A/is0PQwsEHM7Ca6//bGPPvU6UnsdDRSKTWxT/ru/xb88v4BJf6a69H+uTytOEsTusT9ksd/1iWQ==
dependencies:
"@jest/schemas" "^29.4.0"
ansi-styles "^5.0.0"
react-is "^18.0.0"
"@jest/types" "^25.5.0"
ansi-regex "^5.0.0"
ansi-styles "^4.0.0"
react-is "^16.12.0"
private@^0.1.6, private@^0.1.7, private@^0.1.8:
version "0.1.8"
@ -6564,16 +6595,11 @@ react-error-overlay@^4.0.1:
resolved "https://registry.yarnpkg.com/react-error-overlay/-/react-error-overlay-4.0.1.tgz#417addb0814a90f3a7082eacba7cee588d00da89"
integrity sha512-xXUbDAZkU08aAkjtUvldqbvI04ogv+a1XdHxvYuHPYKIVk/42BIOD0zSKTHAWV4+gDy3yGm283z2072rA2gdtw==
react-is@^16.8.1:
react-is@^16.12.0, react-is@^16.8.1:
version "16.13.1"
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"
integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==
react-is@^18.0.0:
version "18.2.0"
resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.2.0.tgz#199431eeaaa2e09f86427efbb4f1473edb47609b"
integrity sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==
react-scripts@^1.0.11:
version "1.1.5"
resolved "https://registry.yarnpkg.com/react-scripts/-/react-scripts-1.1.5.tgz#3041610ab0826736b52197711a4c4e3756e97768"

View File

@ -16,7 +16,7 @@ function reload() {
}
}
// Point to the built version.
build = require('../../../build/oss-experimental/eslint-plugin-react-hooks');
build = require('../../../build/node_modules/eslint-plugin-react-hooks');
}
let rules = {};

View File

@ -8,9 +8,9 @@
"react-scripts": "1.0.17"
},
"scripts": {
"predev":
"cp ../../build/oss-experimental/react/umd/react.development.js public/ && cp ../../build/oss-experimental/react-dom/umd/react-dom.development.js public/",
"dev": "react-scripts start",
"prestart":
"cp ../../build/node_modules/react/umd/react.development.js public/ && cp ../../build/node_modules/react-dom/umd/react-dom.development.js public/",
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test --env=jsdom",
"eject": "react-scripts eject"

View File

@ -12,7 +12,7 @@
"react-motion": "^0.5.0"
},
"scripts": {
"dev": "react-scripts start",
"start": "react-scripts start",
"build": "react-scripts build"
}
}

View File

@ -16,8 +16,8 @@
If you checked out the source from GitHub make sure to run <code>npm run build</code>.
</p>
</div>
<script src="../../build/oss-experimental/react/umd/react.development.js"></script>
<script src="../../build/oss-experimental/react-dom/umd/react-dom.development.js"></script>
<script src="../../build/node_modules/react/umd/react.development.js"></script>
<script src="../../build/node_modules/react-dom/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/babel-standalone@6/babel.js"></script>
<script type="text/babel">
var dotStyle = {

View File

@ -16,9 +16,9 @@
If you checked out the source from GitHub make sure to run <code>npm run build</code>.
</p>
</div>
<script src="../../build/oss-experimental/react/umd/react.development.js"></script>
<script src="../../build/oss-experimental/react-dom/umd/react-dom.development.js"></script>
<script src="../../build/oss-experimental/react-dom/umd/react-dom-server.browser.development.js"></script>
<script src="../../build/node_modules/react/umd/react.development.js"></script>
<script src="../../build/node_modules/react-dom/umd/react-dom.development.js"></script>
<script src="../../build/node_modules/react-dom/umd/react-dom-server.browser.development.js"></script>
<script src="https://unpkg.com/babel-standalone@6/babel.js"></script>
<script type="text/babel">
async function render() {

View File

@ -15,8 +15,8 @@
"concurrently": "^5.3.0",
"express": "^4.17.1",
"nodemon": "^2.0.6",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react": "link:../../build/node_modules/react",
"react-dom": "link:../../build/node_modules/react-dom",
"react-error-boundary": "^3.1.3",
"resolve": "1.12.0",
"rimraf": "^3.0.2",
@ -28,14 +28,12 @@
"prettier": "1.19.1"
},
"scripts": {
"predev": "cp -r ../../build/oss-experimental/* ./node_modules/",
"prestart": "cp -r ../../build/oss-experimental/* ./node_modules/",
"dev": "concurrently \"npm run dev:server\" \"npm run dev:bundler\"",
"start": "concurrently \"npm run start:server\" \"npm run start:bundler\"",
"dev:server": "cross-env NODE_ENV=development nodemon -- --inspect server/server.js",
"start:server": "cross-env NODE_ENV=production nodemon -- server/server.js",
"dev:bundler": "cross-env NODE_ENV=development nodemon -- scripts/build.js",
"start:bundler": "cross-env NODE_ENV=production nodemon -- scripts/build.js"
"start": "concurrently \"npm run server:dev\" \"npm run bundler:dev\"",
"start:prod": "concurrently \"npm run server:prod\" \"npm run bundler:prod\"",
"server:dev": "cross-env NODE_ENV=development nodemon -- --inspect server/server.js",
"server:prod": "cross-env NODE_ENV=production nodemon -- server/server.js",
"bundler:dev": "cross-env NODE_ENV=development nodemon -- scripts/build.js",
"bundler:prod": "cross-env NODE_ENV=production nodemon -- scripts/build.js"
},
"babel": {
"presets": [

View File

@ -3171,7 +3171,7 @@ isobject@^3.0.0, isobject@^3.0.1:
resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df"
integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8=
"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0:
js-tokens@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499"
integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==
@ -3295,13 +3295,6 @@ lodash@^4.17.15, lodash@^4.17.19:
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
loose-envify@^1.1.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf"
integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==
dependencies:
js-tokens "^3.0.0 || ^4.0.0"
lowercase-keys@^1.0.0, lowercase-keys@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.1.tgz#6f9e30b47084d971a7c820ff15a6c5167b74c26f"
@ -4090,13 +4083,8 @@ rc@^1.2.8:
minimist "^1.2.0"
strip-json-comments "~2.0.1"
react-dom@^18.2.0:
version "18.2.0"
resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-18.2.0.tgz#22aaf38708db2674ed9ada224ca4aa708d821e3d"
integrity sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==
dependencies:
loose-envify "^1.1.0"
scheduler "^0.23.0"
"react-dom@link:../../build/node_modules/react-dom":
version "0.0.0"
react-error-boundary@^3.1.3:
version "3.1.4"
@ -4105,12 +4093,8 @@ react-error-boundary@^3.1.3:
dependencies:
"@babel/runtime" "^7.12.5"
react@^18.2.0:
version "18.2.0"
resolved "https://registry.yarnpkg.com/react/-/react-18.2.0.tgz#555bd98592883255fa00de14f1151a917b5d77d5"
integrity sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==
dependencies:
loose-envify "^1.1.0"
"react@link:../../build/node_modules/react":
version "0.0.0"
read-pkg@^4.0.1:
version "4.0.1"
@ -4369,13 +4353,6 @@ safe-regex@^1.1.0:
resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a"
integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==
scheduler@^0.23.0:
version "0.23.0"
resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.23.0.tgz#ba8041afc3d30eb206a487b6b384002e4e61fdfe"
integrity sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==
dependencies:
loose-envify "^1.1.0"
schema-utils@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-1.0.0.tgz#0b79a93204d7b600d4b2850d1f66c2a34951c770"

View File

@ -16,11 +16,11 @@
If you checked out the source from GitHub make sure to run <code>npm run build</code>.
</p>
</div>
<script src="../../build/oss-experimental/react/umd/react.development.js"></script>
<script src="../../build/oss-experimental/react-dom/umd/react-dom.development.js"></script>
<script src="../../build/oss-experimental/react-dom/umd/react-dom-server.browser.development.js"></script>
<script src="../../build/oss-experimental/react-server-dom-webpack/umd/react-server-dom-webpack-server.browser.development.js"></script>
<script src="../../build/oss-experimental/react-server-dom-webpack/umd/react-server-dom-webpack-client.browser.development.js"></script>
<script src="../../build/node_modules/react/umd/react.development.js"></script>
<script src="../../build/node_modules/react-dom/umd/react-dom.development.js"></script>
<script src="../../build/node_modules/react-dom/umd/react-dom-server.browser.development.js"></script>
<script src="../../build/node_modules/react-server-dom-webpack/umd/react-server-dom-webpack-server.browser.development.js"></script>
<script src="../../build/node_modules/react-server-dom-webpack/umd/react-server-dom-webpack.development.js"></script>
<script src="https://unpkg.com/babel-standalone@6/babel.js"></script>
<script type="text/babel">
let Suspense = React.Suspense;
@ -60,7 +60,7 @@
content: <HTML />,
};
let stream = ReactServerDOMServer.renderToReadableStream(model);
let stream = ReactServerDOMWriter.renderToReadableStream(model);
let response = new Response(stream, {
headers: {'Content-Type': 'text/html'},
});
@ -70,13 +70,13 @@
let blob = await responseToDisplay.blob();
let url = URL.createObjectURL(blob);
let data = ReactServerDOMClient.createFromFetch(
let data = ReactServerDOMReader.createFromFetch(
fetch(url)
);
// The client also supports XHR streaming.
// var xhr = new XMLHttpRequest();
// xhr.open('GET', url);
// let data = ReactServerDOMClient.createFromXHR(xhr);
// let data = ReactServerDOMReader.createFromXHR(xhr);
// xhr.send();
renderResult(data);

View File

@ -10,6 +10,7 @@
# production
/build
/dist
.eslintcache
# misc

View File

@ -0,0 +1,66 @@
'use strict';
const fs = require('fs');
const path = require('path');
const crypto = require('crypto');
const chalk = require('react-dev-utils/chalk');
const paths = require('./paths');
// Ensure the certificate and key provided are valid and if not
// throw an easy to debug error
function validateKeyAndCerts({cert, key, keyFile, crtFile}) {
let encrypted;
try {
// publicEncrypt will throw an error with an invalid cert
encrypted = crypto.publicEncrypt(cert, Buffer.from('test'));
} catch (err) {
throw new Error(
`The certificate "${chalk.yellow(crtFile)}" is invalid.\n${err.message}`
);
}
try {
// privateDecrypt will throw an error with an invalid key
crypto.privateDecrypt(key, encrypted);
} catch (err) {
throw new Error(
`The certificate key "${chalk.yellow(keyFile)}" is invalid.\n${
err.message
}`
);
}
}
// Read file and throw an error if it doesn't exist
function readEnvFile(file, type) {
if (!fs.existsSync(file)) {
throw new Error(
`You specified ${chalk.cyan(
type
)} in your env, but the file "${chalk.yellow(file)}" can't be found.`
);
}
return fs.readFileSync(file);
}
// Get the https config
// Return cert files if provided in env, otherwise just true or false
function getHttpsConfig() {
const {SSL_CRT_FILE, SSL_KEY_FILE, HTTPS} = process.env;
const isHttps = HTTPS === 'true';
if (isHttps && SSL_CRT_FILE && SSL_KEY_FILE) {
const crtFile = path.resolve(paths.appPath, SSL_CRT_FILE);
const keyFile = path.resolve(paths.appPath, SSL_KEY_FILE);
const config = {
cert: readEnvFile(crtFile, 'SSL_CRT_FILE'),
key: readEnvFile(keyFile, 'SSL_KEY_FILE'),
};
validateKeyAndCerts({...config, keyFile, crtFile});
return config;
}
return isHttps;
}
module.exports = getHttpsConfig;

View File

@ -3,7 +3,7 @@
const fs = require('fs');
const path = require('path');
const paths = require('./paths');
const chalk = require('chalk');
const chalk = require('react-dev-utils/chalk');
const resolve = require('resolve');
/**

View File

@ -56,6 +56,7 @@ module.exports = {
appPath: resolveApp('.'),
appBuild: resolveApp(buildPath),
appPublic: resolveApp('public'),
appHtml: resolveApp('public/index.html'),
appIndexJs: resolveModule(resolveApp, 'src/index'),
appPackageJson: resolveApp('package.json'),
appSrc: resolveApp('src'),
@ -63,6 +64,7 @@ module.exports = {
appJsConfig: resolveApp('jsconfig.json'),
yarnLockFile: resolveApp('yarn.lock'),
testsSetup: resolveModule(resolveApp, 'src/setupTests'),
proxySetup: resolveApp('src/setupProxy.js'),
appNodeModules: resolveApp('node_modules'),
appWebpackCache: resolveApp('node_modules/.cache'),
appTsBuildInfoFile: resolveApp('node_modules/.cache/tsconfig.tsbuildinfo'),

View File

@ -5,14 +5,18 @@ const ReactFlightWebpackPlugin = require('react-server-dom-webpack/plugin');
// Fork End
const fs = require('fs');
const {createHash} = require('crypto');
const path = require('path');
const webpack = require('webpack');
const resolve = require('resolve');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CaseSensitivePathsPlugin = require('case-sensitive-paths-webpack-plugin');
const InlineChunkHtmlPlugin = require('react-dev-utils/InlineChunkHtmlPlugin');
const TerserPlugin = require('terser-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
const {WebpackManifestPlugin} = require('webpack-manifest-plugin');
const InterpolateHtmlPlugin = require('react-dev-utils/InterpolateHtmlPlugin');
const WorkboxWebpackPlugin = require('workbox-webpack-plugin');
const ModuleScopePlugin = require('react-dev-utils/ModuleScopePlugin');
const getCSSModuleLocalIdent = require('react-dev-utils/getCSSModuleLocalIdent');
const ESLintPlugin = require('eslint-webpack-plugin');
@ -25,14 +29,8 @@ const ForkTsCheckerWebpackPlugin =
? require('react-dev-utils/ForkTsCheckerWarningWebpackPlugin')
: require('react-dev-utils/ForkTsCheckerWebpackPlugin');
const ReactRefreshWebpackPlugin = require('@pmmmwh/react-refresh-webpack-plugin');
const {WebpackManifestPlugin} = require('webpack-manifest-plugin');
function createEnvironmentHash(env) {
const hash = createHash('md5');
hash.update(JSON.stringify(env));
return hash.digest('hex');
}
const createEnvironmentHash = require('./webpack/persistentCache/createEnvironmentHash');
// Source maps are resource heavy and can cause out of memory issue for large source files.
const shouldUseSourceMap = process.env.GENERATE_SOURCEMAP !== 'false';
@ -114,7 +112,7 @@ module.exports = function (webpackEnv) {
const getStyleLoaders = (cssOptions, preProcessor) => {
const loaders = [
isEnvDevelopment && require.resolve('style-loader'),
{
isEnvProduction && {
loader: MiniCssExtractPlugin.loader,
// css is located in `static/css`, use '../../' to locate index.html folder
// in production `paths.publicUrlOrPath` can be a relative path
@ -206,13 +204,7 @@ module.exports = function (webpackEnv) {
: isEnvDevelopment && 'cheap-module-source-map',
// These are the "entry points" to our application.
// This means they will be the "root" imports that are included in JS bundle.
entry: isEnvProduction
? [paths.appIndexJs]
: [
paths.appIndexJs,
// HMR client
'webpack-hot-middleware/client?path=/__webpack_hmr&timeout=20000',
],
entry: paths.appIndexJs,
output: {
// The build folder.
path: paths.appBuild,
@ -575,7 +567,44 @@ module.exports = function (webpackEnv) {
].filter(Boolean),
},
plugins: [
new webpack.HotModuleReplacementPlugin(),
// Generates an `index.html` file with the <script> injected.
new HtmlWebpackPlugin(
Object.assign(
{},
{
inject: true,
template: paths.appHtml,
},
isEnvProduction
? {
minify: {
removeComments: true,
collapseWhitespace: true,
removeRedundantAttributes: true,
useShortDoctype: true,
removeEmptyAttributes: true,
removeStyleLinkTypeAttributes: true,
keepClosingSlash: true,
minifyJS: true,
minifyCSS: true,
minifyURLs: true,
},
}
: undefined
)
),
// Inlines the webpack runtime script. This script is too small to warrant
// a network request.
// https://github.com/facebook/create-react-app/issues/5358
isEnvProduction &&
shouldInlineRuntimeChunk &&
new InlineChunkHtmlPlugin(HtmlWebpackPlugin, [/runtime-.+[.]js/]),
// Makes some environment variables available in index.html.
// The public URL is available as %PUBLIC_URL% in index.html, e.g.:
// <link rel="icon" href="%PUBLIC_URL%/favicon.ico">
// It will be an empty string unless you specify "homepage"
// in `package.json`, in which case it will be the pathname of that URL.
new InterpolateHtmlPlugin(HtmlWebpackPlugin, env.raw),
// This gives some necessary context to module not found errors, such as
// the requesting resource.
new ModuleNotFoundPlugin(paths.appPath),
@ -596,38 +625,35 @@ module.exports = function (webpackEnv) {
// a plugin that prints an error when you attempt to do this.
// See https://github.com/facebook/create-react-app/issues/240
isEnvDevelopment && new CaseSensitivePathsPlugin(),
new MiniCssExtractPlugin({
// Options similar to the same options in webpackOptions.output
// both options are optional
filename: 'static/css/[name].[contenthash:8].css',
chunkFilename: 'static/css/[name].[contenthash:8].chunk.css',
}),
// Generate a manifest containing the required script / css for each entry.
isEnvProduction &&
new MiniCssExtractPlugin({
// Options similar to the same options in webpackOptions.output
// both options are optional
filename: 'static/css/[name].[contenthash:8].css',
chunkFilename: 'static/css/[name].[contenthash:8].chunk.css',
}),
// Generate an asset manifest file with the following content:
// - "files" key: Mapping of all asset filenames to their corresponding
// output file so that tools can pick it up without having to parse
// `index.html`
// - "entrypoints" key: Array of files which are included in `index.html`,
// can be used to reconstruct the HTML if necessary
new WebpackManifestPlugin({
fileName: 'entrypoint-manifest.json',
fileName: 'asset-manifest.json',
publicPath: paths.publicUrlOrPath,
generate: (seed, files, entrypoints) => {
const manifestFiles = files.reduce((manifest, file) => {
manifest[file.name] = file.path;
return manifest;
}, seed);
const entrypointFiles = entrypoints.main.filter(
fileName => !fileName.endsWith('.map')
);
const processedEntrypoints = {};
for (let key in entrypoints) {
processedEntrypoints[key] = {
js: entrypoints[key].filter(
filename =>
// Include JS assets but ignore hot updates because they're not
// safe to include as async script tags.
filename.endsWith('.js') &&
!filename.endsWith('.hot-update.js')
),
css: entrypoints[key].filter(filename =>
filename.endsWith('.css')
),
};
}
return processedEntrypoints;
return {
files: manifestFiles,
entrypoints: entrypointFiles,
};
},
}),
// Moment.js is an extremely popular library that bundles large locale files
@ -639,6 +665,19 @@ module.exports = function (webpackEnv) {
resourceRegExp: /^\.\/locale$/,
contextRegExp: /moment$/,
}),
// Generate a service worker script that will precache, and keep up to date,
// the HTML & assets that are part of the webpack build.
isEnvProduction &&
fs.existsSync(swSrc) &&
new WorkboxWebpackPlugin.InjectManifest({
swSrc,
dontCacheBustURLsMatching: /\.[0-9a-f]{8}\./,
exclude: [/\.map$/, /asset-manifest\.json$/, /LICENSE/],
// Bump up the default maximum size (2mb) that's precached,
// to make lazy-loading failure scenarios less likely.
// See https://github.com/cra-template/pwa/issues/13#issuecomment-722667270
maximumFileSizeToCacheInBytes: 5 * 1024 * 1024,
}),
// TypeScript type checking
useTypeScript &&
new ForkTsCheckerWebpackPlugin({
@ -713,14 +752,7 @@ module.exports = function (webpackEnv) {
// },
// }),
// Fork Start
new ReactFlightWebpackPlugin({
isServer: false,
clientReferences: {
directory: './src',
recursive: true,
include: /\.(js|ts|jsx|tsx)$/,
},
}),
new ReactFlightWebpackPlugin({isServer: false}),
// Fork End
].filter(Boolean),
// Turn off performance processing because we utilize

View File

@ -0,0 +1,9 @@
'use strict';
const {createHash} = require('crypto');
module.exports = env => {
const hash = createHash('md5');
hash.update(JSON.stringify(env));
return hash.digest('hex');
};

View File

@ -0,0 +1,133 @@
'use strict';
const fs = require('fs');
const evalSourceMapMiddleware = require('react-dev-utils/evalSourceMapMiddleware');
const noopServiceWorkerMiddleware = require('react-dev-utils/noopServiceWorkerMiddleware');
const ignoredFiles = require('react-dev-utils/ignoredFiles');
const redirectServedPath = require('react-dev-utils/redirectServedPathMiddleware');
const paths = require('./paths');
const getHttpsConfig = require('./getHttpsConfig');
const host = process.env.HOST || '0.0.0.0';
const sockHost = process.env.WDS_SOCKET_HOST;
const sockPath = process.env.WDS_SOCKET_PATH; // default: '/ws'
const sockPort = process.env.WDS_SOCKET_PORT;
module.exports = function (proxy, allowedHost) {
const disableFirewall =
!proxy || process.env.DANGEROUSLY_DISABLE_HOST_CHECK === 'true';
return {
// WebpackDevServer 2.4.3 introduced a security fix that prevents remote
// websites from potentially accessing local content through DNS rebinding:
// https://github.com/webpack/webpack-dev-server/issues/887
// https://medium.com/webpack/webpack-dev-server-middleware-security-issues-1489d950874a
// However, it made several existing use cases such as development in cloud
// environment or subdomains in development significantly more complicated:
// https://github.com/facebook/create-react-app/issues/2271
// https://github.com/facebook/create-react-app/issues/2233
// While we're investigating better solutions, for now we will take a
// compromise. Since our WDS configuration only serves files in the `public`
// folder we won't consider accessing them a vulnerability. However, if you
// use the `proxy` feature, it gets more dangerous because it can expose
// remote code execution vulnerabilities in backends like Django and Rails.
// So we will disable the host check normally, but enable it if you have
// specified the `proxy` setting. Finally, we let you override it if you
// really know what you're doing with a special environment variable.
// Note: ["localhost", ".localhost"] will support subdomains - but we might
// want to allow setting the allowedHosts manually for more complex setups
allowedHosts: disableFirewall ? 'all' : [allowedHost],
headers: {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': '*',
'Access-Control-Allow-Headers': '*',
},
// Enable gzip compression of generated files.
compress: true,
static: {
// By default WebpackDevServer serves physical files from current directory
// in addition to all the virtual build products that it serves from memory.
// This is confusing because those files wont automatically be available in
// production build folder unless we copy them. However, copying the whole
// project directory is dangerous because we may expose sensitive files.
// Instead, we establish a convention that only files in `public` directory
// get served. Our build script will copy `public` into the `build` folder.
// In `index.html`, you can get URL of `public` folder with %PUBLIC_URL%:
// <link rel="icon" href="%PUBLIC_URL%/favicon.ico">
// In JavaScript code, you can access it with `process.env.PUBLIC_URL`.
// Note that we only recommend to use `public` folder as an escape hatch
// for files like `favicon.ico`, `manifest.json`, and libraries that are
// for some reason broken when imported through webpack. If you just want to
// use an image, put it in `src` and `import` it from JavaScript instead.
directory: paths.appPublic,
publicPath: [paths.publicUrlOrPath],
// By default files from `contentBase` will not trigger a page reload.
watch: {
// Reportedly, this avoids CPU overload on some systems.
// https://github.com/facebook/create-react-app/issues/293
// src/node_modules is not ignored to support absolute imports
// https://github.com/facebook/create-react-app/issues/1065
ignored: ignoredFiles(paths.appSrc),
},
},
client: {
webSocketURL: {
// Enable custom sockjs pathname for websocket connection to hot reloading server.
// Enable custom sockjs hostname, pathname and port for websocket connection
// to hot reloading server.
hostname: sockHost,
pathname: sockPath,
port: sockPort,
},
overlay: {
errors: true,
warnings: false,
},
},
devMiddleware: {
// Fork Start
writeToDisk: filePath => {
return /react-client-manifest\.json$/.test(filePath);
},
// Fork End
// It is important to tell WebpackDevServer to use the same "publicPath" path as
// we specified in the webpack config. When homepage is '.', default to serving
// from the root.
// remove last slash so user can land on `/test` instead of `/test/`
publicPath: paths.publicUrlOrPath.slice(0, -1),
},
https: getHttpsConfig(),
host,
historyApiFallback: {
// Paths with dots should still use the history fallback.
// See https://github.com/facebook/create-react-app/issues/387.
disableDotRule: true,
index: paths.publicUrlOrPath,
},
// `proxy` is run between `before` and `after` `webpack-dev-server` hooks
proxy,
onBeforeSetupMiddleware(devServer) {
// Keep `evalSourceMapMiddleware`
// middlewares before `redirectServedPath` otherwise will not have any effect
// This lets us fetch source contents from webpack for the error overlay
devServer.app.use(evalSourceMapMiddleware(devServer));
if (fs.existsSync(paths.proxySetup)) {
// This registers user provided middleware for proxy reasons
require(paths.proxySetup)(devServer.app);
}
},
onAfterSetupMiddleware(devServer) {
// Redirect to `PUBLIC_URL` or `homepage` from `package.json` if url not match
devServer.app.use(redirectServedPath(paths.publicUrlOrPath));
// This service worker file is effectively a 'no-op' that will reset any
// previous service worker registered for the same host:port combination.
// We do this in development to avoid hitting the production cache if
// it used the same host and port.
// https://github.com/facebook/create-react-app/issues/2272#issuecomment-302832432
devServer.app.use(noopServiceWorkerMiddleware(paths.publicUrlOrPath));
},
};
};

View File

@ -1,51 +0,0 @@
import babel from '@babel/core';
const babelOptions = {
babelrc: false,
ignore: [/\/(build|node_modules)\//],
plugins: [
'@babel/plugin-syntax-import-meta',
'@babel/plugin-transform-react-jsx',
],
};
export async function load(url, context, defaultLoad) {
const {format} = context;
const result = await defaultLoad(url, context, defaultLoad);
if (result.format === 'module') {
const opt = Object.assign({filename: url}, babelOptions);
const newResult = await babel.transformAsync(result.source, opt);
if (!newResult) {
if (typeof result.source === 'string') {
return result;
}
return {
source: Buffer.from(result.source).toString('utf8'),
format: 'module',
};
}
return {source: newResult.code, format: 'module'};
}
return defaultLoad(url, context, defaultLoad);
}
async function babelTransformSource(source, context, defaultTransformSource) {
const {format} = context;
if (format === 'module') {
const opt = Object.assign({filename: context.url}, babelOptions);
const newResult = await babel.transformAsync(source, opt);
if (!newResult) {
if (typeof source === 'string') {
return {source};
}
return {
source: Buffer.from(source).toString('utf8'),
};
}
return {source: newResult.code};
}
return defaultTransformSource(source, context, defaultTransformSource);
}
export const transformSource =
process.version < 'v16' ? babelTransformSource : undefined;

View File

@ -0,0 +1,34 @@
import {
resolve,
getSource,
transformSource as reactTransformSource,
} from 'react-server-dom-webpack/node-loader';
export {resolve, getSource};
import babel from '@babel/core';
const babelOptions = {
babelrc: false,
ignore: [/\/(build|node_modules)\//],
plugins: [
'@babel/plugin-syntax-import-meta',
'@babel/plugin-transform-react-jsx',
],
};
async function babelTransformSource(source, context, defaultTransformSource) {
const {format} = context;
if (format === 'module') {
const opt = Object.assign({filename: context.url}, babelOptions);
const {code} = await babel.transformAsync(source, opt);
return {source: code};
}
return defaultTransformSource(source, context, defaultTransformSource);
}
export async function transformSource(source, context, defaultTransformSource) {
return reactTransformSource(source, context, (s, c) => {
return babelTransformSource(s, c, defaultTransformSource);
});
}

View File

@ -1,73 +0,0 @@
import {
resolve,
load as reactLoad,
getSource as getSourceImpl,
transformSource as reactTransformSource,
} from 'react-server-dom-webpack/node-loader';
export {resolve};
import babel from '@babel/core';
const babelOptions = {
babelrc: false,
ignore: [/\/(build|node_modules)\//],
plugins: [
'@babel/plugin-syntax-import-meta',
'@babel/plugin-transform-react-jsx',
],
};
async function babelLoad(url, context, defaultLoad) {
const {format} = context;
const result = await defaultLoad(url, context, defaultLoad);
if (result.format === 'module') {
const opt = Object.assign({filename: url}, babelOptions);
const newResult = await babel.transformAsync(result.source, opt);
if (!newResult) {
if (typeof result.source === 'string') {
return result;
}
return {
source: Buffer.from(result.source).toString('utf8'),
format: 'module',
};
}
return {source: newResult.code, format: 'module'};
}
return defaultLoad(url, context, defaultLoad);
}
export async function load(url, context, defaultLoad) {
return await reactLoad(url, context, (u, c) => {
return babelLoad(u, c, defaultLoad);
});
}
async function babelTransformSource(source, context, defaultTransformSource) {
const {format} = context;
if (format === 'module') {
const opt = Object.assign({filename: context.url}, babelOptions);
const newResult = await babel.transformAsync(source, opt);
if (!newResult) {
if (typeof source === 'string') {
return {source};
}
return {
source: Buffer.from(source).toString('utf8'),
};
}
return {source: newResult.code};
}
return defaultTransformSource(source, context, defaultTransformSource);
}
async function transformSourceImpl(source, context, defaultTransformSource) {
return await reactTransformSource(source, context, (s, c) => {
return babelTransformSource(s, c, defaultTransformSource);
});
}
export const transformSource =
process.version < 'v16' ? transformSourceImpl : undefined;
export const getSource = process.version < 'v16' ? getSourceImpl : undefined;

View File

@ -15,12 +15,10 @@
"babel-loader": "^8.2.3",
"babel-plugin-named-asset-import": "^0.3.8",
"babel-preset-react-app": "^10.0.1",
"body-parser": "^1.20.1",
"bfj": "^7.0.2",
"browserslist": "^4.18.1",
"busboy": "^1.6.0",
"camelcase": "^6.2.1",
"case-sensitive-paths-webpack-plugin": "^2.4.0",
"compression": "^1.7.4",
"concurrently": "^7.3.0",
"css-loader": "^6.5.1",
"css-minimizer-webpack-plugin": "^3.2.0",
@ -44,10 +42,10 @@
"postcss-normalize": "^10.0.1",
"postcss-preset-env": "^7.0.1",
"prompts": "^2.4.2",
"react": "experimental",
"react": "^18.2.0",
"react-app-polyfill": "^3.0.0",
"react-dev-utils": "^12.0.1",
"react-dom": "experimental",
"react-dom": "^18.2.0",
"react-refresh": "^0.11.0",
"resolve": "^1.20.0",
"resolve-url-loader": "^4.0.0",
@ -57,21 +55,21 @@
"style-loader": "^3.3.1",
"tailwindcss": "^3.0.2",
"terser-webpack-plugin": "^5.2.5",
"undici": "^5.20.0",
"web-vitals": "^2.1.0",
"webpack": "^5.64.4",
"webpack-dev-middleware": "^5.3.1",
"webpack-hot-middleware": "^2.25.3",
"webpack-manifest-plugin": "^4.0.2"
"webpack-dev-server": "^4.6.0",
"webpack-manifest-plugin": "^4.0.2",
"workbox-webpack-plugin": "^6.4.1"
},
"scripts": {
"predev": "cp -r ../../build/oss-experimental/* ./node_modules/",
"prebuild": "cp -r ../../build/oss-experimental/* ./node_modules/",
"dev": "concurrently \"npm run dev:region\" \"npm run dev:global\"",
"dev:global": "NODE_ENV=development BUILD_PATH=dist node --experimental-loader ./loader/global.js server/global",
"dev:region": "NODE_ENV=development BUILD_PATH=dist nodemon --watch src --watch dist -- --experimental-loader ./loader/region.js --conditions=react-server server/region",
"start": "node scripts/build.js && concurrently \"npm run start:region\" \"npm run start:global\"",
"start:global": "NODE_ENV=production node --experimental-loader ./loader/global.js server/global",
"start:region": "NODE_ENV=production node --experimental-loader ./loader/region.js --conditions=react-server server/region",
"prestart": "cp -r ../../build/node_modules/* ./node_modules/",
"prebuild": "cp -r ../../build/node_modules/* ./node_modules/",
"start": "concurrently \"npm run start:server\" \"npm run start:client\"",
"start:client": "NODE_ENV=development BUILD_PATH=dist node scripts/start.js",
"start:server": "NODE_ENV=development BUILD_PATH=dist nodemon -- --experimental-loader ./loader/index.js --conditions=react-server server",
"start:prod": "node scripts/build.js && concurrently \"npm run start:prod-server\" \"npm run start:prod-client\"",
"start:prod-client": "cd ./build && python -m SimpleHTTPServer 3000",
"start:prod-server": "NODE_ENV=production node --experimental-loader ./loader/index.js --conditions=react-server server",
"build": "node scripts/build.js",
"test": "node scripts/test.js --env=jsdom"
},

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

View File

@ -0,0 +1,11 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Flight</title>
</head>
<body>
<div id="root"></div>
</body>
</html>

View File

@ -15,8 +15,9 @@ process.on('unhandledRejection', err => {
require('../config/env');
const path = require('path');
const chalk = require('chalk');
const chalk = require('react-dev-utils/chalk');
const fs = require('fs-extra');
const bfj = require('bfj');
const webpack = require('webpack');
const configFactory = require('../config/webpack.config');
const paths = require('../config/paths');
@ -38,7 +39,7 @@ const WARN_AFTER_CHUNK_GZIP_SIZE = 1024 * 1024;
const isInteractive = process.stdout.isTTY;
// Warn and crash if required files are missing
if (!checkRequiredFiles([paths.appIndexJs])) {
if (!checkRequiredFiles([paths.appHtml, paths.appIndexJs])) {
process.exit(1);
}
@ -196,13 +197,21 @@ function build(previousFileSizes) {
warnings: messages.warnings,
};
if (writeStatsJson) {
return bfj
.write(paths.appBuild + '/bundle-stats.json', stats.toJson())
.then(() => resolve(resolveArgs))
.catch(error => reject(new Error(error)));
}
return resolve(resolveArgs);
});
});
}
function copyPublicFolder() {
fs.copySync('public', 'build', {
fs.copySync(paths.appPublic, paths.appBuild, {
dereference: true,
filter: file => file !== paths.appHtml,
});
}

View File

@ -0,0 +1,154 @@
'use strict';
// Do this as the first thing so that any code reading it knows the right env.
process.env.BABEL_ENV = 'development';
process.env.NODE_ENV = 'development';
// Makes the script crash on unhandled rejections instead of silently
// ignoring them. In the future, promise rejections that are not handled will
// terminate the Node.js process with a non-zero exit code.
process.on('unhandledRejection', err => {
throw err;
});
// Ensure environment variables are read.
require('../config/env');
const fs = require('fs');
const chalk = require('react-dev-utils/chalk');
const webpack = require('webpack');
const WebpackDevServer = require('webpack-dev-server');
const clearConsole = require('react-dev-utils/clearConsole');
const checkRequiredFiles = require('react-dev-utils/checkRequiredFiles');
const {
choosePort,
createCompiler,
prepareProxy,
prepareUrls,
} = require('react-dev-utils/WebpackDevServerUtils');
const openBrowser = require('react-dev-utils/openBrowser');
const semver = require('semver');
const paths = require('../config/paths');
const configFactory = require('../config/webpack.config');
const createDevServerConfig = require('../config/webpackDevServer.config');
const getClientEnvironment = require('../config/env');
const react = require(require.resolve('react', {paths: [paths.appPath]}));
const env = getClientEnvironment(paths.publicUrlOrPath.slice(0, -1));
const useYarn = fs.existsSync(paths.yarnLockFile);
const isInteractive = process.stdout.isTTY;
// Warn and crash if required files are missing
if (!checkRequiredFiles([paths.appHtml, paths.appIndexJs])) {
process.exit(1);
}
// Tools like Cloud9 rely on this.
const DEFAULT_PORT = parseInt(process.env.PORT, 10) || 3000;
const HOST = process.env.HOST || '0.0.0.0';
if (process.env.HOST) {
console.log(
chalk.cyan(
`Attempting to bind to HOST environment variable: ${chalk.yellow(
chalk.bold(process.env.HOST)
)}`
)
);
console.log(
`If this was unintentional, check that you haven't mistakenly set it in your shell.`
);
console.log(
`Learn more here: ${chalk.yellow('https://cra.link/advanced-config')}`
);
console.log();
}
// We require that you explicitly set browsers and do not fall back to
// browserslist defaults.
const {checkBrowsers} = require('react-dev-utils/browsersHelper');
checkBrowsers(paths.appPath, isInteractive)
.then(() => {
// We attempt to use the default port but if it is busy, we offer the user to
// run on a different port. `choosePort()` Promise resolves to the next free port.
return choosePort(HOST, DEFAULT_PORT);
})
.then(port => {
if (port == null) {
// We have not found a port.
return;
}
const config = configFactory('development');
const protocol = process.env.HTTPS === 'true' ? 'https' : 'http';
const appName = require(paths.appPackageJson).name;
const useTypeScript = fs.existsSync(paths.appTsConfig);
const urls = prepareUrls(
protocol,
HOST,
port,
paths.publicUrlOrPath.slice(0, -1)
);
// Create a webpack compiler that is configured with custom messages.
const compiler = createCompiler({
appName,
config,
urls,
useYarn,
useTypeScript,
webpack,
});
// Load proxy config
const proxySetting = require(paths.appPackageJson).proxy;
const proxyConfig = prepareProxy(
proxySetting,
paths.appPublic,
paths.publicUrlOrPath
);
// Serve webpack assets generated by the compiler over a web server.
const serverConfig = {
...createDevServerConfig(proxyConfig, urls.lanUrlForConfig),
host: HOST,
port,
};
const devServer = new WebpackDevServer(serverConfig, compiler);
// Launch WebpackDevServer.
devServer.startCallback(() => {
if (isInteractive) {
clearConsole();
}
if (env.raw.FAST_REFRESH && semver.lt(react.version, '16.10.0')) {
console.log(
chalk.yellow(
`Fast Refresh requires React 16.10 or higher. You are using React ${react.version}.`
)
);
}
console.log(chalk.cyan('Starting the development server...\n'));
openBrowser(urls.localUrlForBrowser);
});
['SIGINT', 'SIGTERM'].forEach(function (sig) {
process.on(sig, function () {
devServer.close();
process.exit();
});
});
if (process.env.CI !== 'true') {
// Gracefully exit when stdin ends
process.stdin.on('end', function () {
devServer.close();
process.exit();
});
}
})
.catch(err => {
if (err && err.message) {
console.log(err.message);
}
process.exit(1);
});

View File

@ -0,0 +1,72 @@
'use strict';
const register = require('react-server-dom-webpack/node-register');
register();
const babelRegister = require('@babel/register');
const path = require('path');
babelRegister({
babelrc: false,
ignore: [
/\/(build|node_modules)\//,
function (file) {
if ((path.dirname(file) + '/').startsWith(__dirname + '/')) {
// Ignore everything in this folder
// because it's a mix of CJS and ESM
// and working with raw code is easier.
return true;
}
return false;
},
],
presets: ['react-app'],
plugins: ['@babel/transform-modules-commonjs'],
});
const express = require('express');
const app = express();
// Application
app.get('/', function (req, res) {
require('./handler.server.js')(req, res);
});
app.get('/todos', function (req, res) {
res.setHeader('Access-Control-Allow-Origin', '*');
res.json([
{
id: 1,
text: 'Shave yaks',
},
{
id: 2,
text: 'Eat kale',
},
]);
});
app.listen(3001, () => {
console.log('Flight Server listening on port 3001...');
});
app.on('error', function (error) {
if (error.syscall !== 'listen') {
throw error;
}
var bind = typeof port === 'string' ? 'Pipe ' + port : 'Port ' + port;
switch (error.code) {
case 'EACCES':
console.error(bind + ' requires elevated privileges');
process.exit(1);
break;
case 'EADDRINUSE':
console.error(bind + ' is already in use');
process.exit(1);
break;
default:
throw error;
}
});

View File

@ -1,205 +0,0 @@
'use strict';
// This is a server to host CDN distributed resources like Webpack bundles and SSR
const path = require('path');
// Do this as the first thing so that any code reading it knows the right env.
process.env.BABEL_ENV = process.env.NODE_ENV;
const register = require('react-server-dom-webpack/node-register');
register();
const babelRegister = require('@babel/register');
babelRegister({
babelrc: false,
ignore: [
/\/(build|node_modules)\//,
function (file) {
if ((path.dirname(file) + '/').startsWith(__dirname + '/')) {
// Ignore everything in this folder
// because it's a mix of CJS and ESM
// and working with raw code is easier.
return true;
}
return false;
},
],
presets: ['react-app'],
plugins: ['@babel/transform-modules-commonjs'],
});
// Ensure environment variables are read.
require('../config/env');
const fs = require('fs').promises;
const compress = require('compression');
const chalk = require('chalk');
const express = require('express');
const http = require('http');
const {renderToPipeableStream} = require('react-dom/server');
const {createFromNodeStream} = require('react-server-dom-webpack/client');
const app = express();
app.use(compress());
if (process.env.NODE_ENV === 'development') {
// In development we host the Webpack server for live bundling.
const webpack = require('webpack');
const webpackMiddleware = require('webpack-dev-middleware');
const webpackHotMiddleware = require('webpack-hot-middleware');
const paths = require('../config/paths');
const configFactory = require('../config/webpack.config');
const getClientEnvironment = require('../config/env');
const env = getClientEnvironment(paths.publicUrlOrPath.slice(0, -1));
const config = configFactory('development');
const protocol = process.env.HTTPS === 'true' ? 'https' : 'http';
const appName = require(paths.appPackageJson).name;
// Create a webpack compiler that is configured with custom messages.
const compiler = webpack(config);
app.use(
webpackMiddleware(compiler, {
publicPath: paths.publicUrlOrPath.slice(0, -1),
serverSideRender: true,
})
);
app.use(webpackHotMiddleware(compiler));
}
function request(options, body) {
return new Promise((resolve, reject) => {
const req = http.request(options, res => {
resolve(res);
});
req.on('error', e => {
reject(e);
});
body.pipe(req);
});
}
app.all('/', async function (req, res, next) {
// Proxy the request to the regional server.
const proxiedHeaders = {
'X-Forwarded-Host': req.hostname,
'X-Forwarded-For': req.ips,
'X-Forwarded-Port': 3000,
'X-Forwarded-Proto': req.protocol,
};
// Proxy other headers as desired.
if (req.get('rsc-action')) {
proxiedHeaders['Content-type'] = req.get('Content-type');
proxiedHeaders['rsc-action'] = req.get('rsc-action');
} else if (req.get('Content-type')) {
proxiedHeaders['Content-type'] = req.get('Content-type');
}
const promiseForData = request(
{
host: '127.0.0.1',
port: 3001,
method: req.method,
path: '/',
headers: proxiedHeaders,
},
req
);
if (req.accepts('text/html')) {
try {
const rscResponse = await promiseForData;
let virtualFs;
let buildPath;
if (process.env.NODE_ENV === 'development') {
const {devMiddleware} = res.locals.webpack;
virtualFs = devMiddleware.outputFileSystem.promises;
buildPath = devMiddleware.stats.toJson().outputPath;
} else {
virtualFs = fs;
buildPath = path.join(__dirname, '../build/');
}
// Read the module map from the virtual file system.
const moduleMap = JSON.parse(
await virtualFs.readFile(
path.join(buildPath, 'react-ssr-manifest.json'),
'utf8'
)
);
// Read the entrypoints containing the initial JS to bootstrap everything.
// For other pages, the chunks in the RSC payload are enough.
const mainJSChunks = JSON.parse(
await virtualFs.readFile(
path.join(buildPath, 'entrypoint-manifest.json'),
'utf8'
)
).main.js;
// For HTML, we're a "client" emulator that runs the client code,
// so we start by consuming the RSC payload. This needs a module
// map that reverse engineers the client-side path to the SSR path.
const root = await createFromNodeStream(rscResponse, moduleMap);
// Render it into HTML by resolving the client components
res.set('Content-type', 'text/html');
const {pipe} = renderToPipeableStream(root, {
bootstrapScripts: mainJSChunks,
});
pipe(res);
} catch (e) {
console.error(`Failed to SSR: ${e.stack}`);
res.statusCode = 500;
res.end();
}
} else {
try {
const rscResponse = await promiseForData;
// For other request, we pass-through the RSC payload.
res.set('Content-type', 'text/x-component');
rscResponse.on('data', data => {
res.write(data);
res.flush();
});
rscResponse.on('end', data => {
res.end();
});
} catch (e) {
console.error(`Failed to proxy request: ${e.stack}`);
res.statusCode = 500;
res.end();
}
}
});
if (process.env.NODE_ENV === 'development') {
app.use(express.static('public'));
} else {
// In production we host the static build output.
app.use(express.static('build'));
}
app.listen(3000, () => {
console.log('Global Fizz/Webpack Server listening on port 3000...');
});
app.on('error', function (error) {
if (error.syscall !== 'listen') {
throw error;
}
switch (error.code) {
case 'EACCES':
console.error('port 3000 requires elevated privileges');
process.exit(1);
break;
case 'EADDRINUSE':
console.error('Port 3000 is already in use');
process.exit(1);
break;
default:
throw error;
}
});

View File

@ -0,0 +1,30 @@
'use strict';
const {renderToPipeableStream} = require('react-server-dom-webpack/server');
const {readFile} = require('fs');
const {resolve} = require('path');
const React = require('react');
module.exports = function (req, res) {
// const m = require('../src/App.server.js');
import('../src/App.server.js').then(m => {
const dist = process.env.NODE_ENV === 'development' ? 'dist' : 'build';
readFile(
resolve(__dirname, `../${dist}/react-client-manifest.json`),
'utf8',
(err, data) => {
if (err) {
throw err;
}
const App = m.default.default || m.default;
res.setHeader('Access-Control-Allow-Origin', '*');
const moduleMap = JSON.parse(data);
const {pipe} = renderToPipeableStream(React.createElement(App), {
clientManifest: moduleMap,
});
pipe(res);
}
);
});
};

View File

@ -1,3 +1,4 @@
{
"type": "commonjs"
"type": "commonjs",
"main": "./cli.server.js"
}

View File

@ -1,199 +0,0 @@
'use strict';
// This is a server to host data-local resources like databases and RSC
const path = require('path');
const register = require('react-server-dom-webpack/node-register');
register();
const babelRegister = require('@babel/register');
babelRegister({
babelrc: false,
ignore: [
/\/(build|node_modules)\//,
function (file) {
if ((path.dirname(file) + '/').startsWith(__dirname + '/')) {
// Ignore everything in this folder
// because it's a mix of CJS and ESM
// and working with raw code is easier.
return true;
}
return false;
},
],
presets: ['react-app'],
plugins: ['@babel/transform-modules-commonjs'],
});
if (typeof fetch === 'undefined') {
// Patch fetch for earlier Node versions.
global.fetch = require('undici').fetch;
}
const express = require('express');
const bodyParser = require('body-parser');
const busboy = require('busboy');
const app = express();
const compress = require('compression');
const {Readable} = require('node:stream');
app.use(compress());
// Application
const {readFile} = require('fs').promises;
const React = require('react');
async function renderApp(res, returnValue) {
const {renderToPipeableStream} = await import(
'react-server-dom-webpack/server'
);
// const m = require('../src/App.js');
const m = await import('../src/App.js');
let moduleMap;
let mainCSSChunks;
if (process.env.NODE_ENV === 'development') {
// Read the module map from the HMR server in development.
moduleMap = await (
await fetch('http://localhost:3000/react-client-manifest.json')
).json();
mainCSSChunks = (
await (
await fetch('http://localhost:3000/entrypoint-manifest.json')
).json()
).main.css;
} else {
// Read the module map from the static build in production.
moduleMap = JSON.parse(
await readFile(
path.resolve(__dirname, `../build/react-client-manifest.json`),
'utf8'
)
);
mainCSSChunks = JSON.parse(
await readFile(
path.resolve(__dirname, `../build/entrypoint-manifest.json`),
'utf8'
)
).main.css;
}
const App = m.default.default || m.default;
const root = [
// Prepend the App's tree with stylesheets required for this entrypoint.
mainCSSChunks.map(filename =>
React.createElement('link', {
rel: 'stylesheet',
href: filename,
precedence: 'default',
})
),
React.createElement(App),
];
// For client-invoked server actions we refresh the tree and return a return value.
const payload = returnValue ? {returnValue, root} : root;
const {pipe} = renderToPipeableStream(payload, moduleMap);
pipe(res);
}
app.get('/', async function (req, res) {
await renderApp(res, null);
});
app.post('/', bodyParser.text(), async function (req, res) {
const {
renderToPipeableStream,
decodeReply,
decodeReplyFromBusboy,
decodeAction,
} = await import('react-server-dom-webpack/server');
const serverReference = req.get('rsc-action');
if (serverReference) {
// This is the client-side case
const [filepath, name] = serverReference.split('#');
const action = (await import(filepath))[name];
// Validate that this is actually a function we intended to expose and
// not the client trying to invoke arbitrary functions. In a real app,
// you'd have a manifest verifying this before even importing it.
if (action.$$typeof !== Symbol.for('react.server.reference')) {
throw new Error('Invalid action');
}
let args;
if (req.is('multipart/form-data')) {
// Use busboy to streamingly parse the reply from form-data.
const bb = busboy({headers: req.headers});
const reply = decodeReplyFromBusboy(bb);
req.pipe(bb);
args = await reply;
} else {
args = await decodeReply(req.body);
}
const result = action.apply(null, args);
try {
// Wait for any mutations
await result;
} catch (x) {
// We handle the error on the client
}
// Refresh the client and return the value
renderApp(res, result);
} else {
// This is the progressive enhancement case
const UndiciRequest = require('undici').Request;
const fakeRequest = new UndiciRequest('http://localhost', {
method: 'POST',
headers: {'Content-Type': req.headers['content-type']},
body: Readable.toWeb(req),
duplex: 'half',
});
const formData = await fakeRequest.formData();
const action = await decodeAction(formData);
try {
// Wait for any mutations
await action();
} catch (x) {
const {setServerState} = await import('../src/ServerState.js');
setServerState('Error: ' + x.message);
}
renderApp(res, null);
}
});
app.get('/todos', function (req, res) {
res.json([
{
id: 1,
text: 'Shave yaks',
},
{
id: 2,
text: 'Eat kale',
},
]);
});
app.listen(3001, () => {
console.log('Regional Flight Server listening on port 3001...');
});
app.on('error', function (error) {
if (error.syscall !== 'listen') {
throw error;
}
switch (error.code) {
case 'EACCES':
console.error('port 3001 requires elevated privileges');
process.exit(1);
break;
case 'EADDRINUSE':
console.error('Port 3001 is already in use');
process.exit(1);
break;
default:
throw error;
}
});

View File

@ -1,47 +0,0 @@
import * as React from 'react';
import Container from './Container.js';
import {Counter} from './Counter.js';
import {Counter as Counter2} from './Counter2.js';
import ShowMore from './ShowMore.js';
import Button from './Button.js';
import Form from './Form.js';
import {like, greet} from './actions.js';
import {getServerState} from './ServerState.js';
export default async function App() {
const res = await fetch('http://localhost:3001/todos');
const todos = await res.json();
return (
<html lang="en">
<head>
<meta charSet="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Flight</title>
</head>
<body>
<Container>
<h1>{getServerState()}</h1>
<Counter />
<Counter2 />
<ul>
{todos.map(todo => (
<li key={todo.id}>{todo.text}</li>
))}
</ul>
<ShowMore>
<p>Lorem ipsum</p>
</ShowMore>
<Form action={greet} />
<div>
<Button action={like}>Like</Button>
</div>
</Container>
</body>
</html>
);
}

View File

@ -0,0 +1,28 @@
import * as React from 'react';
import {fetch} from 'react-fetch';
import Container from './Container.js';
import {Counter} from './Counter.client.js';
import {Counter as Counter2} from './Counter2.client.js';
import ShowMore from './ShowMore.client.js';
export default function App() {
const todos = fetch('http://localhost:3001/todos').json();
return (
<Container>
<h1>Hello, world</h1>
<Counter />
<Counter2 />
<ul>
{todos.map(todo => (
<li key={todo.id}>{todo.text}</li>
))}
</ul>
<ShowMore>
<p>Lorem ipsum</p>
</ShowMore>
</Container>
);
}

View File

@ -1,26 +0,0 @@
'use client';
import * as React from 'react';
import {experimental_useFormStatus as useFormStatus} from 'react-dom';
import ErrorBoundary from './ErrorBoundary.js';
function ButtonDisabledWhilePending({action, children}) {
const {pending} = useFormStatus();
return (
<button disabled={pending} formAction={action}>
{children}
</button>
);
}
export default function Button({action, children}) {
return (
<ErrorBoundary>
<form>
<ButtonDisabledWhilePending action={action}>
{children}
</ButtonDisabledWhilePending>
</form>
</ErrorBoundary>
);
}

View File

@ -1,5 +1,3 @@
'use client';
import * as React from 'react';
import Container from './Container.js';

View File

@ -0,0 +1 @@
export * from './Counter.client.js';

View File

@ -1,3 +0,0 @@
'use client';
export * from './Counter.js';

View File

@ -1,16 +0,0 @@
'use client';
import * as React from 'react';
export default class ErrorBoundary extends React.Component {
state = {error: null};
static getDerivedStateFromError(error) {
return {error};
}
render() {
if (this.state.error) {
return <div>Caught an error: {this.state.error.message}</div>;
}
return this.props.children;
}
}

View File

@ -1,29 +0,0 @@
'use client';
import * as React from 'react';
import {experimental_useFormStatus as useFormStatus} from 'react-dom';
import ErrorBoundary from './ErrorBoundary.js';
function Status() {
const {pending} = useFormStatus();
return pending ? 'Saving...' : null;
}
export default function Form({action, children}) {
const [isPending, setIsPending] = React.useState(false);
return (
<ErrorBoundary>
<form action={action}>
<label>
Name: <input name="name" />
</label>
<label>
File: <input type="file" name="file" />
</label>
<button>Say Hi</button>
<Status />
</form>
</ErrorBoundary>
);
}

View File

@ -1,9 +0,0 @@
let serverState = 'Hello World';
export function setServerState(message) {
serverState = message;
}
export function getServerState() {
return serverState;
}

View File

@ -1,5 +1,3 @@
'use client';
import * as React from 'react';
import Container from './Container.js';

View File

@ -1,20 +0,0 @@
'use server';
import {setServerState} from './ServerState.js';
export async function like() {
setServerState('Liked!');
return new Promise((resolve, reject) => resolve('Liked'));
}
export async function greet(formData) {
const name = formData.get('name') || 'you';
setServerState('Hi ' + name);
const file = formData.get('file');
if (file) {
return `Ok, ${name}, here is ${file.name}:
${(await file.text()).toUpperCase()}
`;
}
return 'Hi ' + name + '!';
}

View File

@ -1,44 +1,16 @@
import * as React from 'react';
import {use, Suspense, useState, startTransition} from 'react';
import {Suspense} from 'react';
import ReactDOM from 'react-dom/client';
import {createFromFetch, encodeReply} from 'react-server-dom-webpack/client';
import ReactServerDOMReader from 'react-server-dom-webpack/client';
// TODO: This should be a dependency of the App but we haven't implemented CSS in Node yet.
import './style.css';
let data = ReactServerDOMReader.createFromFetch(fetch('http://localhost:3001'));
let updateRoot;
async function callServer(id, args) {
const response = fetch('/', {
method: 'POST',
headers: {
Accept: 'text/x-component',
'rsc-action': id,
},
body: await encodeReply(args),
});
const {returnValue, root} = await createFromFetch(response, {callServer});
// Refresh the tree with the new RSC payload.
startTransition(() => {
updateRoot(root);
});
return returnValue;
function Content() {
return React.use(data);
}
let data = createFromFetch(
fetch('/', {
headers: {
Accept: 'text/x-component',
},
}),
{
callServer,
}
ReactDOM.createRoot(document.getElementById('root')).render(
<Suspense fallback={<h1>Loading...</h1>}>
<Content />
</Suspense>
);
function Shell({data}) {
const [root, setRoot] = useState(use(data));
updateRoot = setRoot;
return root;
}
ReactDOM.hydrateRoot(document, <Shell data={data} />);

View File

@ -1,3 +0,0 @@
body {
font-family: Helvetica;
}

File diff suppressed because it is too large Load Diff

View File

@ -2,20 +2,18 @@
"dependencies": {
"@babel/plugin-transform-modules-commonjs": "^7.10.4",
"@babel/preset-react": "^7.10.4",
"jest": "^29.4.1"
"jest": "^26.5.3"
},
"jest": {
"setupFilesAfterEnv": [
"./setupTests.js"
]
"setupFilesAfterEnv": ["./setupTests.js"]
},
"scripts": {
"install-all": "cd react-14 && yarn && cd ../react-15 && yarn && cd ../react-16 && yarn && cd ../react-17 && yarn && cd ..",
"lint": "node lint-runtimes.js",
"pretest": "yarn install-all && yarn lint",
"test-jsxdev-dev": "BABEL_ENV=development NODE_ENV=development jest --env=jsdom",
"test-jsx-dev": "BABEL_ENV=production NODE_ENV=development jest --env=jsdom",
"test-jsx-prod": "BABEL_ENV=production NODE_ENV=production jest --env=jsdom",
"test-jsxdev-dev": "BABEL_ENV=development NODE_ENV=development jest",
"test-jsx-dev": "BABEL_ENV=production NODE_ENV=development jest",
"test-jsx-prod": "BABEL_ENV=production NODE_ENV=production jest",
"test": "yarn test-jsxdev-dev && yarn test-jsx-dev && yarn test-jsx-prod"
}
}

View File

@ -5,7 +5,7 @@
const expect = global.expect;
const {diff: jestDiff} = require('jest-diff');
const jestDiff = require('jest-diff').default;
const util = require('util');
function shouldIgnoreConsoleError(format, args) {

File diff suppressed because it is too large Load Diff

View File

@ -15,9 +15,9 @@
"watch:legacy": "cpx 'src/shared/**' 'src/legacy/shared/' --watch --no-initial",
"watch:modern": "cpx 'src/shared/**' 'src/modern/shared/' --watch --no-initial",
"prebuild": "run-p copy:*",
"predev": "run-p copy:*",
"dev": "run-p dev-app watch:*",
"dev-app": "react-scripts start",
"prestart": "run-p copy:*",
"start": "run-p start-app watch:*",
"start-app": "react-scripts start",
"build": "react-scripts build",
"eject": "react-scripts eject"
},

View File

@ -1,7 +1,7 @@
<html>
<body>
<script src="../../../build/oss-experimental/react/umd/react.development.js"></script>
<script src="../../../build/oss-experimental/react-dom/umd/react-dom.development.js"></script>
<script src="../../../build/node_modules/react/umd/react.development.js"></script>
<script src="../../../build/node_modules/react-dom/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/babel-standalone@6/babel.js"></script>
<div id="container"></div>
<script type="text/babel">

View File

@ -6,6 +6,6 @@
},
"scripts": {
"build": "rm -f output.js && browserify ./input.js -o output.js",
"prebuild": "cp -r ../../../../build/oss-experimental/* ./node_modules/"
"prebuild": "cp -r ../../../../build/node_modules/* ./node_modules/"
}
}

View File

@ -6,7 +6,7 @@
},
"scripts": {
"build": "rm -f output.js && browserify ./input.js -g [envify --NODE_ENV 'production'] -o output.js",
"prebuild": "cp -r ../../../../build/oss-experimental/* ./node_modules/"
"prebuild": "cp -r ../../../../build/node_modules/* ./node_modules/"
},
"devDependencies": {
"envify": "^4.0.0"

Some files were not shown because too many files have changed in this diff Show More