diff --git a/.cargo/config.toml b/.cargo/config.toml index aa9e2d561c2db..c73baee6b159c 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -17,10 +17,22 @@ rustdocflags = [] [target.x86_64-pc-windows-msvc] linker = "rust-lld" -rustflags = ["-C", "target-feature=+crt-static"] +rustflags = [ + "--cfg", + "tokio_unstable", + "-Zshare-generics=y", + "-C", + "target-feature=+crt-static" +] [target.i686-pc-windows-msvc] -rustflags = ["-C", "target-feature=+crt-static"] +rustflags = [ + "--cfg", + "tokio_unstable", + "-Zshare-generics=y", + "-C", + "target-feature=+crt-static" +] [target.aarch64-pc-windows-msvc] linker = "rust-lld" @@ -42,6 +54,7 @@ rustflags = [ [target.aarch64-unknown-linux-musl] linker = "aarch64-linux-musl-gcc" +# Config need to be mirrowed to .github/workflows/build_and_deploy.yml rustflags = [ "--cfg", "tokio_unstable", @@ -51,5 +64,16 @@ rustflags = [ "-Clink-arg=-lgcc", ] +[target.x86_64-unknown-linux-musl] +# Config need to be mirrowed to .github/workflows/build_and_deploy.yml +rustflags = [ + "--cfg", + "tokio_unstable", + "-Zshare-generics=y", + "-Zthreads=8", + "-Csymbol-mangling-version=v0", + "-Ctarget-feature=-crt-static", +] + [target.armv7-unknown-linux-gnueabihf] linker = "arm-linux-gnueabihf-gcc" diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index 9db6f2118da64..37532e6f63f20 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -28,4 +28,5 @@ RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \ # RUN su node -c "npm install -g " # Enable pnpm +RUN npm i -g corepack@latest RUN corepack enable pnpm \ No newline at end of file diff --git a/.eslintrc.json b/.eslintrc.json index 70781e88e2756..f6dd37deadcfa 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -162,7 +162,7 @@ "files": ["packages/**"], "excludedFiles": [ "packages/next/taskfile*.js", - "packages/next/next_runtime.config.js" + "packages/next/next-runtime.webpack-config.js" ], "rules": { "no-shadow": ["error", { "builtinGlobals": false }], diff --git a/.github/ISSUE_TEMPLATE/1.bug_report.yml b/.github/ISSUE_TEMPLATE/1.bug_report.yml index 37bd59d214985..c71ed39859946 100644 --- a/.github/ISSUE_TEMPLATE/1.bug_report.yml +++ b/.github/ISSUE_TEMPLATE/1.bug_report.yml @@ -82,27 +82,31 @@ body: - 'create-next-app' - 'CSS' - 'dynamicIO' + - 'Dynamic Routes' - 'Error Handling' - - 'Experimental' - 'Lazy Loading' - 'Font (next/font)' - 'Form (next/form)' - 'Image (next/image)' - 'Instrumentation' - 'Internationalization (i18n)' - - 'Link (next/link)' + - 'Linking and Navigating' - 'Linting' + - 'Loading UI and Streaming' - 'Markdown (MDX)' - 'Metadata' - 'Middleware' - 'Module Resolution' - - 'Output (export/standalone)' + - 'Output' + - 'Package Managers' - 'Pages Router' - 'Parallel & Intercepting Routes' - 'Partial Prerendering (PPR)' - 'Performance' - 'React' + - 'Redirects' - 'Route Groups' + - 'Route Handlers' - 'Runtime' - 'Script (next/script)' - 'Server Actions' @@ -110,6 +114,7 @@ body: - 'Turbopack' - 'TypeScript' - 'SWC' + - 'Use Cache' - 'Webpack' validations: diff --git a/.github/actions/next-stats-action/Dockerfile b/.github/actions/next-stats-action/Dockerfile index aea5978124198..1ba64a9132111 100644 --- a/.github/actions/next-stats-action/Dockerfile +++ b/.github/actions/next-stats-action/Dockerfile @@ -12,6 +12,7 @@ RUN apt install unzip wget curl nano htop screen build-essential pkg-config libs RUN ln $(which python3) /usr/bin/python RUN curl -sfLS https://install-node.vercel.app/v18.18.2 | bash -s -- -f +RUN npm i -g corepack@0.31 RUN corepack enable WORKDIR /next-stats diff --git a/.github/workflows/build_and_deploy.yml b/.github/workflows/build_and_deploy.yml index c1dcf16358b2b..8ddf8088175dc 100644 --- a/.github/workflows/build_and_deploy.yml +++ b/.github/workflows/build_and_deploy.yml @@ -29,7 +29,10 @@ jobs: with: node-version: ${{ env.NODE_LTS_VERSION }} check-latest: true - - run: corepack enable + - name: Setup corepack + run: | + npm i -g corepack@0.31 + corepack enable - name: Determine deploy target # 'force-preview' performs a full preview build but only if acknowledged i.e. workflow_dispatch # 'automated-preview' for pushes on branches other than 'canary' for integration testing. @@ -70,7 +73,10 @@ jobs: with: node-version: ${{ env.NODE_LTS_VERSION }} check-latest: true - - run: corepack enable + - name: Setup corepack + run: | + npm i -g corepack@0.31 + corepack enable - uses: actions/checkout@v4 with: @@ -225,6 +231,7 @@ jobs: rustup show && rustup target add x86_64-unknown-linux-musl && npm i -g "@napi-rs/cli@${NAPI_CLI_VERSION}" && + export RUSTFLAGS="--cfg tokio_unstable -Zshare-generics=y -Zthreads=8 -Csymbol-mangling-version=v0 -Ctarget-feature=-crt-static" && cd packages/next-swc && npm run build-native-release -- --target x86_64-unknown-linux-musl && strip native/next-swc.*.node @@ -266,6 +273,7 @@ jobs: npm i -g "@napi-rs/cli@${NAPI_CLI_VERSION}" && rustup show && rustup target add aarch64-unknown-linux-musl && + export RUSTFLAGS="--cfg tokio_unstable -Zshare-generics=y -Zthreads=8 -Zunstable-options -Csymbol-mangling-version=v0 -Clinker-flavor=gnu-lld-cc -Clink-self-contained=+linker" && cd packages/next-swc && npm run build-native-release -- --target aarch64-unknown-linux-musl && llvm-strip -x native/next-swc.*.node @@ -458,7 +466,10 @@ jobs: with: node-version: ${{ env.NODE_LTS_VERSION }} check-latest: true - - run: corepack enable + - name: Setup corepack + run: | + npm i -g corepack@0.31 + corepack enable # https://github.com/actions/virtual-environments/issues/1187 - name: tune linux network @@ -518,7 +529,10 @@ jobs: with: node-version: ${{ env.NODE_LTS_VERSION }} check-latest: true - - run: corepack enable + - name: Setup corepack + run: | + npm i -g corepack@0.31 + corepack enable # https://github.com/actions/virtual-environments/issues/1187 - name: tune linux network @@ -576,7 +590,10 @@ jobs: with: node-version: ${{ env.NODE_LTS_VERSION }} check-latest: true - - run: corepack enable + - name: Setup corepack + run: | + npm i -g corepack@0.31 + corepack enable - uses: ./.github/actions/setup-rust with: diff --git a/.github/workflows/build_and_test.yml b/.github/workflows/build_and_test.yml index 0936964a0749f..e25d883f4a7d7 100644 --- a/.github/workflows/build_and_test.yml +++ b/.github/workflows/build_and_test.yml @@ -108,7 +108,10 @@ jobs: - uses: actions/setup-node@v4 with: node-version: 18 - - run: corepack enable + - name: Setup corepack + run: | + npm i -g corepack@0.31 + corepack enable - name: 'Run link checker' run: node ./.github/actions/validate-docs-links/dist/index.js env: diff --git a/.github/workflows/code_freeze.yml b/.github/workflows/code_freeze.yml index b66e2b880bf75..d3a7e9884d224 100644 --- a/.github/workflows/code_freeze.yml +++ b/.github/workflows/code_freeze.yml @@ -31,7 +31,10 @@ jobs: with: node-version: 18 check-latest: true - - run: corepack enable + - name: Setup corepack + run: | + npm i -g corepack@0.31 + corepack enable - run: git clone https://github.com/vercel/next.js.git --depth=1 . diff --git a/.github/workflows/issue_wrong_template.yml b/.github/workflows/issue_wrong_template.yml index ec0a58a676bd0..21d10b3afcefb 100644 --- a/.github/workflows/issue_wrong_template.yml +++ b/.github/workflows/issue_wrong_template.yml @@ -11,7 +11,10 @@ jobs: steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 - - run: corepack enable + - name: Setup corepack + run: | + npm i -g corepack@0.31 + corepack enable - name: 'Close issues using the wrong issue template' run: node ./.github/actions/next-repo-actions/dist/wrong-issue-template/index.js env: diff --git a/.github/workflows/popular.yml b/.github/workflows/popular.yml index b97f2609306a9..8224d325d0fb9 100644 --- a/.github/workflows/popular.yml +++ b/.github/workflows/popular.yml @@ -12,7 +12,10 @@ jobs: steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 - - run: corepack enable + - name: Setup corepack + run: | + npm i -g corepack@0.31 + corepack enable - name: 'Issues: Send notification to Slack' run: node ./.github/actions/next-repo-actions/dist/issues/index.mjs continue-on-error: true diff --git a/.github/workflows/rspack-nextjs-build-integration-tests.yml b/.github/workflows/rspack-nextjs-build-integration-tests.yml new file mode 100644 index 0000000000000..673742d73eab2 --- /dev/null +++ b/.github/workflows/rspack-nextjs-build-integration-tests.yml @@ -0,0 +1,211 @@ +# Reusable workflow to execute certain version of Next.js integration tests +# with Rspack. +# +# Refer test.yml for how this workflow is being initialized +# - Workflow can specify `inputs.version` to specify which version of next.js to use, otherwise will use latest release version. +name: Rspack Next.js production integration tests + +on: + schedule: + - cron: '0 6 * * *' + workflow_dispatch: + inputs: + # Allow to specify Next.js version to run integration test against. + # If not specified, will use latest release version including canary. + version: + description: Next.js version, sha, branch to test + type: string + default: 'canary' + # The base of the test results to compare against. If not specified, will try to compare with latest main branch's test results. + diff_base: + type: string + default: 'none' + +# Workflow-common env variables +env: + # Enabling backtrace will makes snapshot tests fail + RUST_BACKTRACE: 0 + NEXT_TELEMETRY_DISABLED: 1 + TEST_CONCURRENCY: 6 + NEXT_JUNIT_TEST_REPORT: 'true' + NEXT_TEST_SKIP_RETRY_MANIFEST: ${{ github.workspace }}/integration-test-data/test-results/main/failed-test-path-list.json + NEXT_TEST_CONTINUE_ON_ERROR: TRUE + NEXT_E2E_TEST_TIMEOUT: 240000 + NEXT_TEST_JOB: 1 + +jobs: + # First, build Next.js to execute across tests. + setup_nextjs: + name: Setup Next.js build + uses: ./.github/workflows/setup-nextjs-build.yml + with: + nodeVersion: 18.18.2 + version: ${{ inputs.version || 'canary' }} + + # Actual test scheduling. These jobs mimic the same jobs in Next.js repo, + # which we do allow some of duplications to make it easier to update if upstream changes. + # Refer build_and_test.yml in the Next.js repo for more details. + test-production: + # This job name is being used in github action to collect test results. Do not change it, or should update + # ./.github/actions/next-integration-stat to match the new name. + name: Next.js integration test (Production) + # Currently it is possible test grouping puts large number of failing tests suites in a single group, + # which ends up job timeouts. Temporarily relieve the timeout until we make progresses on the failing suites. + # ref: https://github.com/vercel/turbo/pull/5668 + # timeout-minutes: 180 + runs-on: + - 'self-hosted' + - 'linux' + - 'x64' + - 'metal' + + needs: [setup_nextjs] + strategy: + fail-fast: false + matrix: + group: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12] + + steps: + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: 18.18.2 + check-latest: true + - uses: actions/cache/restore@v3 + id: restore-build + with: + path: ./* + key: ${{ inputs.version || 'canary' }}-${{ github.sha }}-${{ github.run_id }}-${{ github.run_attempt}}-${{ github.run_number }} + fail-on-cache-miss: true + + - name: Enable corepack and install yarn + run: | + corepack enable + corepack prepare --activate yarn@1.22.19 + + - name: Setup playwright + run: | + pnpm playwright install + + - name: Run test/production + run: | + NEXT_TEST_MODE=start NEXT_RSPACK=1 NEXT_E2E_TEST_TIMEOUT=240000 node run-tests.js -g ${{ matrix.group }}/12 -c ${TEST_CONCURRENCY} --type production + # It is currently expected to fail some of next.js integration test, do not fail CI check. + continue-on-error: true + + - name: Upload test report artifacts + uses: actions/upload-artifact@v4 + with: + name: test-reports-start-${{ matrix.group }} + if-no-files-found: 'error' + path: | + test/rspack-test-junit-report + + test-integration-production: + name: Next.js integration test (Integration) + needs: [setup_nextjs] + runs-on: + - 'self-hosted' + - 'linux' + - 'x64' + - 'metal' + + timeout-minutes: 180 + strategy: + fail-fast: false + matrix: + group: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12] + + steps: + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: 18.18.2 + check-latest: true + - uses: actions/cache/restore@v3 + id: restore-build + with: + path: ./* + key: ${{ inputs.version || 'canary' }}-${{ github.sha }} + fail-on-cache-miss: true + + - name: Enable corepack and install yarn + run: | + corepack enable + corepack prepare --activate yarn@1.22.19 + + - name: Setup playwright + run: | + pnpm playwright install + + - name: Run test/integration + run: | + NEXT_RSPACK=1 NEXT_E2E_TEST_TIMEOUT=240000 node run-tests.js -g ${{ matrix.group }}/12 -c ${TEST_CONCURRENCY} --type integration + continue-on-error: true + + - name: Upload test report artifacts + uses: actions/upload-artifact@v4 + with: + name: test-reports-build-integration-${{ matrix.group }} + if-no-files-found: 'error' + path: | + test/turbopack-test-junit-report + + # Collect integration test results from execute_tests, + # Store it as github artifact for next step to consume. + collect_nextjs_production_integration_stat: + needs: [test-production, test-integration-production] + name: Next.js integration test production status report + runs-on: + - 'self-hosted' + - 'linux' + - 'x64' + - 'metal' + + if: always() + permissions: + pull-requests: write + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Collect integration test stat + uses: ./.github/actions/next-integration-stat + with: + diff_base: ${{ inputs.diff_base || 'none' }} + + - name: Store artifacts + uses: actions/upload-artifact@v4 + with: + name: test-results-rspack-production + path: | + nextjs-test-results.json + failed-test-path-list.json + passed-test-path-list.json + + upload_test_report: + needs: [test-production, test-integration-production] + name: Upload test report to datadog + runs-on: + - 'self-hosted' + - 'linux' + - 'x64' + - 'metal' + + if: ${{ !cancelled() }} + steps: + - name: Download test report artifacts + id: download-test-reports + uses: actions/download-artifact@v4 + with: + pattern: test-reports-* + path: test/reports + merge-multiple: true + + - name: Upload to datadog + env: + DATADOG_API_KEY: ${{ secrets.DATA_DOG_API_KEY }} + DD_ENV: 'ci' + run: | + # We'll tag this to the "rspack" datadog service, not "nextjs" + npx @datadog/datadog-ci@2.23.1 junit upload --tags test.type:rspack-build.daily --service rspack-build ./test/reports diff --git a/.github/workflows/rspack-nextjs-dev-integration-tests.yml b/.github/workflows/rspack-nextjs-dev-integration-tests.yml new file mode 100644 index 0000000000000..b7eb142757402 --- /dev/null +++ b/.github/workflows/rspack-nextjs-dev-integration-tests.yml @@ -0,0 +1,211 @@ +# Reusable workflow to execute certain version of Next.js integration tests +# with Rspack. +# +# Refer test.yml for how this workflow is being initialized +# - Workflow can specify `inputs.version` to specify which version of next.js to use, otherwise will use latest release version. +name: Rspack Next.js development integration tests + +on: + schedule: + - cron: '0 6 * * *' + workflow_dispatch: + inputs: + # Allow to specify Next.js version to run integration test against. + # If not specified, will use latest release version including canary. + version: + description: Next.js version, sha, branch to test + type: string + default: 'canary' + # The base of the test results to compare against. If not specified, will try to compare with latest main branch's test results. + diff_base: + type: string + default: 'none' + +# Workflow-common env variables +env: + # Enabling backtrace will makes snapshot tests fail + RUST_BACKTRACE: 0 + NEXT_TELEMETRY_DISABLED: 1 + TEST_CONCURRENCY: 6 + NEXT_JUNIT_TEST_REPORT: 'true' + NEXT_TEST_SKIP_RETRY_MANIFEST: ${{ github.workspace }}/integration-test-data/test-results/main/failed-test-path-list.json + NEXT_TEST_CONTINUE_ON_ERROR: TRUE + NEXT_E2E_TEST_TIMEOUT: 240000 + NEXT_TEST_JOB: 1 + +jobs: + # First, build next-dev and Next.js both to execute across tests. + setup_nextjs: + name: Setup Next.js build + uses: ./.github/workflows/setup-nextjs-build.yml + with: + nodeVersion: 18.18.2 + version: ${{ inputs.version || 'canary' }} + + # Actual test scheduling. These jobs mimic the same jobs in Next.js repo, + # which we do allow some of duplications to make it easier to update if upstream changes. + # Refer build_and_test.yml in the Next.js repo for more details. + test-dev: + # This job name is being used in github action to collect test results. Do not change it, or should update + # ./.github/actions/next-integration-stat to match the new name. + name: Next.js integration test (Development) + # Currently it is possible test grouping puts large number of failing tests suites in a single group, + # which ends up job timeouts. Temporarily relieve the timeout until we make progresses on the failing suites. + # ref: https://github.com/vercel/turbo/pull/5668 + # timeout-minutes: 180 + runs-on: + - 'self-hosted' + - 'linux' + - 'x64' + - 'metal' + + needs: [setup_nextjs] + strategy: + fail-fast: false + matrix: + group: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12] + + steps: + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: 18.18.2 + check-latest: true + - uses: actions/cache/restore@v3 + id: restore-build + with: + path: ./* + key: ${{ inputs.version || 'canary' }}-${{ github.sha }}-${{ github.run_id }}-${{ github.run_attempt}}-${{ github.run_number }} + fail-on-cache-miss: true + + - name: Enable corepack and install yarn + run: | + corepack enable + corepack prepare --activate yarn@1.22.19 + + - name: Setup playwright + run: | + pnpm playwright install + + - name: Run test/development + run: | + NEXT_TEST_MODE=dev NEXT_RSPACK=1 NEXT_E2E_TEST_TIMEOUT=240000 node run-tests.js -g ${{ matrix.group }}/12 -c ${TEST_CONCURRENCY} --type development + # It is currently expected to fail some of next.js integration test, do not fail CI check. + continue-on-error: true + + - name: Upload test report artifacts + uses: actions/upload-artifact@v4 + with: + name: test-reports-dev-${{ matrix.group }} + if-no-files-found: 'error' + path: | + test/rspack-test-junit-report + + test-integration-development: + name: Next.js integration test (Integration) + needs: [setup_nextjs] + runs-on: + - 'self-hosted' + - 'linux' + - 'x64' + - 'metal' + + timeout-minutes: 180 + strategy: + fail-fast: false + matrix: + group: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12] + + steps: + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: 18.18.2 + check-latest: true + - uses: actions/cache/restore@v3 + id: restore-build + with: + path: ./* + key: ${{ inputs.version || 'canary' }}-${{ github.sha }} + fail-on-cache-miss: true + + - name: Enable corepack and install yarn + run: | + corepack enable + corepack prepare --activate yarn@1.22.19 + + - name: Setup playwright + run: | + pnpm playwright install + + - name: Run test/integration + run: | + NEXT_RSPACK=1 NEXT_E2E_TEST_TIMEOUT=240000 node run-tests.js -g ${{ matrix.group }}/12 -c ${TEST_CONCURRENCY} --type integration + continue-on-error: true + + - name: Upload test report artifacts + uses: actions/upload-artifact@v4 + with: + name: test-reports-dev-integration-${{ matrix.group }} + if-no-files-found: 'error' + path: | + test/rspack-test-junit-report + + # Collect integration test results from execute_tests, + # Store it as github artifact for next step to consume. + collect_nextjs_development_integration_stat: + needs: [test-dev, test-integration-development] + name: Next.js integration test development status report + runs-on: + - 'self-hosted' + - 'linux' + - 'x64' + - 'metal' + + if: always() + permissions: + pull-requests: write + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Collect integration test stat + uses: ./.github/actions/next-integration-stat + with: + diff_base: ${{ inputs.diff_base || 'none' }} + + - name: Store artifacts + uses: actions/upload-artifact@v4 + with: + name: test-results-rspack-development + path: | + nextjs-test-results.json + failed-test-path-list.json + passed-test-path-list.json + + upload_test_report: + needs: [test-dev, test-integration-development] + name: Upload test report to datadog + runs-on: + - 'self-hosted' + - 'linux' + - 'x64' + - 'metal' + + if: ${{ !cancelled() }} + steps: + - name: Download test report artifacts + id: download-test-reports + uses: actions/download-artifact@v4 + with: + pattern: test-reports-* + path: test/reports + merge-multiple: true + + - name: Upload to datadog + env: + DATADOG_API_KEY: ${{ secrets.DATA_DOG_API_KEY }} + DD_ENV: 'ci' + run: | + # We'll tag this to the "rspack" datadog service, not "nextjs" + npx @datadog/datadog-ci@2.23.1 junit upload --tags test.type:rspack.daily --service rspack ./test/reports diff --git a/.github/workflows/rspack-update-tests-manifest.yml b/.github/workflows/rspack-update-tests-manifest.yml new file mode 100644 index 0000000000000..76342b0501990 --- /dev/null +++ b/.github/workflows/rspack-update-tests-manifest.yml @@ -0,0 +1,82 @@ +# A recurring workflow which updates the passing/failing/skipped integration tests for Turbopack. +name: Update Rspack test manifest + +on: + schedule: + # Every day at 9AM https://crontab.guru/#0_9_*_*_* + - cron: '0 7 * * *' + workflow_dispatch: + +jobs: + update_dev_manifest: + name: Update and upload Rspack development test manifest + if: github.repository_owner == 'vercel' + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + # Commits made with the default `GITHUB_TOKEN` won't trigger workflows. + # See: https://docs.github.com/en/actions/security-guides/automatic-token-authentication#using-the-github_token-in-a-workflow + token: ${{ secrets.RELEASE_BOT_GITHUB_TOKEN }} + + - name: Setup node + uses: actions/setup-node@v4 + with: + node-version: ${{ env.NODE_LTS_VERSION }} + check-latest: true + + - name: Setup corepack + run: | + npm i -g corepack@0.31 + corepack enable + + - name: Install dependencies + shell: bash + run: pnpm i + + - name: Create Pull Request + shell: bash + run: node scripts/automated-update-workflow.js + env: + GITHUB_TOKEN: ${{ secrets.GH_TOKEN_PULL_REQUESTS }} + BRANCH_NAME: rspack-manifest + SCRIPT: test/build-rspack-dev-tests-manifest.js + PR_TITLE: Update Rspack development test manifest + PR_BODY: This auto-generated PR updates the development integration test manifest used when testing Rspack. + update_build_manifest: + name: Update and upload Rspack production test manifest + if: github.repository_owner == 'vercel' + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + # Commits made with the default `GITHUB_TOKEN` won't trigger workflows. + # See: https://docs.github.com/en/actions/security-guides/automatic-token-authentication#using-the-github_token-in-a-workflow + token: ${{ secrets.RELEASE_BOT_GITHUB_TOKEN }} + + - name: Setup node + uses: actions/setup-node@v4 + with: + node-version: ${{ env.NODE_LTS_VERSION }} + check-latest: true + + - name: Setup corepack + run: | + npm i -g corepack@0.31 + corepack enable + + - name: Install dependencies + shell: bash + run: pnpm i + + - name: Create Pull Request + shell: bash + run: node scripts/automated-update-workflow.js + env: + GITHUB_TOKEN: ${{ secrets.GH_TOKEN_PULL_REQUESTS }} + BRANCH_NAME: rspack-manifest + SCRIPT: test/build-rspack-build-tests-manifest.js + PR_TITLE: Update Rspack production test manifest + PR_BODY: This auto-generated PR updates the production integration test manifest used when testing Rspack. diff --git a/.github/workflows/setup-nextjs-build.yml b/.github/workflows/setup-nextjs-build.yml index c3b9911c792cb..29a3f8369fc80 100644 --- a/.github/workflows/setup-nextjs-build.yml +++ b/.github/workflows/setup-nextjs-build.yml @@ -82,6 +82,7 @@ jobs: run: | wget https://github.com/sharkdp/hyperfine/releases/download/v1.16.1/hyperfine_1.16.1_amd64.deb sudo dpkg -i hyperfine_1.16.1_amd64.deb + npm i -g corepack@0.31 corepack enable pnpm install --loglevel error diff --git a/.github/workflows/test_e2e_deploy_release.yml b/.github/workflows/test_e2e_deploy_release.yml index f8311f1c9ba57..7bb51cbda9499 100644 --- a/.github/workflows/test_e2e_deploy_release.yml +++ b/.github/workflows/test_e2e_deploy_release.yml @@ -25,7 +25,9 @@ jobs: check-latest: true - name: Setup pnpm - run: corepack enable + run: | + npm i -g corepack@0.31 + corepack enable - name: Checkout uses: actions/checkout@v4 diff --git a/.github/workflows/test_examples.yml b/.github/workflows/test_examples.yml index 4533894b4c157..e0a88fe51b50d 100644 --- a/.github/workflows/test_examples.yml +++ b/.github/workflows/test_examples.yml @@ -39,7 +39,10 @@ jobs: with: node-version: 18 check-latest: true - - run: corepack enable + - name: Setup corepack + run: | + npm i -g corepack@0.31 + corepack enable - run: pnpm install - run: pnpm build diff --git a/.github/workflows/triage_with_ai.yml b/.github/workflows/triage_with_ai.yml index bd99efd52fd88..252d90e4c088c 100644 --- a/.github/workflows/triage_with_ai.yml +++ b/.github/workflows/triage_with_ai.yml @@ -10,7 +10,10 @@ jobs: steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 - - run: corepack enable + - name: Setup corepack + run: | + npm i -g corepack@0.31 + corepack enable - name: 'Send report to Slack (AI-powered)' run: node ./.github/actions/next-repo-actions/dist/triage-issues-with-ai/index.js env: diff --git a/.github/workflows/trigger_release.yml b/.github/workflows/trigger_release.yml index 37f276405b452..fb075cc7becd8 100644 --- a/.github/workflows/trigger_release.yml +++ b/.github/workflows/trigger_release.yml @@ -82,7 +82,11 @@ jobs: - name: tune linux network run: sudo ethtool -K eth0 tx off rx off - - run: corepack enable && pnpm --version + - name: Setup corepack + run: | + npm i -g corepack@0.31 + corepack enable + pnpm --version - id: get-store-path run: echo STORE_PATH=$(pnpm store path) >> $GITHUB_OUTPUT diff --git a/.github/workflows/turbopack-nextjs-dev-integration-tests.yml b/.github/workflows/turbopack-nextjs-dev-integration-tests.yml index 8e4136b8c8542..58759b48a3767 100644 --- a/.github/workflows/turbopack-nextjs-dev-integration-tests.yml +++ b/.github/workflows/turbopack-nextjs-dev-integration-tests.yml @@ -178,7 +178,7 @@ jobs: - name: Store artifacts uses: actions/upload-artifact@v4 with: - name: test-results + name: test-results-turbopack-development path: | nextjs-test-results.json failed-test-path-list.json diff --git a/.github/workflows/turbopack-update-tests-manifest.yml b/.github/workflows/turbopack-update-tests-manifest.yml index 550c9776180f4..8dc4ce2b64f0c 100644 --- a/.github/workflows/turbopack-update-tests-manifest.yml +++ b/.github/workflows/turbopack-update-tests-manifest.yml @@ -26,7 +26,10 @@ jobs: node-version: ${{ env.NODE_LTS_VERSION }} check-latest: true - - run: corepack enable + - name: Setup corepack + run: | + npm i -g corepack@0.31 + corepack enable - name: Install dependencies shell: bash diff --git a/.github/workflows/turbopack-upload-tests-manifest.yml b/.github/workflows/turbopack-upload-tests-manifest.yml index 39eddeb3f8c69..597bf4954163d 100644 --- a/.github/workflows/turbopack-upload-tests-manifest.yml +++ b/.github/workflows/turbopack-upload-tests-manifest.yml @@ -27,7 +27,10 @@ jobs: - name: Checkout uses: actions/checkout@v4 - - run: corepack enable + - name: Setup corepack + run: | + npm i -g corepack@0.31 + corepack enable - name: Install dependencies shell: bash diff --git a/.github/workflows/update_fonts_data.yml b/.github/workflows/update_fonts_data.yml index 76633e9ab5d3f..63b382ac29b42 100644 --- a/.github/workflows/update_fonts_data.yml +++ b/.github/workflows/update_fonts_data.yml @@ -28,7 +28,10 @@ jobs: node-version: ${{ env.NODE_LTS_VERSION }} check-latest: true - - run: corepack enable + - name: Setup corepack + run: | + npm i -g corepack@0.31 + corepack enable - name: Install dependencies shell: bash diff --git a/.github/workflows/update_react.yml b/.github/workflows/update_react.yml index f935de8e6cd34..58dfd64c4f4d2 100644 --- a/.github/workflows/update_react.yml +++ b/.github/workflows/update_react.yml @@ -39,7 +39,10 @@ jobs: node-version: ${{ env.NODE_LTS_VERSION }} check-latest: true - - run: corepack enable + - name: Setup corepack + run: | + npm i -g corepack@0.31 + corepack enable - name: Install dependencies shell: bash diff --git a/Cargo.lock b/Cargo.lock index efe302104fb73..0f474f6f61d1b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -420,7 +420,7 @@ version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ff6e472cdea888a4bd64f342f09b3f50e1886d32afe8df3d663c01140b811b18" dependencies = [ - "event-listener 5.3.1", + "event-listener 5.4.0", "event-listener-strategy", "pin-project-lite", ] @@ -744,9 +744,9 @@ dependencies = [ [[package]] name = "binding_macros" -version = "10.0.0" +version = "12.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "440746af4e54fe815db0079c93a341b74ffa307cdc6ccc0fd6f2ee3bce0bf2b4" +checksum = "16ed992f7f441e9a53b679f72fd7dda26241ef4ff34d5aae39000acf88d7f74f" dependencies = [ "anyhow", "console_error_panic_hook", @@ -850,9 +850,9 @@ dependencies = [ [[package]] name = "browserslist-rs" -version = "0.16.0" +version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdf0ca73de70c3da94e4194e4a01fe732378f55d47cf4c0588caab22a0dbfa14" +checksum = "74c973b79d9b6b89854493185ab760c6ef8e54bcfad10ad4e33991e46b374ac8" dependencies = [ "ahash 0.8.11", "chrono", @@ -860,7 +860,6 @@ dependencies = [ "indexmap 2.7.1", "itertools 0.13.0", "nom", - "once_cell", "serde", "serde_json", "thiserror", @@ -2230,11 +2229,12 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "erased-serde" -version = "0.3.25" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f2b0c2380453a92ea8b6c8e5f64ecaafccddde8ceab55ff7a8ac1029f894569" +checksum = "24e2389d65ab4fab27dc2a5de7b191e1f6617d1f1c8855c0dc569c94a4cbb18d" dependencies = [ "serde", + "typeid", ] [[package]] @@ -2266,9 +2266,9 @@ dependencies = [ [[package]] name = "event-listener" -version = "5.3.1" +version = "5.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6032be9bd27023a771701cc49f9f053c751055f71efb2e0ae5c15809093675ba" +checksum = "3492acde4c3fc54c845eaab3eed8bd00c7a7d881f78bfc801e43a93dec1331ae" dependencies = [ "concurrent-queue", "parking", @@ -2281,7 +2281,7 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0f214dc438f977e6d4e3500aaa277f5ad94ca83fbbd9b1a15713ce2344ccc5a1" dependencies = [ - "event-listener 5.3.1", + "event-listener 5.4.0", "pin-project-lite", ] @@ -2837,9 +2837,9 @@ dependencies = [ [[package]] name = "hstr" -version = "0.2.15" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63d6824358c0fd9a68bb23999ed2ef76c84f79408a26ef7ae53d5f370c94ad36" +checksum = "a1a26def229ea95a8709dad32868d975d0dd40235bd2ce82920e4a8fe692b5e0" dependencies = [ "hashbrown 0.14.5", "new_debug_unreachable", @@ -4084,8 +4084,7 @@ dependencies = [ [[package]] name = "mdxjs" version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0749f4b14cd606b8c01bd9d4fb8c0b026804190ae9b3fe7d43feb898333ccd90" +source = "git+https://github.com/kdy1/mdxjs-rs.git?branch=swc-core-11#c87f8e40a98c93a22bc78cdd525fd7ff8c8fde2c" dependencies = [ "markdown", "serde", @@ -4245,9 +4244,9 @@ dependencies = [ [[package]] name = "modularize_imports" -version = "0.72.0" +version = "0.74.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c0aee0d722058acd0288f7fc39b973cb1971b8657afbea7a5fc87d8acf3e0bb" +checksum = "e2d9813134499d4517a2f25ac193eb2d346fda3a384df1f8cc51eeff547bd014" dependencies = [ "convert_case", "handlebars", @@ -5341,9 +5340,9 @@ checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" [[package]] name = "preset_env_base" -version = "1.0.0" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c8a797e42c09d55157424ac6e9b6e9e5843fc68b887691b280b055e8c3ca5e4" +checksum = "11eaf0ce8bb3041c3e2fd31286d493b3cf38fdb73198dd87de0273b6bdb2cc6d" dependencies = [ "ahash 0.8.11", "anyhow", @@ -5728,9 +5727,9 @@ dependencies = [ [[package]] name = "react_remove_properties" -version = "0.26.1" +version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7ffca0d8f2df49cfc21f9a7a1d639c1cccff31856dafcfa15a31120ddd31bb1" +checksum = "2914bfbbd9567e91004423f9d57f3cd2cf93cf3ab801ff13d9150be726105932" dependencies = [ "serde", "swc_atoms", @@ -5846,9 +5845,9 @@ checksum = "c707298afce11da2efef2f600116fa93ffa7a032b5d7b628aa17711ec81383ca" [[package]] name = "remove_console" -version = "0.27.1" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bd11c34d717fcd2912cf838997140160f4ae0b870b074466f6e728a89403dfe" +checksum = "0c2ecbdb43d58205863cbc8ca1a375bc1238c2ece7b6c6d873bb60090d82129d" dependencies = [ "serde", "swc_atoms", @@ -6424,9 +6423,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.135" +version = "1.0.138" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b0d7ba2887406110130a978386c4e1befb98c674b4fba677954e4db976630d9" +checksum = "d434192e7da787e94a6ea7e9670b26a036d0ca41e0b7efb2676dd32bae872949" dependencies = [ "indexmap 2.7.1", "itoa", @@ -6447,9 +6446,9 @@ dependencies = [ [[package]] name = "serde_qs" -version = "0.11.0" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c679fa27b429f2bb57fd4710257e643e86c966e716037259f8baa33de594a1b6" +checksum = "cd34f36fe4c5ba9654417139a9b3a20d2e1de6012ee678ad14d240c22c78d8d6" dependencies = [ "percent-encoding", "serde", @@ -6509,15 +6508,17 @@ dependencies = [ [[package]] name = "serde_with" -version = "2.3.2" +version = "3.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "331bb8c3bf9b92457ab7abecf07078c13f7d270ba490103e84e8b014490cd0b0" +checksum = "d6b6f7f2fcb69f747921f79f3926bd1e203fce4fef62c268dd3abfb6d86029aa" dependencies = [ - "base64 0.13.1", + "base64 0.22.1", "chrono", "hex", "indexmap 1.9.3", + "indexmap 2.7.1", "serde", + "serde_derive", "serde_json", "serde_with_macros", "time", @@ -6525,14 +6526,14 @@ dependencies = [ [[package]] name = "serde_with_macros" -version = "2.3.2" +version = "3.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "859011bddcc11f289f07f467cc1fe01c7a941daa4d8f6c40d4d1c92eb6d9319c" +checksum = "8d00caa5193a3c8362ac2b73be6b9e768aa5a4b2f721d8f4b339600c3cb51f8e" dependencies = [ - "darling 0.14.4", + "darling 0.20.8", "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.95", ] [[package]] @@ -6892,9 +6893,9 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "styled_components" -version = "0.100.1" +version = "0.102.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8bd437f52c22ee362baab2f49462f0d8a7df44194944acc2c8c38752aa83a98" +checksum = "a37e284714cc4612184828424c35cce1bb9df3def8fb53f45743b267506eed23" dependencies = [ "Inflector", "once_cell", @@ -6910,9 +6911,9 @@ dependencies = [ [[package]] name = "styled_jsx" -version = "0.76.0" +version = "0.78.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4f3904ed82f85537fb9041f8609d24fc4be4b9be9457db0de24303e0b1d50ab" +checksum = "c4e8a675bd16ac2421bcab98bb84ca728650dd02fabcda23ed966c0a8b91dc51" dependencies = [ "anyhow", "lightningcss", @@ -6946,9 +6947,9 @@ checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" [[package]] name = "swc" -version = "10.0.0" +version = "12.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8ade39563c1ad642548eb5f43cc1fab61053c382490423fc653cd87e1e60b06" +checksum = "8d14e0ef4aaab179796aa919b0a6ab7b06e298df0c34b017559d90f082f4deaf" dependencies = [ "anyhow", "base64 0.21.4", @@ -7025,9 +7026,9 @@ dependencies = [ [[package]] name = "swc_atoms" -version = "3.0.3" +version = "3.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec403702d532412d862e4a4ec0619022f05996a64876febe8ae5519146bdf0ce" +checksum = "31cf812d2f10fd40a9c11227fe0e2e09779113f6ae6f04bd396ac5da92b69c91" dependencies = [ "bytecheck 0.8.0", "hstr", @@ -7040,9 +7041,9 @@ dependencies = [ [[package]] name = "swc_bundler" -version = "7.0.0" +version = "8.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c88a91910cd8430f88f8987019cf3a96d92a5d5dded3e0ba8203e0379e4a2f6f" +checksum = "3ec9e5bf73554d2c72d73000c2f78dbb113a8af28690ad39602bb16c079784e0" dependencies = [ "anyhow", "crc", @@ -7086,9 +7087,9 @@ dependencies = [ [[package]] name = "swc_common" -version = "5.0.0" +version = "5.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a521e8120dc0401580864a643b5bffa035c29fc3fc41697c972743d4f008ed22" +checksum = "29e67f0a373efdcbc1faebbb9ed7eaf7bcd7bc407cdd8b0fdd9475337c4364ce" dependencies = [ "ahash 0.8.11", "anyhow", @@ -7120,9 +7121,9 @@ dependencies = [ [[package]] name = "swc_compiler_base" -version = "8.0.0" +version = "10.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bac05e842e05893583b4152485bf8d001540d3825e3eb33bad690776f60d0ba7" +checksum = "1abc72f614a5501588c6eafb7d915bb5253d5a5042fe576061a3cfea20044a6f" dependencies = [ "anyhow", "base64 0.21.4", @@ -7175,9 +7176,9 @@ dependencies = [ [[package]] name = "swc_core" -version = "10.5.0" +version = "12.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13d7454c4e08ac1590e37d465826a54ff9345c4e7e139f4eadf391c36fb27e1c" +checksum = "b9918b58a97d4a87da954892725dbf77db18586e8b210682aa92fee33176b7bc" dependencies = [ "binding_macros", "swc", @@ -7297,9 +7298,9 @@ dependencies = [ [[package]] name = "swc_css_prefixer" -version = "5.0.0" +version = "6.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c057841ee09b6dcc791e3a46b6f2c47df9fec2afd81546fe2d88e6326fe33162" +checksum = "d822d560c406cd0cb9d2ee36048e91026eb2a5294da7c3f51178be912d200f3f" dependencies = [ "once_cell", "preset_env_base", @@ -7342,9 +7343,9 @@ dependencies = [ [[package]] name = "swc_ecma_ast" -version = "5.0.2" +version = "5.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0f8476c5338a588dec42c3dc5eecb3192a517e88a74e1673c235ba4214167ba" +checksum = "f04d44a7edb591a66b9abc276ef306ab6d73d4ef189c1cb54423625ad236348f" dependencies = [ "bitflags 2.5.0", "bytecheck 0.8.0", @@ -7396,9 +7397,9 @@ dependencies = [ [[package]] name = "swc_ecma_compat_bugfixes" -version = "7.0.0" +version = "8.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "748636a889a7bf082ca4547fdb89176cdac40418427b47421a48db47b7443492" +checksum = "fe620fb6dd413faf9a1a68cba631ff70b3c037cebf218830c2d4810027054048" dependencies = [ "swc_atoms", "swc_common", @@ -7413,9 +7414,9 @@ dependencies = [ [[package]] name = "swc_ecma_compat_common" -version = "7.0.0" +version = "8.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "373e66d36d26f1b202955c7062a902f54ca5f69918253d98efdc7a3e6ecad45a" +checksum = "b09b7cc2c0383622b490dea05ae8c606b013f9ed970432c7f974c87125e7b7e3" dependencies = [ "swc_common", "swc_ecma_ast", @@ -7426,9 +7427,9 @@ dependencies = [ [[package]] name = "swc_ecma_compat_es2015" -version = "7.0.0" +version = "8.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47bf8a8f3348a810b865622fdc5f9198e432d0ab49c074f861229441dfcf3a22" +checksum = "94689adc1840a37508c1c9ccf15881d76547c48ae320333857cecb8ad12177fe" dependencies = [ "arrayvec 0.7.4", "indexmap 2.7.1", @@ -7453,9 +7454,9 @@ dependencies = [ [[package]] name = "swc_ecma_compat_es2016" -version = "7.0.0" +version = "8.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ddd488f29abb9faf192f15d907a0fdba9b01d502ea1eab1afe25e484ec6e4c9" +checksum = "15894156ad95321bf7b1328d21af43ee921f1f093bce71df951780f774d6681b" dependencies = [ "swc_atoms", "swc_common", @@ -7470,9 +7471,9 @@ dependencies = [ [[package]] name = "swc_ecma_compat_es2017" -version = "7.0.0" +version = "8.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "874ebcd6417b029ee719fbab9cb3c8b16f7d922a6bb45f07913292c101fa85d9" +checksum = "ac4d6cbe0f746d2d92910fb352cc3317afdf3aff94a92b330843c8e20553ce95" dependencies = [ "serde", "swc_atoms", @@ -7488,9 +7489,9 @@ dependencies = [ [[package]] name = "swc_ecma_compat_es2018" -version = "7.0.0" +version = "8.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f7a742b37dd913674db4e53e0d645d1ba606d413432adf17afd9575ffc69790" +checksum = "286f7a400623314a37870f2584bed5d7bd3375f7fc9d1d0338095112ad703192" dependencies = [ "serde", "swc_atoms", @@ -7507,9 +7508,9 @@ dependencies = [ [[package]] name = "swc_ecma_compat_es2019" -version = "7.0.0" +version = "8.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2e114e2ad0248529d9f211a6c8f411773b1468d9b17180829999f71ea5d853d" +checksum = "b03462016861062b09d812424ddce5a9c49994a71b59b5e02c995eee3d3c21bd" dependencies = [ "swc_atoms", "swc_common", @@ -7523,9 +7524,9 @@ dependencies = [ [[package]] name = "swc_ecma_compat_es2020" -version = "8.0.0" +version = "9.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb6cc14fac0ac8728259b913a6bd27d6e6a8b589004f94bbac29d0e1d51ab73e" +checksum = "aaef439cdf8084a563d7c4112defc8a798a455b63f05a764241b05e925dd1992" dependencies = [ "serde", "swc_atoms", @@ -7541,9 +7542,9 @@ dependencies = [ [[package]] name = "swc_ecma_compat_es2021" -version = "7.0.0" +version = "8.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c332af5dbcda1f6378e3248c542fbe54faff7e5a45d91eb11896e6e89232529c" +checksum = "8ec31cc178384c86ce7cf69a34524e131e1677062377a463e212412e9e9177e3" dependencies = [ "swc_atoms", "swc_common", @@ -7557,9 +7558,9 @@ dependencies = [ [[package]] name = "swc_ecma_compat_es2022" -version = "8.0.0" +version = "9.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8cac23712e95dc29f9cdd249b68c6b6c2da44dd7a6415bb201ee9a4c57cf41d" +checksum = "158c384a8b650a5866a4933903cbace1b2a6fb01b9518a0ef6d62a9a8aa2a211" dependencies = [ "swc_atoms", "swc_common", @@ -7576,9 +7577,9 @@ dependencies = [ [[package]] name = "swc_ecma_compat_es3" -version = "7.0.0" +version = "8.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e08d1848b9677ca3bda15d2f890aee0c7a096010d2dd27b6aac8fbeb4556e4a9" +checksum = "5d152ef39193d34fb775a5e22f24187bf341fb7869ff506e8fb0c3917891f3af" dependencies = [ "swc_common", "swc_ecma_ast", @@ -7591,9 +7592,9 @@ dependencies = [ [[package]] name = "swc_ecma_ext_transforms" -version = "7.0.0" +version = "8.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ebd8afc6cdb0b421cb52345991f7e20d254b459191197237b6a8d3002e9a42e" +checksum = "6ade9f4fed5cd85ecf79848b9f283a1c434edb246818ccd7f616baace621870d" dependencies = [ "phf", "swc_atoms", @@ -7605,9 +7606,9 @@ dependencies = [ [[package]] name = "swc_ecma_lints" -version = "7.0.1" +version = "8.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da44b5afe6c0e928963a465a158ed615f0eac690549e13233f29ade7c1769650" +checksum = "3de9148ac1b2c786bc81421dcf5955fb8ffa7bc5ac77c23731e6f2d75c04aadb" dependencies = [ "auto_impl", "dashmap 5.5.3", @@ -7647,9 +7648,9 @@ dependencies = [ [[package]] name = "swc_ecma_minifier" -version = "7.3.0" +version = "9.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c947fce8df9670f62632ab336d48aafdcab9e2d6e2ff489fc94f7fcb541daf8b" +checksum = "c4f6ff1fca2e025f3bd615d352b4f4e6045739f1e1dcaf52231b0e1a4628d2e0" dependencies = [ "arrayvec 0.7.4", "indexmap 2.7.1", @@ -7684,9 +7685,9 @@ dependencies = [ [[package]] name = "swc_ecma_parser" -version = "6.0.2" +version = "7.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b92d3a25349d7f612c38d940f09f9c19c7b7aa3bf4d22fbe31ea44fd5354de02" +checksum = "8cf8a7677aa667eb2a629625cc4a5947eefcab717ee0feee5aadb1a4bf9d5888" dependencies = [ "either", "new_debug_unreachable", @@ -7706,9 +7707,9 @@ dependencies = [ [[package]] name = "swc_ecma_preset_env" -version = "9.0.0" +version = "10.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f61f42ee34bce3d543285abb4731ba033d18258a89cf119268ed5ffd8e74e89f" +checksum = "67e6001e9927da64e972f45eeb510f27578268ade970877bb3e6e6df6aa89bb1" dependencies = [ "anyhow", "dashmap 5.5.3", @@ -7731,9 +7732,9 @@ dependencies = [ [[package]] name = "swc_ecma_quote_macros" -version = "6.0.0" +version = "7.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d098f0eca09f8c1a5a5b95c3db8416168e00b920fb9e02165177b9e12b38f395" +checksum = "cc4e722b4b4da4341d6d4ae67d329574282a6a0ece01a09de30dcbe4e049f862" dependencies = [ "anyhow", "proc-macro2", @@ -7761,9 +7762,9 @@ dependencies = [ [[package]] name = "swc_ecma_transforms" -version = "9.0.0" +version = "10.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06ee0a6cd6af77166b5c9e295c72140768abc408477ea98006eb60daf8d568aa" +checksum = "5091fda143655e9958183e6fa47d7feae1dc84384b5cff6a91d5e5a4c669887d" dependencies = [ "swc_atoms", "swc_common", @@ -7781,9 +7782,9 @@ dependencies = [ [[package]] name = "swc_ecma_transforms_base" -version = "7.1.1" +version = "8.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4596fe5bcb4ed0836c71e69fb4cbf0071bb832669ae57ba28aaa4b6a67b6ddfd" +checksum = "3c135c2def758a74bdaa2d2a77f68b495ac2965749772a942323571bf9845624" dependencies = [ "better_scoped_tls", "bitflags 2.5.0", @@ -7806,9 +7807,9 @@ dependencies = [ [[package]] name = "swc_ecma_transforms_classes" -version = "7.0.0" +version = "8.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "331bfc8add971c9ed71a2febfdd133d9f62cc36ed8f329f3d9602315a22fbeb5" +checksum = "f7fe69a90aad73147d1d3bfc7888cb44e9395f7650f8816a1d9185d3f71287e2" dependencies = [ "swc_atoms", "swc_common", @@ -7820,9 +7821,9 @@ dependencies = [ [[package]] name = "swc_ecma_transforms_compat" -version = "8.0.0" +version = "9.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d537411c909aca11ccf6e5ff5cdd4eb246958b4b6eb9ae16fb5ffd6d93291f3a" +checksum = "75a160bc8a2417aa8447cb65aa808546c03699fb9b5c2fa380ce3ea9dba9d024" dependencies = [ "arrayvec 0.7.4", "indexmap 2.7.1", @@ -7869,9 +7870,9 @@ dependencies = [ [[package]] name = "swc_ecma_transforms_module" -version = "8.0.0" +version = "9.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae1f1172c488c9fd224fa31b0c620cb37cfc124292d091cbae0fb4d2f403e415" +checksum = "47ec95ecdf34325371fb671c0a4ace238ef216c848cc79d20b7f8f87e442312d" dependencies = [ "Inflector", "anyhow", @@ -7896,9 +7897,9 @@ dependencies = [ [[package]] name = "swc_ecma_transforms_optimization" -version = "7.1.1" +version = "8.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "445aa8dc0b03a875fd14dd9afdfbd774b223b1e37916dae96dd8d79f45421422" +checksum = "89cce1fc8676e89c36bd86fa11820ccdd135346f34fabf0fc50d1f991c632dc8" dependencies = [ "dashmap 5.5.3", "indexmap 2.7.1", @@ -7921,9 +7922,9 @@ dependencies = [ [[package]] name = "swc_ecma_transforms_proposal" -version = "7.0.1" +version = "8.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b4e13ff44c34653923b6e5035bfb4d410b7976ca799dede0ac1665830587090" +checksum = "31eb5778754b4c0854ccfc5f5e3ca73098ed6782dd3cbc1d5862efe31ecd2a74" dependencies = [ "either", "rustc-hash 1.1.0", @@ -7941,15 +7942,16 @@ dependencies = [ [[package]] name = "swc_ecma_transforms_react" -version = "7.0.0" +version = "8.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aebcf8a522005fc12c79d34e3643b9ac143118a395ff7d48070751a1aafc2c3d" +checksum = "bbbf1f0c6ac5f221e744c98210eb46fc6d1c61304ca0ce81a335dea358d6fd37" dependencies = [ "base64 0.21.4", "dashmap 5.5.3", "indexmap 2.7.1", "once_cell", "rayon", + "rustc-hash 1.1.0", "serde", "sha1", "string_enum", @@ -7967,9 +7969,9 @@ dependencies = [ [[package]] name = "swc_ecma_transforms_testing" -version = "7.0.1" +version = "8.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6595f97e02012d9d284c34c6f328be674a8631502629c921f606da88b59b3743" +checksum = "862382be64386edfbb16bf6315e70c250f8fda68d350b73f4e39a6682268b76a" dependencies = [ "ansi_term", "anyhow", @@ -7994,10 +7996,11 @@ dependencies = [ [[package]] name = "swc_ecma_transforms_typescript" -version = "7.0.0" +version = "8.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ed09e052cf5392e3883e4fa6727346983650cd81b24dbba68e5e9dd129d75bb" +checksum = "9c1c385179f20177432618ee45a58a5d7ee40ebffbf6daa4a2d42293e43a68fd" dependencies = [ + "once_cell", "ryu-js", "serde", "swc_atoms", @@ -8011,9 +8014,9 @@ dependencies = [ [[package]] name = "swc_ecma_usage_analyzer" -version = "7.0.0" +version = "9.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15eb86aaa82d7ec4c1a6c3a8a824b1fdbbaace73c3ed81035a1fbbac49f8e0bd" +checksum = "289f228d757aa06792ef4bcef13877cbfb4a727cfff6f23be6f08a12a7454457" dependencies = [ "indexmap 2.7.1", "rustc-hash 1.1.0", @@ -8028,9 +8031,9 @@ dependencies = [ [[package]] name = "swc_ecma_utils" -version = "7.0.3" +version = "8.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f8f5bd06f238e7df2472dda5c9372bea1e56e169710260bf10de7979ef0a4bb" +checksum = "229ad0ad13418aa0162fea9e9ed6eb48232f6e6043df1568d5a90125f0c9fe6d" dependencies = [ "indexmap 2.7.1", "num_cpus", @@ -8065,9 +8068,9 @@ dependencies = [ [[package]] name = "swc_emotion" -version = "0.76.0" +version = "0.78.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d9e2d354e667f165c0e287102d85395f6030a41ec3d4ea1e847407d2ec19958" +checksum = "371fb66343f1da1bf11581d8a6ce62ec90181831f95bbb7e493eecf595879890" dependencies = [ "base64 0.22.1", "byteorder", @@ -8175,9 +8178,9 @@ dependencies = [ [[package]] name = "swc_parallel" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d22c97eeb6cad7e98dd246769b740e7f724fee6dc752190f14ad2b361cbf565b" +checksum = "e5f75f1094d69174ef628e3665fff0f81d58e9f568802e3c90d332c72b0b6026" dependencies = [ "chili", "once_cell", @@ -8238,9 +8241,9 @@ dependencies = [ [[package]] name = "swc_relay" -version = "0.46.1" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acce1cd9a9015e408b52baa63cabde116c10291abac5a82fab86f48dc31d47c6" +checksum = "6eeb9fa3e912d4af8b180d3f27c97ff335017b7fe71b646c0df42a3f50ea2589" dependencies = [ "once_cell", "regex", @@ -8289,9 +8292,9 @@ dependencies = [ [[package]] name = "swc_typescript" -version = "6.1.1" +version = "7.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fec37f682d079c9c6afa3a637a6ea387066830dd56b47bb217c7f3502c0f71e4" +checksum = "0a0eb6bb9e77d2d71e96b4b9c5bc0acc83e39c4fc7f05c93ff56ccf1e9aba2c4" dependencies = [ "petgraph", "rustc-hash 1.1.0", @@ -9107,7 +9110,7 @@ dependencies = [ "dashmap 6.1.0", "either", "erased-serde", - "event-listener 2.5.3", + "event-listener 5.4.0", "futures", "indexmap 2.7.1", "mopa", @@ -10017,6 +10020,12 @@ version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6af6ae20167a9ece4bcb41af5b80f8a1f1df981f6391189ce00fd257af04126a" +[[package]] +name = "typeid" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e13db2e0ccd5e14a544e8a246ba2312cd25223f616442d7f2cb0e3db614236e" + [[package]] name = "typenum" version = "1.16.0" diff --git a/Cargo.toml b/Cargo.toml index ee31dae0f8c43..c0f036838d63e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -91,21 +91,21 @@ turbopack-trace-utils = { path = "turbopack/crates/turbopack-trace-utils" } turbopack-wasm = { path = "turbopack/crates/turbopack-wasm" } # SWC crates -swc_core = { version = "10.5.0", features = [ +swc_core = { version = "12.0.0", features = [ "ecma_loader_lru", "ecma_loader_parking_lot", ] } testing = { version = "5.0.0" } # Keep consistent with preset_env_base through swc_core -browserslist-rs = { version = "0.16.0" } +browserslist-rs = { version = "0.17.0" } miette = { version = "5.10.0", features = ["fancy"] } mdxjs = "0.2.15" -modularize_imports = { version = "0.72.0" } -styled_components = { version = "0.100.1" } -styled_jsx = { version = "0.76.0" } -swc_emotion = { version = "0.76.0" } -swc_relay = { version = "0.46.1" } +modularize_imports = { version = "0.74.0" } +styled_components = { version = "0.102.0" } +styled_jsx = { version = "0.78.0" } +swc_emotion = { version = "0.78.0" } +swc_relay = { version = "0.48.0" } # General Deps chromiumoxide = { version = "0.5.4", features = [ @@ -140,6 +140,7 @@ dhat = { version = "0.3.2" } dialoguer = "0.10.3" dunce = "1.0.3" either = "1.9.0" +erased-serde = "0.4.5" futures = "0.3.26" futures-retry = "0.6.0" hashbrown = "0.14.5" @@ -183,13 +184,12 @@ reqwest = { version = "=0.11.17", default-features = false } rstest = "0.16.0" rustc-hash = "1.1.0" semver = "1.0.16" -serde = { version = "1.0.152", features = ["derive"] } -serde_json = "1.0.93" +serde = { version = "1.0.217", features = ["derive"] } +serde_json = "1.0.138" serde_bytes = "0.11.15" -serde_path_to_error = "0.1.9" -serde_qs = "0.11.0" -serde_with = "2.3.2" -serde_yaml = "0.9.17" +serde_path_to_error = "0.1.16" +serde_qs = "0.13.0" +serde_with = "3.12.0" shadow-rs = { version = "0.37.0", default-features = false, features = [ "tzdb", ] } @@ -224,3 +224,6 @@ wasmer = { git = "https://github.com/kdy1/wasmer", branch = "build-deps" } wasmer-cache = { git = "https://github.com/kdy1/wasmer", branch = "build-deps" } wasmer-compiler-cranelift = { git = "https://github.com/kdy1/wasmer", branch = "build-deps" } wasmer-wasix = { git = "https://github.com/kdy1/wasmer", branch = "build-deps" } + +# Remove this once https://github.com/wooorm/mdxjs-rs/pull/62 is merged and released +mdxjs = { git="https://github.com/kdy1/mdxjs-rs.git", branch="swc-core-11" } diff --git a/contributing/core/vscode-debugger.md b/contributing/core/vscode-debugger.md index 52c9033e7823b..22be0b556b33d 100644 --- a/contributing/core/vscode-debugger.md +++ b/contributing/core/vscode-debugger.md @@ -24,4 +24,4 @@ To see the changes you make to the Next.js codebase during development, you can When developing/debugging Next.js, you can set breakpoints anywhere in the `packages/next` source code that will stop the debugger at certain locations so you can examine the behavior. Read more about [breakpoints in the VS Code documentation](https://code.visualstudio.com/docs/nodejs/nodejs-debugging#_breakpoints). -To ensure that the original names are displayed in the "Variables" section, build the Next.js source code with `NEXT_SERVER_NO_MANGLE=1`. This is automatically applied when using `pnpm dev`. +To ensure that the original names are displayed in the "Variables" section, build the Next.js source code with `NEXT_SERVER_EVAL_SOURCE_MAPS=1`. This is automatically applied when using `pnpm dev`. diff --git a/crates/napi/src/lib.rs b/crates/napi/src/lib.rs index 0c208bd5c1af1..61a73404ae055 100644 --- a/crates/napi/src/lib.rs +++ b/crates/napi/src/lib.rs @@ -76,6 +76,9 @@ static ALLOC: dhat::Alloc = dhat::Alloc; #[napi::module_init] fn init() { + use tokio::runtime::Builder; + use turbo_tasks_malloc::TurboMalloc; + set_hook(Box::new(|panic_info| { util::log_internal_error_and_inform(&format!( "Panic: {}\nBacktrace: {:?}", @@ -83,6 +86,15 @@ fn init() { Backtrace::new() )); })); + let rt = Builder::new_multi_thread() + .enable_all() + .on_thread_stop(|| { + TurboMalloc::thread_stop(); + }) + .disable_lifo_slot() + .build() + .unwrap(); + create_custom_tokio_runtime(rt); } #[inline] diff --git a/crates/next-api/src/project.rs b/crates/next-api/src/project.rs index 49d899ae5c62a..c296969b652d5 100644 --- a/crates/next-api/src/project.rs +++ b/crates/next-api/src/project.rs @@ -27,6 +27,7 @@ use turbo_tasks::{ debug::ValueDebugFormat, fxindexmap, graph::{AdjacencyMap, GraphTraversal}, + mark_root, trace::TraceRawVcs, Completion, Completions, FxIndexMap, IntoTraitRef, NonLocalValue, OperationValue, OperationVc, ReadRef, ResolvedVc, State, TaskInput, TransientInstance, TryFlatJoinIterExt, Value, Vc, @@ -897,9 +898,9 @@ impl Project { pub async fn whole_app_module_graphs(self: ResolvedVc) -> Result> { async move { let module_graphs_op = whole_app_module_graph_operation(self); - let module_graphs_vc = module_graphs_op.resolve_strongly_consistent().await?; + let module_graphs_vc = module_graphs_op.connect().resolve().await?; let _ = module_graphs_op.take_issues_with_path().await?; - Ok(*module_graphs_vc) + Ok(module_graphs_vc) } .instrument(tracing::info_span!("module graph for app")) .await @@ -1605,6 +1606,7 @@ impl Project { async fn whole_app_module_graph_operation( project: ResolvedVc, ) -> Result> { + mark_root(); let base_single_module_graph = SingleModuleGraph::new_with_entries(project.get_all_entries()); let base_visited_modules = VisitedModules::from_graph(base_single_module_graph); diff --git a/crates/next-core/Cargo.toml b/crates/next-core/Cargo.toml index 3b1a2eae2bf96..1c35a9b4f4457 100644 --- a/crates/next-core/Cargo.toml +++ b/crates/next-core/Cargo.toml @@ -32,8 +32,8 @@ lazy_static = { workspace = true } thiserror = { workspace = true } tracing = { workspace = true } rustc-hash = { workspace = true } -react_remove_properties = "0.26.1" -remove_console = "0.27.1" +react_remove_properties = "0.28.0" +remove_console = "0.29.0" auto-hash-map = { workspace = true } diff --git a/crates/next-core/src/next_shared/transforms/next_edge_node_api_assert.rs b/crates/next-core/src/next_shared/transforms/next_edge_node_api_assert.rs index 13eaea081fb2d..657cf64efca70 100644 --- a/crates/next-core/src/next_shared/transforms/next_edge_node_api_assert.rs +++ b/crates/next-core/src/next_shared/transforms/next_edge_node_api_assert.rs @@ -46,6 +46,7 @@ impl CustomTransformer for NextEdgeNodeApiAssert { is_unresolved_ref_safe: false, unresolved_ctxt: SyntaxContext::empty().apply_mark(ctx.unresolved_mark), in_strict: false, + remaining_depth: 4, }, self.should_error_for_node_apis, self.is_production, diff --git a/crates/next-custom-transforms/Cargo.toml b/crates/next-custom-transforms/Cargo.toml index d9760a9ec1529..e43e10aa3c48b 100644 --- a/crates/next-custom-transforms/Cargo.toml +++ b/crates/next-custom-transforms/Cargo.toml @@ -60,9 +60,9 @@ swc_relay = { workspace = true } turbopack-ecmascript-plugins = { workspace = true, optional = true } turbo-rcstr = { workspace = true } -react_remove_properties = "0.26.1" -remove_console = "0.27.1" -preset_env_base = "1.0.0" +react_remove_properties = "0.28.0" +remove_console = "0.29.0" +preset_env_base = "2.0.0" [dev-dependencies] swc_core = { workspace = true, features = ["testing_transform"]} diff --git a/crates/next-custom-transforms/src/chain_transforms.rs b/crates/next-custom-transforms/src/chain_transforms.rs index 4abac10efaaf8..c596629ff09a0 100644 --- a/crates/next-custom-transforms/src/chain_transforms.rs +++ b/crates/next-custom-transforms/src/chain_transforms.rs @@ -170,7 +170,7 @@ where &file.name, &styled_jsx::visitor::Config { use_lightningcss: config.use_lightningcss, - browsers: target_browsers, + browsers: *target_browsers, }, &styled_jsx::visitor::NativeConfig { process_css: None }, )) diff --git a/crates/next-custom-transforms/src/transforms/page_static_info/collect_exported_const_visitor.rs b/crates/next-custom-transforms/src/transforms/page_static_info/collect_exported_const_visitor.rs index 1f49fe3625d03..7304f0b176f5d 100644 --- a/crates/next-custom-transforms/src/transforms/page_static_info/collect_exported_const_visitor.rs +++ b/crates/next-custom-transforms/src/transforms/page_static_info/collect_exported_const_visitor.rs @@ -37,6 +37,7 @@ impl CollectExportedConstVisitor { unresolved_ctxt: SyntaxContext::empty().apply_mark(Mark::new()), is_unresolved_ref_safe: false, in_strict: false, + remaining_depth: 4, }, } } @@ -61,7 +62,7 @@ impl Visit for CollectExportedConstVisitor { { let id = id.sym.as_ref(); if let Some(prop) = self.properties.get_mut(id) { - *prop = extract_value(&self.expr_ctx, init, id.to_string()); + *prop = extract_value(self.expr_ctx, init, id.to_string()); }; } } @@ -74,7 +75,7 @@ impl Visit for CollectExportedConstVisitor { } /// Coerece the actual value of the given ast node. -fn extract_value(ctx: &ExprCtx, init: &Expr, id: String) -> Option { +fn extract_value(ctx: ExprCtx, init: &Expr, id: String) -> Option { match init { init if init.is_undefined(ctx) => Some(Const::Value(Value::Null)), Expr::Ident(ident) => Some(Const::Unsupported(format!( diff --git a/crates/next-custom-transforms/src/transforms/react_server_components.rs b/crates/next-custom-transforms/src/transforms/react_server_components.rs index 2f846c41d32d2..3b1c0f7cb113e 100644 --- a/crates/next-custom-transforms/src/transforms/react_server_components.rs +++ b/crates/next-custom-transforms/src/transforms/react_server_components.rs @@ -277,8 +277,8 @@ fn report_error(app_dir: &Option, filepath: &str, error_kind: RSCErrorK // If importing "react-dom/server", we should show a different error. "react-dom/server" => "You're importing a component that imports react-dom/server. To fix it, render or return the content directly as a Server Component instead for perf and security.\nLearn more: https://nextjs.org/docs/app/building-your-application/rendering".to_string(), // If importing "next/router", we should tell them to use "next/navigation". - "next/router" => r#"You have a Server Component that imports next/router. Use next/navigation instead.\nLearn more: https://nextjs.org/docs/app/api-reference/functions/use-router"#.to_string(), - _ => format!(r#"You're importing a component that imports {source}. It only works in a Client Component but none of its parents are marked with "use client", so they're Server Components by default.\nLearn more: https://nextjs.org/docs/app/building-your-application/rendering\n\n"#) + "next/router" => "You have a Server Component that imports next/router. Use next/navigation instead.\nLearn more: https://nextjs.org/docs/app/api-reference/functions/use-router".to_string(), + _ => format!("You're importing a component that imports {source}. It only works in a Client Component but none of its parents are marked with \"use client\", so they're Server Components by default.\nLearn more: https://nextjs.org/docs/app/building-your-application/rendering") }; (msg, vec![span]) diff --git a/crates/next-custom-transforms/src/transforms/warn_for_edge_runtime.rs b/crates/next-custom-transforms/src/transforms/warn_for_edge_runtime.rs index f7cf3535020bf..d320e1910fcd1 100644 --- a/crates/next-custom-transforms/src/transforms/warn_for_edge_runtime.rs +++ b/crates/next-custom-transforms/src/transforms/warn_for_edge_runtime.rs @@ -234,14 +234,14 @@ Learn more: https://nextjs.org/docs/api-reference/edge-runtime", Expr::Member(member) => { if member.prop.is_ident_with("NEXT_RUNTIME") { if let Expr::Member(obj_member) = &*member.obj { - if obj_member.obj.is_global_ref_to(&self.ctx, "process") + if obj_member.obj.is_global_ref_to(self.ctx, "process") && obj_member.prop.is_ident_with("env") { self.guarded_runtime = true; } } } - if member.obj.is_global_ref_to(&self.ctx, "process") { + if member.obj.is_global_ref_to(self.ctx, "process") { if let MemberProp::Ident(prop) = &member.prop { self.guarded_process_props.push(prop.sym.clone()); } @@ -364,7 +364,7 @@ impl Visit for WarnForEdgeRuntime { } fn visit_member_expr(&mut self, n: &MemberExpr) { - if n.obj.is_global_ref_to(&self.ctx, "process") { + if n.obj.is_global_ref_to(self.ctx, "process") { if let MemberProp::Ident(prop) = &n.prop { self.warn_for_unsupported_process_api(n.span, prop); return; diff --git a/crates/next-custom-transforms/tests/errors/react-server-components/server-graph/client-only/output.stderr b/crates/next-custom-transforms/tests/errors/react-server-components/server-graph/client-only/output.stderr index 570aa9f9226ff..4109c7998c4b8 100644 --- a/crates/next-custom-transforms/tests/errors/react-server-components/server-graph/client-only/output.stderr +++ b/crates/next-custom-transforms/tests/errors/react-server-components/server-graph/client-only/output.stderr @@ -1,5 +1,5 @@ - x You're importing a component that imports client-only. It only works in a Client Component but none of its parents are marked with "use client", so they're Server Components by default.\nLearn - | more: https://nextjs.org/docs/app/building-your-application/rendering\n\n + x You're importing a component that imports client-only. It only works in a Client Component but none of its parents are marked with "use client", so they're Server Components by default. + | Learn more: https://nextjs.org/docs/app/building-your-application/rendering ,-[input.js:9:1] 8 | 9 | import 'client-only' diff --git a/crates/next-custom-transforms/tests/errors/react-server-components/server-graph/react-dom-server-client/output.stderr b/crates/next-custom-transforms/tests/errors/react-server-components/server-graph/react-dom-server-client/output.stderr index 1152d6d2e2d9f..07bcbe9cee375 100644 --- a/crates/next-custom-transforms/tests/errors/react-server-components/server-graph/react-dom-server-client/output.stderr +++ b/crates/next-custom-transforms/tests/errors/react-server-components/server-graph/react-dom-server-client/output.stderr @@ -6,7 +6,7 @@ : ^^^^^^^^^^^^^^^^^^^^^^^^^ `---- x You're importing a component that imports react-dom/client. It only works in a Client Component but none of its parents are marked with "use client", so they're Server Components by default. - | \nLearn more: https://nextjs.org/docs/app/building-your-application/rendering\n\n + | Learn more: https://nextjs.org/docs/app/building-your-application/rendering ,-[input.js:11:1] 10 | 11 | import 'react-dom/client' diff --git a/crates/next-custom-transforms/tests/fixture.rs b/crates/next-custom-transforms/tests/fixture.rs index 4dddeb54befa6..50ad5b5773839 100644 --- a/crates/next-custom-transforms/tests/fixture.rs +++ b/crates/next-custom-transforms/tests/fixture.rs @@ -2,6 +2,7 @@ use std::{ env::current_dir, iter::FromIterator, path::{Path, PathBuf}, + sync::Arc, }; use next_custom_transforms::transforms::{ @@ -363,8 +364,8 @@ fn next_ssg_fixture(input: PathBuf) { next: false.into(), runtime: None, import_source: Some("".into()), - pragma: Some("__jsx".into()), - pragma_frag: Some("__jsxFrag".into()), + pragma: Some(Arc::new("__jsx".into())), + pragma_frag: Some(Arc::new("__jsxFrag".into())), throw_if_namespace: false.into(), development: false.into(), refresh: Default::default(), @@ -777,8 +778,8 @@ fn run_stip_page_exports_test(input: &Path, output: &Path, mode: ExportFilter) { next: false.into(), runtime: None, import_source: Some("".into()), - pragma: Some("__jsx".into()), - pragma_frag: Some("__jsxFrag".into()), + pragma: Some(Arc::new("__jsx".into())), + pragma_frag: Some(Arc::new("__jsxFrag".into())), throw_if_namespace: false.into(), development: false.into(), ..Default::default() @@ -854,6 +855,7 @@ fn test_edge_assert(input: PathBuf) { is_unresolved_ref_safe: false, unresolved_ctxt: SyntaxContext::empty().apply_mark(unresolved_mark), in_strict: false, + remaining_depth: 4, }, true, true, diff --git a/docs/01-app/03-building-your-application/02-data-fetching/03-server-actions-and-mutations.mdx b/docs/01-app/03-building-your-application/02-data-fetching/03-server-actions-and-mutations.mdx index d0f374e90f4de..0d047ba817b26 100644 --- a/docs/01-app/03-building-your-application/02-data-fetching/03-server-actions-and-mutations.mdx +++ b/docs/01-app/03-building-your-application/02-data-fetching/03-server-actions-and-mutations.mdx @@ -979,7 +979,7 @@ However, for this to happen, the captured variables are sent to the client and b When self-hosting your Next.js application across multiple servers, each server instance may end up with a different encryption key, leading to potential inconsistencies. -To mitigate this, you can overwrite the encryption key using the `process.env.NEXT_SERVER_ACTIONS_ENCRYPTION_KEY` environment variable. Specifying this variable ensures that your encryption keys are persistent across builds, and all server instances use the same key. +To mitigate this, you can overwrite the encryption key using the `process.env.NEXT_SERVER_ACTIONS_ENCRYPTION_KEY` environment variable. Specifying this variable ensures that your encryption keys are persistent across builds, and all server instances use the same key. This variable **must** be AES-GCM encrypted. This is an advanced use case where consistent encryption behavior across multiple deployments is critical for your application. You should consider standard security practices such key rotation and signing. diff --git a/docs/01-app/03-building-your-application/07-configuring/03-environment-variables.mdx b/docs/01-app/03-building-your-application/07-configuring/03-environment-variables.mdx index 82426438a978a..a9a1d976834bc 100644 --- a/docs/01-app/03-building-your-application/07-configuring/03-environment-variables.mdx +++ b/docs/01-app/03-building-your-application/07-configuring/03-environment-variables.mdx @@ -17,6 +17,8 @@ Next.js comes with built-in support for environment variables, which allows you - [Use `.env` to load environment variables](#loading-environment-variables) - [Bundle environment variables for the browser by prefixing with `NEXT_PUBLIC_`](#bundling-environment-variables-for-the-browser) +> **Warning:** The default `create-next-app` template ensures all `.env` files are added to your `.gitignore`. You almost never want to commit these files to your repository. + ## Loading Environment Variables Next.js has built-in support for loading environment variables from `.env*` files into `process.env`. @@ -232,15 +234,7 @@ This allows you to use a singular Docker image that can be promoted through mult **Good to know:** - You can run code on server startup using the [`register` function](/docs/app/building-your-application/optimizing/instrumentation). -- We do not recommend using the [runtimeConfig](/docs/pages/api-reference/config/next-config-js/runtime-configuration) option, as this does not work with the standalone output mode. Instead, we recommend [incrementally adopting](/docs/app/building-your-application/upgrading/app-router-migration) the App Router. - -## Default Environment Variables - -Typically, only `.env*` file is needed. However, sometimes you might want to add some defaults for the `development` (`next dev`) or `production` (`next start`) environment. - -Next.js allows you to set defaults in `.env` (all environments), `.env.development` (development environment), and `.env.production` (production environment). - -> **Good to know**: `.env`, `.env.development`, and `.env.production` files should be included in your repository as they define defaults. All `.env` files are excluded in `.gitignore` by default, allowing you to opt-into committing these values to your repository. +- We do not recommend using the [`runtimeConfig`](/docs/pages/api-reference/config/next-config-js/runtime-configuration) option, as this does not work with the standalone output mode. Instead, we recommend [incrementally adopting](/docs/app/building-your-application/upgrading/app-router-migration) the App Router if you need this feature. ## Environment Variables on Vercel diff --git a/docs/01-app/03-building-your-application/11-upgrading/05-app-router-migration.mdx b/docs/01-app/03-building-your-application/11-upgrading/05-app-router-migration.mdx index b0d3b8a800907..217b60068934c 100644 --- a/docs/01-app/03-building-your-application/11-upgrading/05-app-router-migration.mdx +++ b/docs/01-app/03-building-your-application/11-upgrading/05-app-router-migration.mdx @@ -923,6 +923,12 @@ export default function RootLayout({ children }) { Learn more about [styling with Tailwind CSS](/docs/app/building-your-application/styling/tailwind-css) +## Using App Router together with Pages Router + +When navigating between routes served by the different Next.js routers, there will be a hard navigation. Automatic link prefetching with `next/link` will not prefetch across routers. + +Instead, you can [optimize navigations](https://vercel.com/guides/optimizing-hard-navigations) between App Router and Pages Router to retain the prefetched and fast page transitions. [Learn more](https://vercel.com/guides/optimizing-hard-navigations). + ## Codemods Next.js provides Codemod transformations to help upgrade your codebase when a feature is deprecated. See [Codemods](/docs/app/building-your-application/upgrading/codemods) for more information. diff --git a/jest.config.js b/jest.config.js index cf47e8b8b9276..c9d2ebf13cf82 100644 --- a/jest.config.js +++ b/jest.config.js @@ -36,9 +36,14 @@ if (enableTestReport) { customJestConfig.reporters = ['default'] } - const outputDirectory = process.env.TURBOPACK - ? '/turbopack-test-junit-report' - : '/test-junit-report' + let outputDirectory + if (process.env.TURBOPACK) { + outputDirectory = '/turbopack-test-junit-report' + } else if (process.env.NEXT_RSPACK) { + outputDirectory = '/rspack-test-junit-report' + } else { + outputDirectory = '/test-junit-report' + } customJestConfig.reporters.push([ 'jest-junit', diff --git a/lerna.json b/lerna.json index 7721268c31648..4ddb4fedf9f58 100644 --- a/lerna.json +++ b/lerna.json @@ -16,5 +16,5 @@ "registry": "https://registry.npmjs.org/" } }, - "version": "15.2.0-canary.28" + "version": "15.2.0-canary.36" } diff --git a/package.json b/package.json index b19ff019abdc9..96eb85d67d347 100644 --- a/package.json +++ b/package.json @@ -64,10 +64,12 @@ "unpack-next": "node scripts/unpack-next.cjs", "swc-build-native": "node scripts/build-native.cjs", "swc-build-wasm": "node scripts/build-wasm.cjs", + "build-turbopack-cli": "cargo build -p turbopack-cli --release", "sweep": "node scripts/sweep.cjs", "check-error-codes": "node packages/next/check-error-codes.js", "storybook": "turbo run storybook", - "build-storybook": "turbo run build-storybook" + "build-storybook": "turbo run build-storybook", + "test-storybook": "turbo run test-storybook" }, "devDependencies": { "@actions/core": "1.10.1", @@ -213,16 +215,16 @@ "pretty-ms": "7.0.0", "random-seed": "0.3.0", "react": "19.0.0", - "react-builtin": "npm:react@19.1.0-canary-9eabb373-20250124", + "react-builtin": "npm:react@19.1.0-canary-37906d4d-20250127", "react-dom": "19.0.0", - "react-dom-builtin": "npm:react-dom@19.1.0-canary-9eabb373-20250124", - "react-dom-experimental-builtin": "npm:react-dom@0.0.0-experimental-9eabb373-20250124", - "react-experimental-builtin": "npm:react@0.0.0-experimental-9eabb373-20250124", - "react-is-builtin": "npm:react-is@19.1.0-canary-9eabb373-20250124", - "react-server-dom-turbopack": "19.1.0-canary-9eabb373-20250124", - "react-server-dom-turbopack-experimental": "npm:react-server-dom-turbopack@0.0.0-experimental-9eabb373-20250124", - "react-server-dom-webpack": "19.1.0-canary-9eabb373-20250124", - "react-server-dom-webpack-experimental": "npm:react-server-dom-webpack@0.0.0-experimental-9eabb373-20250124", + "react-dom-builtin": "npm:react-dom@19.1.0-canary-37906d4d-20250127", + "react-dom-experimental-builtin": "npm:react-dom@0.0.0-experimental-37906d4d-20250127", + "react-experimental-builtin": "npm:react@0.0.0-experimental-37906d4d-20250127", + "react-is-builtin": "npm:react-is@19.1.0-canary-37906d4d-20250127", + "react-server-dom-turbopack": "19.1.0-canary-37906d4d-20250127", + "react-server-dom-turbopack-experimental": "npm:react-server-dom-turbopack@0.0.0-experimental-37906d4d-20250127", + "react-server-dom-webpack": "19.1.0-canary-37906d4d-20250127", + "react-server-dom-webpack-experimental": "npm:react-server-dom-webpack@0.0.0-experimental-37906d4d-20250127", "react-ssr-prepass": "1.0.8", "react-virtualized": "9.22.3", "relay-compiler": "13.0.2", @@ -232,8 +234,8 @@ "resolve-from": "5.0.0", "sass": "1.54.0", "satori": "0.12.1", - "scheduler-builtin": "npm:scheduler@0.26.0-canary-9eabb373-20250124", - "scheduler-experimental-builtin": "npm:scheduler@0.0.0-experimental-9eabb373-20250124", + "scheduler-builtin": "npm:scheduler@0.26.0-canary-37906d4d-20250127", + "scheduler-experimental-builtin": "npm:scheduler@0.0.0-experimental-37906d4d-20250127", "seedrandom": "3.0.5", "semver": "7.3.7", "shell-quote": "1.7.3", @@ -274,14 +276,14 @@ "@types/react": "19.0.8", "@types/react-dom": "19.0.3", "jest-snapshot": "30.0.0-alpha.6", - "react": "19.1.0-canary-9eabb373-20250124", - "react-dom": "19.1.0-canary-9eabb373-20250124", - "react-is": "19.1.0-canary-9eabb373-20250124", - "scheduler": "0.26.0-canary-9eabb373-20250124" + "react": "19.1.0-canary-37906d4d-20250127", + "react-dom": "19.1.0-canary-37906d4d-20250127", + "react-is": "19.1.0-canary-37906d4d-20250127", + "scheduler": "0.26.0-canary-37906d4d-20250127" }, "patchedDependencies": { "webpack-sources@3.2.3": "patches/webpack-sources@3.2.3.patch", - "@storybook/react@8.4.7": "patches/@storybook__react@8.4.7.patch" + "@storybook/react@8.5.2": "patches/@storybook__react@8.5.2.patch" } } } diff --git a/packages/create-next-app/index.ts b/packages/create-next-app/index.ts index 42c6b7d63c467..d621f52e3f748 100644 --- a/packages/create-next-app/index.ts +++ b/packages/create-next-app/index.ts @@ -227,7 +227,7 @@ async function run(): Promise { if (!example) { const defaults: typeof preferences = { typescript: true, - eslint: true, + eslint: false, tailwind: true, app: true, srcDir: false, diff --git a/packages/create-next-app/package.json b/packages/create-next-app/package.json index 9a0618f049105..107056fa97c88 100644 --- a/packages/create-next-app/package.json +++ b/packages/create-next-app/package.json @@ -1,6 +1,6 @@ { "name": "create-next-app", - "version": "15.2.0-canary.28", + "version": "15.2.0-canary.36", "keywords": [ "react", "next", diff --git a/packages/create-next-app/templates/app-tw-empty/js/app/globals.css b/packages/create-next-app/templates/app-tw-empty/js/app/globals.css index b5c61c956711f..f1d8c73cdcf9e 100644 --- a/packages/create-next-app/templates/app-tw-empty/js/app/globals.css +++ b/packages/create-next-app/templates/app-tw-empty/js/app/globals.css @@ -1,3 +1 @@ -@tailwind base; -@tailwind components; -@tailwind utilities; +@import "tailwindcss"; diff --git a/packages/create-next-app/templates/app-tw-empty/js/postcss.config.mjs b/packages/create-next-app/templates/app-tw-empty/js/postcss.config.mjs index 1a69fd2a450af..c7bcb4b1ee14c 100644 --- a/packages/create-next-app/templates/app-tw-empty/js/postcss.config.mjs +++ b/packages/create-next-app/templates/app-tw-empty/js/postcss.config.mjs @@ -1,8 +1,5 @@ -/** @type {import('postcss-load-config').Config} */ const config = { - plugins: { - tailwindcss: {}, - }, + plugins: ["@tailwindcss/postcss"], }; export default config; diff --git a/packages/create-next-app/templates/app-tw-empty/js/tailwind.config.mjs b/packages/create-next-app/templates/app-tw-empty/js/tailwind.config.mjs deleted file mode 100644 index 47fda2d4d16ac..0000000000000 --- a/packages/create-next-app/templates/app-tw-empty/js/tailwind.config.mjs +++ /dev/null @@ -1,6 +0,0 @@ -/** @type {import('tailwindcss').Config} */ -export default { - content: ["./app/**/*.{js,ts,jsx,tsx,mdx}"], - theme: {}, - plugins: [], -}; diff --git a/packages/create-next-app/templates/app-tw-empty/ts/app/globals.css b/packages/create-next-app/templates/app-tw-empty/ts/app/globals.css index b5c61c956711f..f1d8c73cdcf9e 100644 --- a/packages/create-next-app/templates/app-tw-empty/ts/app/globals.css +++ b/packages/create-next-app/templates/app-tw-empty/ts/app/globals.css @@ -1,3 +1 @@ -@tailwind base; -@tailwind components; -@tailwind utilities; +@import "tailwindcss"; diff --git a/packages/create-next-app/templates/app-tw-empty/ts/postcss.config.mjs b/packages/create-next-app/templates/app-tw-empty/ts/postcss.config.mjs index 1a69fd2a450af..c7bcb4b1ee14c 100644 --- a/packages/create-next-app/templates/app-tw-empty/ts/postcss.config.mjs +++ b/packages/create-next-app/templates/app-tw-empty/ts/postcss.config.mjs @@ -1,8 +1,5 @@ -/** @type {import('postcss-load-config').Config} */ const config = { - plugins: { - tailwindcss: {}, - }, + plugins: ["@tailwindcss/postcss"], }; export default config; diff --git a/packages/create-next-app/templates/app-tw-empty/ts/tailwind.config.ts b/packages/create-next-app/templates/app-tw-empty/ts/tailwind.config.ts deleted file mode 100644 index a52c869bdf999..0000000000000 --- a/packages/create-next-app/templates/app-tw-empty/ts/tailwind.config.ts +++ /dev/null @@ -1,7 +0,0 @@ -import type { Config } from "tailwindcss"; - -export default { - content: ["./app/**/*.{js,ts,jsx,tsx,mdx}"], - theme: {}, - plugins: [], -} satisfies Config; diff --git a/packages/create-next-app/templates/app-tw/js/app/globals.css b/packages/create-next-app/templates/app-tw/js/app/globals.css index 6b717ad346d3d..947a04834f220 100644 --- a/packages/create-next-app/templates/app-tw/js/app/globals.css +++ b/packages/create-next-app/templates/app-tw/js/app/globals.css @@ -1,6 +1,9 @@ -@tailwind base; -@tailwind components; -@tailwind utilities; +@import "tailwindcss"; + +@theme { + --font-sans: var(--font-geist-sans); + --font-mono: var(--font-geist-mono); +} :root { --background: #ffffff; diff --git a/packages/create-next-app/templates/app-tw/js/postcss.config.mjs b/packages/create-next-app/templates/app-tw/js/postcss.config.mjs index 1a69fd2a450af..c7bcb4b1ee14c 100644 --- a/packages/create-next-app/templates/app-tw/js/postcss.config.mjs +++ b/packages/create-next-app/templates/app-tw/js/postcss.config.mjs @@ -1,8 +1,5 @@ -/** @type {import('postcss-load-config').Config} */ const config = { - plugins: { - tailwindcss: {}, - }, + plugins: ["@tailwindcss/postcss"], }; export default config; diff --git a/packages/create-next-app/templates/app-tw/js/tailwind.config.mjs b/packages/create-next-app/templates/app-tw/js/tailwind.config.mjs deleted file mode 100644 index b522c25eec086..0000000000000 --- a/packages/create-next-app/templates/app-tw/js/tailwind.config.mjs +++ /dev/null @@ -1,17 +0,0 @@ -/** @type {import('tailwindcss').Config} */ -export default { - content: [ - "./pages/**/*.{js,ts,jsx,tsx,mdx}", - "./components/**/*.{js,ts,jsx,tsx,mdx}", - "./app/**/*.{js,ts,jsx,tsx,mdx}", - ], - theme: { - extend: { - colors: { - background: "var(--background)", - foreground: "var(--foreground)", - }, - }, - }, - plugins: [], -}; diff --git a/packages/create-next-app/templates/app-tw/ts/app/globals.css b/packages/create-next-app/templates/app-tw/ts/app/globals.css index 6b717ad346d3d..947a04834f220 100644 --- a/packages/create-next-app/templates/app-tw/ts/app/globals.css +++ b/packages/create-next-app/templates/app-tw/ts/app/globals.css @@ -1,6 +1,9 @@ -@tailwind base; -@tailwind components; -@tailwind utilities; +@import "tailwindcss"; + +@theme { + --font-sans: var(--font-geist-sans); + --font-mono: var(--font-geist-mono); +} :root { --background: #ffffff; diff --git a/packages/create-next-app/templates/app-tw/ts/postcss.config.mjs b/packages/create-next-app/templates/app-tw/ts/postcss.config.mjs index 1a69fd2a450af..c7bcb4b1ee14c 100644 --- a/packages/create-next-app/templates/app-tw/ts/postcss.config.mjs +++ b/packages/create-next-app/templates/app-tw/ts/postcss.config.mjs @@ -1,8 +1,5 @@ -/** @type {import('postcss-load-config').Config} */ const config = { - plugins: { - tailwindcss: {}, - }, + plugins: ["@tailwindcss/postcss"], }; export default config; diff --git a/packages/create-next-app/templates/app-tw/ts/tailwind.config.ts b/packages/create-next-app/templates/app-tw/ts/tailwind.config.ts deleted file mode 100644 index 1362b8826a5aa..0000000000000 --- a/packages/create-next-app/templates/app-tw/ts/tailwind.config.ts +++ /dev/null @@ -1,18 +0,0 @@ -import type { Config } from "tailwindcss"; - -export default { - content: [ - "./pages/**/*.{js,ts,jsx,tsx,mdx}", - "./components/**/*.{js,ts,jsx,tsx,mdx}", - "./app/**/*.{js,ts,jsx,tsx,mdx}", - ], - theme: { - extend: { - colors: { - background: "var(--background)", - foreground: "var(--foreground)", - }, - }, - }, - plugins: [], -} satisfies Config; diff --git a/packages/create-next-app/templates/default-tw-empty/js/postcss.config.mjs b/packages/create-next-app/templates/default-tw-empty/js/postcss.config.mjs index 1a69fd2a450af..c7bcb4b1ee14c 100644 --- a/packages/create-next-app/templates/default-tw-empty/js/postcss.config.mjs +++ b/packages/create-next-app/templates/default-tw-empty/js/postcss.config.mjs @@ -1,8 +1,5 @@ -/** @type {import('postcss-load-config').Config} */ const config = { - plugins: { - tailwindcss: {}, - }, + plugins: ["@tailwindcss/postcss"], }; export default config; diff --git a/packages/create-next-app/templates/default-tw-empty/js/styles/globals.css b/packages/create-next-app/templates/default-tw-empty/js/styles/globals.css index b5c61c956711f..f1d8c73cdcf9e 100644 --- a/packages/create-next-app/templates/default-tw-empty/js/styles/globals.css +++ b/packages/create-next-app/templates/default-tw-empty/js/styles/globals.css @@ -1,3 +1 @@ -@tailwind base; -@tailwind components; -@tailwind utilities; +@import "tailwindcss"; diff --git a/packages/create-next-app/templates/default-tw-empty/js/tailwind.config.mjs b/packages/create-next-app/templates/default-tw-empty/js/tailwind.config.mjs deleted file mode 100644 index 1eed62eb42aa3..0000000000000 --- a/packages/create-next-app/templates/default-tw-empty/js/tailwind.config.mjs +++ /dev/null @@ -1,6 +0,0 @@ -/** @type {import('tailwindcss').Config} */ -export default { - content: ["./pages/**/*.{js,jsx,mdx}"], - theme: {}, - plugins: [], -}; diff --git a/packages/create-next-app/templates/default-tw-empty/ts/postcss.config.mjs b/packages/create-next-app/templates/default-tw-empty/ts/postcss.config.mjs index 1a69fd2a450af..c7bcb4b1ee14c 100644 --- a/packages/create-next-app/templates/default-tw-empty/ts/postcss.config.mjs +++ b/packages/create-next-app/templates/default-tw-empty/ts/postcss.config.mjs @@ -1,8 +1,5 @@ -/** @type {import('postcss-load-config').Config} */ const config = { - plugins: { - tailwindcss: {}, - }, + plugins: ["@tailwindcss/postcss"], }; export default config; diff --git a/packages/create-next-app/templates/default-tw-empty/ts/styles/globals.css b/packages/create-next-app/templates/default-tw-empty/ts/styles/globals.css index b5c61c956711f..f1d8c73cdcf9e 100644 --- a/packages/create-next-app/templates/default-tw-empty/ts/styles/globals.css +++ b/packages/create-next-app/templates/default-tw-empty/ts/styles/globals.css @@ -1,3 +1 @@ -@tailwind base; -@tailwind components; -@tailwind utilities; +@import "tailwindcss"; diff --git a/packages/create-next-app/templates/default-tw-empty/ts/tailwind.config.ts b/packages/create-next-app/templates/default-tw-empty/ts/tailwind.config.ts deleted file mode 100644 index ad025df087097..0000000000000 --- a/packages/create-next-app/templates/default-tw-empty/ts/tailwind.config.ts +++ /dev/null @@ -1,7 +0,0 @@ -import type { Config } from "tailwindcss"; - -export default { - content: ["./pages/**/*.{ts,tsx,mdx}"], - theme: {}, - plugins: [], -} satisfies Config; diff --git a/packages/create-next-app/templates/default-tw/js/postcss.config.mjs b/packages/create-next-app/templates/default-tw/js/postcss.config.mjs index 1a69fd2a450af..c7bcb4b1ee14c 100644 --- a/packages/create-next-app/templates/default-tw/js/postcss.config.mjs +++ b/packages/create-next-app/templates/default-tw/js/postcss.config.mjs @@ -1,8 +1,5 @@ -/** @type {import('postcss-load-config').Config} */ const config = { - plugins: { - tailwindcss: {}, - }, + plugins: ["@tailwindcss/postcss"], }; export default config; diff --git a/packages/create-next-app/templates/default-tw/js/styles/globals.css b/packages/create-next-app/templates/default-tw/js/styles/globals.css index 6b717ad346d3d..947a04834f220 100644 --- a/packages/create-next-app/templates/default-tw/js/styles/globals.css +++ b/packages/create-next-app/templates/default-tw/js/styles/globals.css @@ -1,6 +1,9 @@ -@tailwind base; -@tailwind components; -@tailwind utilities; +@import "tailwindcss"; + +@theme { + --font-sans: var(--font-geist-sans); + --font-mono: var(--font-geist-mono); +} :root { --background: #ffffff; diff --git a/packages/create-next-app/templates/default-tw/js/tailwind.config.mjs b/packages/create-next-app/templates/default-tw/js/tailwind.config.mjs deleted file mode 100644 index b522c25eec086..0000000000000 --- a/packages/create-next-app/templates/default-tw/js/tailwind.config.mjs +++ /dev/null @@ -1,17 +0,0 @@ -/** @type {import('tailwindcss').Config} */ -export default { - content: [ - "./pages/**/*.{js,ts,jsx,tsx,mdx}", - "./components/**/*.{js,ts,jsx,tsx,mdx}", - "./app/**/*.{js,ts,jsx,tsx,mdx}", - ], - theme: { - extend: { - colors: { - background: "var(--background)", - foreground: "var(--foreground)", - }, - }, - }, - plugins: [], -}; diff --git a/packages/create-next-app/templates/default-tw/ts/postcss.config.mjs b/packages/create-next-app/templates/default-tw/ts/postcss.config.mjs index 1a69fd2a450af..c7bcb4b1ee14c 100644 --- a/packages/create-next-app/templates/default-tw/ts/postcss.config.mjs +++ b/packages/create-next-app/templates/default-tw/ts/postcss.config.mjs @@ -1,8 +1,5 @@ -/** @type {import('postcss-load-config').Config} */ const config = { - plugins: { - tailwindcss: {}, - }, + plugins: ["@tailwindcss/postcss"], }; export default config; diff --git a/packages/create-next-app/templates/default-tw/ts/styles/globals.css b/packages/create-next-app/templates/default-tw/ts/styles/globals.css index 6b717ad346d3d..947a04834f220 100644 --- a/packages/create-next-app/templates/default-tw/ts/styles/globals.css +++ b/packages/create-next-app/templates/default-tw/ts/styles/globals.css @@ -1,6 +1,9 @@ -@tailwind base; -@tailwind components; -@tailwind utilities; +@import "tailwindcss"; + +@theme { + --font-sans: var(--font-geist-sans); + --font-mono: var(--font-geist-mono); +} :root { --background: #ffffff; diff --git a/packages/create-next-app/templates/default-tw/ts/tailwind.config.ts b/packages/create-next-app/templates/default-tw/ts/tailwind.config.ts deleted file mode 100644 index 1362b8826a5aa..0000000000000 --- a/packages/create-next-app/templates/default-tw/ts/tailwind.config.ts +++ /dev/null @@ -1,18 +0,0 @@ -import type { Config } from "tailwindcss"; - -export default { - content: [ - "./pages/**/*.{js,ts,jsx,tsx,mdx}", - "./components/**/*.{js,ts,jsx,tsx,mdx}", - "./app/**/*.{js,ts,jsx,tsx,mdx}", - ], - theme: { - extend: { - colors: { - background: "var(--background)", - foreground: "var(--foreground)", - }, - }, - }, - plugins: [], -} satisfies Config; diff --git a/packages/create-next-app/templates/index.ts b/packages/create-next-app/templates/index.ts index 34880b4b115d0..707cb5d55f091 100644 --- a/packages/create-next-app/templates/index.ts +++ b/packages/create-next-app/templates/index.ts @@ -55,11 +55,7 @@ export const installTemplate = async ({ const templatePath = path.join(__dirname, template, mode); const copySource = ["**"]; if (!eslint) copySource.push("!eslint.config.mjs"); - if (!tailwind) - copySource.push( - mode == "ts" ? "tailwind.config.ts" : "!tailwind.config.mjs", - "!postcss.config.mjs", - ); + if (!tailwind) copySource.push("!postcss.config.mjs"); await copy(copySource, root, { parents: true, @@ -164,20 +160,6 @@ export const installTemplate = async ({ isAppTemplate ? "src/app/page" : "src/pages/index", ), ); - - if (tailwind) { - const tailwindConfigFile = path.join( - root, - mode === "ts" ? "tailwind.config.ts" : "tailwind.config.mjs", - ); - await fs.writeFile( - tailwindConfigFile, - (await fs.readFile(tailwindConfigFile, "utf8")).replace( - /\.\/(\w+)\/\*\*\/\*\.\{js,ts,jsx,tsx,mdx\}/g, - "./src/$1/**/*.{js,ts,jsx,tsx,mdx}", - ), - ); - } } } @@ -223,8 +205,8 @@ export const installTemplate = async ({ if (tailwind) { packageJson.devDependencies = { ...packageJson.devDependencies, - postcss: "^8", - tailwindcss: "^3.4.1", + "@tailwindcss/postcss": "^4", + tailwindcss: "^4", }; } diff --git a/packages/eslint-config-next/package.json b/packages/eslint-config-next/package.json index 54986193d844b..1ccc5e940e493 100644 --- a/packages/eslint-config-next/package.json +++ b/packages/eslint-config-next/package.json @@ -1,6 +1,6 @@ { "name": "eslint-config-next", - "version": "15.2.0-canary.28", + "version": "15.2.0-canary.36", "description": "ESLint configuration used by Next.js.", "main": "index.js", "license": "MIT", @@ -10,7 +10,7 @@ }, "homepage": "https://nextjs.org/docs/app/api-reference/config/eslint", "dependencies": { - "@next/eslint-plugin-next": "15.2.0-canary.28", + "@next/eslint-plugin-next": "15.2.0-canary.36", "@rushstack/eslint-patch": "^1.10.3", "@typescript-eslint/eslint-plugin": "^5.4.2 || ^6.0.0 || ^7.0.0 || ^8.0.0", "@typescript-eslint/parser": "^5.4.2 || ^6.0.0 || ^7.0.0 || ^8.0.0", diff --git a/packages/eslint-config-next/parser.js b/packages/eslint-config-next/parser.js index 9e9fd22cfc073..b0366825e3542 100644 --- a/packages/eslint-config-next/parser.js +++ b/packages/eslint-config-next/parser.js @@ -2,8 +2,13 @@ const { parse, parseForESLint, } = require('next/dist/compiled/babel/eslint-parser') +const { version } = require('./package.json') module.exports = { parse, parseForESLint, + meta: { + name: 'eslint-config-next/parser', + version, + }, } diff --git a/packages/eslint-plugin-next/package.json b/packages/eslint-plugin-next/package.json index 3b0907b2a9da1..d7dc687579d3e 100644 --- a/packages/eslint-plugin-next/package.json +++ b/packages/eslint-plugin-next/package.json @@ -1,6 +1,6 @@ { "name": "@next/eslint-plugin-next", - "version": "15.2.0-canary.28", + "version": "15.2.0-canary.36", "description": "ESLint plugin for Next.js.", "main": "dist/index.js", "license": "MIT", diff --git a/packages/font/package.json b/packages/font/package.json index da39a76534ec4..cc9b100038607 100644 --- a/packages/font/package.json +++ b/packages/font/package.json @@ -1,7 +1,7 @@ { "name": "@next/font", "private": true, - "version": "15.2.0-canary.28", + "version": "15.2.0-canary.36", "repository": { "url": "vercel/next.js", "directory": "packages/font" diff --git a/packages/next-bundle-analyzer/package.json b/packages/next-bundle-analyzer/package.json index eb4fb9884cf23..a10d37d5ddb9c 100644 --- a/packages/next-bundle-analyzer/package.json +++ b/packages/next-bundle-analyzer/package.json @@ -1,6 +1,6 @@ { "name": "@next/bundle-analyzer", - "version": "15.2.0-canary.28", + "version": "15.2.0-canary.36", "main": "index.js", "types": "index.d.ts", "license": "MIT", diff --git a/packages/next-codemod/package.json b/packages/next-codemod/package.json index bd17686ed4a3b..da2adbcfe0ef8 100644 --- a/packages/next-codemod/package.json +++ b/packages/next-codemod/package.json @@ -1,6 +1,6 @@ { "name": "@next/codemod", - "version": "15.2.0-canary.28", + "version": "15.2.0-canary.36", "license": "MIT", "repository": { "type": "git", diff --git a/packages/next-env/package.json b/packages/next-env/package.json index a77ad261dda3b..aaacd56016773 100644 --- a/packages/next-env/package.json +++ b/packages/next-env/package.json @@ -1,6 +1,6 @@ { "name": "@next/env", - "version": "15.2.0-canary.28", + "version": "15.2.0-canary.36", "keywords": [ "react", "next", diff --git a/packages/next-mdx/package.json b/packages/next-mdx/package.json index 10087953703fc..8ba1770750dcc 100644 --- a/packages/next-mdx/package.json +++ b/packages/next-mdx/package.json @@ -1,6 +1,6 @@ { "name": "@next/mdx", - "version": "15.2.0-canary.28", + "version": "15.2.0-canary.36", "main": "index.js", "license": "MIT", "repository": { diff --git a/packages/next-plugin-storybook/package.json b/packages/next-plugin-storybook/package.json index 34bd38e017051..63adef86ee734 100644 --- a/packages/next-plugin-storybook/package.json +++ b/packages/next-plugin-storybook/package.json @@ -1,6 +1,6 @@ { "name": "@next/plugin-storybook", - "version": "15.2.0-canary.28", + "version": "15.2.0-canary.36", "repository": { "url": "vercel/next.js", "directory": "packages/next-plugin-storybook" diff --git a/packages/next-polyfill-module/package.json b/packages/next-polyfill-module/package.json index 14259aec5e0cb..388d6d39f7826 100644 --- a/packages/next-polyfill-module/package.json +++ b/packages/next-polyfill-module/package.json @@ -1,6 +1,6 @@ { "name": "@next/polyfill-module", - "version": "15.2.0-canary.28", + "version": "15.2.0-canary.36", "description": "A standard library polyfill for ES Modules supporting browsers (Edge 16+, Firefox 60+, Chrome 61+, Safari 10.1+)", "main": "dist/polyfill-module.js", "license": "MIT", diff --git a/packages/next-polyfill-nomodule/package.json b/packages/next-polyfill-nomodule/package.json index 024829daa4398..9f5cf86899f69 100644 --- a/packages/next-polyfill-nomodule/package.json +++ b/packages/next-polyfill-nomodule/package.json @@ -1,6 +1,6 @@ { "name": "@next/polyfill-nomodule", - "version": "15.2.0-canary.28", + "version": "15.2.0-canary.36", "description": "A polyfill for non-dead, nomodule browsers.", "main": "dist/polyfill-nomodule.js", "license": "MIT", diff --git a/packages/next-swc/package.json b/packages/next-swc/package.json index c4ae1c0bcf025..ac8c87257188b 100644 --- a/packages/next-swc/package.json +++ b/packages/next-swc/package.json @@ -1,6 +1,6 @@ { "name": "@next/swc", - "version": "15.2.0-canary.28", + "version": "15.2.0-canary.36", "private": true, "scripts": { "clean": "node ../../scripts/rm.mjs native", diff --git a/packages/next/.storybook/main.ts b/packages/next/.storybook/main.ts index 0d7b170179eb0..f702b638ee0fd 100644 --- a/packages/next/.storybook/main.ts +++ b/packages/next/.storybook/main.ts @@ -17,10 +17,9 @@ const config: StorybookConfig = { ], addons: [ getAbsolutePath('@storybook/addon-webpack5-compiler-swc'), - getAbsolutePath('@storybook/addon-onboarding'), getAbsolutePath('@storybook/addon-essentials'), - getAbsolutePath('@chromatic-com/storybook'), getAbsolutePath('@storybook/addon-interactions'), + getAbsolutePath('@storybook/addon-a11y'), ], framework: { name: getAbsolutePath('@storybook/react-webpack5'), diff --git a/packages/next/.storybook/preview.ts b/packages/next/.storybook/preview.ts index 34e5d7547fb3e..49fd2a1cc4623 100644 --- a/packages/next/.storybook/preview.ts +++ b/packages/next/.storybook/preview.ts @@ -2,6 +2,9 @@ import type { Preview } from '@storybook/react' const preview: Preview = { parameters: { + a11y: { + element: 'nextjs-portal', + }, controls: { matchers: { color: /(background|color)$/i, @@ -19,6 +22,12 @@ const preview: Preview = { default: 'backdrop', }, }, + globals: { + a11y: { + // Optional flag to prevent the automatic check + manual: true, + }, + }, } export default preview diff --git a/packages/next/.storybook/test-runner.ts b/packages/next/.storybook/test-runner.ts new file mode 100644 index 0000000000000..2b488b1125eab --- /dev/null +++ b/packages/next/.storybook/test-runner.ts @@ -0,0 +1,22 @@ +import type { TestRunnerConfig } from '@storybook/test-runner' +import { injectAxe, checkA11y } from 'axe-playwright' + +/* + * See https://storybook.js.org/docs/writing-tests/test-runner#test-hook-api + * to learn more about the test-runner hooks API. + */ +const config: TestRunnerConfig = { + async preVisit(page) { + await injectAxe(page) + }, + async postVisit(page) { + await checkA11y(page, 'nextjs-portal', { + detailedReport: true, + detailedReportOptions: { + html: true, + }, + }) + }, +} + +export default config diff --git a/packages/next/next_runtime.config.js b/packages/next/next-runtime.webpack-config.js similarity index 90% rename from packages/next/next_runtime.config.js rename to packages/next/next-runtime.webpack-config.js index 03490803301c3..11194efdf09df 100644 --- a/packages/next/next_runtime.config.js +++ b/packages/next/next-runtime.webpack-config.js @@ -1,9 +1,11 @@ -const rspack = require('@rspack/core') +const webpack = require('webpack') const path = require('path') +const TerserPlugin = require('terser-webpack-plugin') const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer') +const EvalSourceMapDevToolPlugin = require('./webpack-plugins/eval-source-map-dev-tool-plugin') const DevToolsIgnoreListPlugin = require('./webpack-plugins/devtools-ignore-list-plugin') -function shouldIgnorePath() { +function shouldIgnorePath(modulePath) { // For consumers, everything will be considered 3rd party dependency if they use // the bundles we produce here. // In other words, this is all library code and should therefore be ignored. @@ -128,7 +130,16 @@ const bundleTypes = { module.exports = ({ dev, turbo, bundleType, experimental }) => { const externalHandler = ({ context, request, getResolve }, callback) => { ;(async () => { - if (request.match(/next[/\\]dist[/\\]compiled[/\\](babel|webpack)/)) { + if ( + request.match( + /next[/\\]dist[/\\]compiled[/\\](babel|webpack|source-map|semver|jest-worker|stacktrace-parser|@ampproject\/toolbox-optimizer)/ + ) + ) { + callback(null, 'commonjs ' + request) + return + } + + if (request.match(/(server\/image-optimizer|experimental\/testmode)/)) { callback(null, 'commonjs ' + request) return } @@ -167,22 +178,37 @@ module.exports = ({ dev, turbo, bundleType, experimental }) => { }.runtime.${dev ? 'dev' : 'prod'}.js`, libraryTarget: 'commonjs2', }, - devtool: 'source-map', + devtool: process.env.NEXT_SERVER_EVAL_SOURCE_MAPS + ? // We'll use a fork in plugins + false + : 'source-map', optimization: { moduleIds: 'named', minimize: true, concatenateModules: true, minimizer: [ - new rspack.SwcJsMinimizerRspackPlugin({ - minimizerOptions: { - mangle: dev || process.env.NEXT_SERVER_NO_MANGLE ? false : true, + new TerserPlugin({ + minify: TerserPlugin.swcMinify, + terserOptions: { + compress: { + dead_code: true, + // Zero means no limit. + passes: 0, + }, + format: { + preamble: '', + }, + mangle: + dev && !process.env.NEXT_SERVER_EVAL_SOURCE_MAPS ? false : true, }, }), ], }, plugins: [ - new DevToolsIgnoreListPlugin({ shouldIgnorePath }), - new rspack.DefinePlugin({ + process.env.NEXT_SERVER_EVAL_SOURCE_MAPS + ? new EvalSourceMapDevToolPlugin({ shouldIgnorePath }) + : new DevToolsIgnoreListPlugin({ shouldIgnorePath }), + new webpack.DefinePlugin({ 'typeof window': JSON.stringify('undefined'), 'process.env.NEXT_MINIMAL': JSON.stringify('true'), 'this.serverOptions.experimentalTestProxy': JSON.stringify(false), diff --git a/packages/next/package.json b/packages/next/package.json index 3c3216129126e..d1797857a1ece 100644 --- a/packages/next/package.json +++ b/packages/next/package.json @@ -1,6 +1,6 @@ { "name": "next", - "version": "15.2.0-canary.28", + "version": "15.2.0-canary.36", "description": "The React Framework", "main": "./dist/server/next.js", "license": "MIT", @@ -80,7 +80,7 @@ "next": "./dist/bin/next" }, "scripts": { - "dev": "cross-env NEXT_SERVER_NO_MANGLE=1 taskr", + "dev": "cross-env NEXT_SERVER_EVAL_SOURCE_MAPS=1 taskr", "release": "taskr release", "build": "pnpm release", "prepublishOnly": "cd ../../ && turbo run build", @@ -88,18 +88,19 @@ "typescript": "tsec --noEmit", "ncc-compiled": "taskr ncc", "storybook": "storybook dev -p 6006", - "build-storybook": "storybook build" + "build-storybook": "storybook build", + "test-storybook": "test-storybook" }, "taskr": { "requires": [ - "./taskfile-rspack.js", + "./taskfile-webpack.js", "./taskfile-ncc.js", "./taskfile-swc.js", "./taskfile-watch.js" ] }, "dependencies": { - "@next/env": "15.2.0-canary.28", + "@next/env": "15.2.0-canary.36", "@swc/counter": "0.1.3", "@swc/helpers": "0.5.15", "busboy": "1.6.0", @@ -155,7 +156,6 @@ "@babel/traverse": "7.22.5", "@babel/types": "7.22.5", "@capsizecss/metrics": "3.4.0", - "@chromatic-com/storybook": "^3.2.2", "@edge-runtime/cookies": "6.0.0", "@edge-runtime/ponyfill": "4.0.0", "@edge-runtime/primitives": "6.0.0", @@ -164,22 +164,22 @@ "@jest/types": "29.5.0", "@mswjs/interceptors": "0.23.0", "@napi-rs/triples": "1.2.0", - "@next/font": "15.2.0-canary.28", - "@next/polyfill-module": "15.2.0-canary.28", - "@next/polyfill-nomodule": "15.2.0-canary.28", - "@next/react-refresh-utils": "15.2.0-canary.28", - "@next/swc": "15.2.0-canary.28", + "@next/font": "15.2.0-canary.36", + "@next/polyfill-module": "15.2.0-canary.36", + "@next/polyfill-nomodule": "15.2.0-canary.36", + "@next/react-refresh-utils": "15.2.0-canary.36", + "@next/swc": "15.2.0-canary.36", "@opentelemetry/api": "1.6.0", "@playwright/test": "1.41.2", - "@rspack/core": "1.2.2", - "@storybook/addon-essentials": "^8.4.7", - "@storybook/addon-interactions": "^8.4.7", - "@storybook/addon-onboarding": "^8.4.7", + "@storybook/addon-a11y": "8.5.2", + "@storybook/addon-essentials": "8.5.2", + "@storybook/addon-interactions": "8.5.2", "@storybook/addon-webpack5-compiler-swc": "^1.0.5", - "@storybook/blocks": "^8.4.7", - "@storybook/react": "^8.4.7", - "@storybook/react-webpack5": "^8.4.7", - "@storybook/test": "^8.4.7", + "@storybook/blocks": "8.5.2", + "@storybook/react": "8.5.2", + "@storybook/react-webpack5": "8.5.2", + "@storybook/test": "8.5.2", + "@storybook/test-runner": "0.21.0", "@swc/core": "1.9.3", "@swc/types": "0.1.7", "@taskr/clear": "1.1.0", @@ -228,6 +228,7 @@ "assert": "2.0.0", "async-retry": "1.2.3", "async-sema": "3.0.0", + "axe-playwright": "2.0.3", "babel-plugin-react-compiler": "19.0.0-beta-e552027-20250112", "babel-plugin-transform-define": "2.0.0", "babel-plugin-transform-react-remove-prop-types": "0.4.24", @@ -318,7 +319,7 @@ "source-map-loader": "5.0.0", "source-map08": "npm:source-map@0.8.0-beta.0", "stacktrace-parser": "0.1.10", - "storybook": "^8.4.7", + "storybook": "8.5.2", "stream-browserify": "3.0.0", "stream-http": "3.1.1", "strict-event-emitter": "0.5.0", diff --git a/packages/next/src/build/build-context.ts b/packages/next/src/build/build-context.ts index f041eee208fad..81310824f1a83 100644 --- a/packages/next/src/build/build-context.ts +++ b/packages/next/src/build/build-context.ts @@ -53,6 +53,7 @@ export const NextBuildContext: Partial<{ pluginState: Record // core fields dir: string + distDir: string buildId: string encryptionKey: string config: NextConfigComplete @@ -68,6 +69,7 @@ export const NextBuildContext: Partial<{ afterFiles: Rewrite[] beforeFiles: Rewrite[] } + hasRewrites: boolean originalRedirects: Redirect[] loadedEnvFiles: LoadedEnvFiles previewProps: __ApiPreviewProps diff --git a/packages/next/src/build/index.ts b/packages/next/src/build/index.ts index e5299fc7bfefe..ef7e013c1276e 100644 --- a/packages/next/src/build/index.ts +++ b/packages/next/src/build/index.ts @@ -18,7 +18,6 @@ import { defaultConfig } from '../server/config-shared' import devalue from 'next/dist/compiled/devalue' import findUp from 'next/dist/compiled/find-up' import { nanoid } from 'next/dist/compiled/nanoid/index.cjs' -import { Sema } from 'next/dist/compiled/async-sema' import path from 'path' import { STATIC_STATUS_PAGE_GET_INITIAL_PROPS_ERROR, @@ -50,7 +49,6 @@ import type { import { nonNullable } from '../lib/non-nullable' import { recursiveDelete } from '../lib/recursive-delete' import { verifyPartytownSetup } from '../lib/verify-partytown-setup' -import { validateTurboNextConfig } from '../lib/turbopack-warning' import { BUILD_ID_FILE, BUILD_MANIFEST, @@ -144,12 +142,7 @@ import type { NextError } from '../lib/is-error' import { isEdgeRuntime } from '../lib/is-edge-runtime' import { recursiveCopy } from '../lib/recursive-copy' import { recursiveReadDir } from '../lib/recursive-readdir' -import { - loadBindings, - lockfilePatchPromise, - teardownTraceSubscriber, - createDefineEnv, -} from './swc' +import { lockfilePatchPromise, teardownTraceSubscriber } from './swc' import { getNamedRouteRegex } from '../shared/lib/router/utils/route-regex' import { getFilesInDir } from '../lib/get-files-in-dir' import { eventSwcPlugins } from '../telemetry/events/swc-plugins' @@ -186,9 +179,7 @@ import { import { getStartServerInfo, logStartInfo } from '../server/lib/app-info-log' import type { NextEnabledDirectories } from '../server/base-server' import { hasCustomExportOutput } from '../export/utils' -import { TurbopackManifestLoader } from '../shared/lib/turbopack/manifest-loader' import { buildCustomRoute } from '../lib/build-custom-route' -import { createProgress } from './progress' import { traceMemoryUsage } from '../lib/memory/trace' import { generateEncryptionKeyBase64 } from '../server/app-render/encryption-utils-server' import type { DeepReadonly } from '../shared/lib/deep-readonly' @@ -207,19 +198,8 @@ import { import { InvariantError } from '../shared/lib/invariant-error' import { HTML_LIMITED_BOT_UA_RE_STRING } from '../shared/lib/router/utils/is-bot' import type { UseCacheTrackerKey } from './webpack/plugins/telemetry-plugin/use-cache-tracker-utils' -import { - handleEntrypoints, - handlePagesErrorRoute, - handleRouteType, -} from './handle-entrypoints' -import type { Entrypoints } from './swc/types' -import { - formatIssue, - getTurbopackJsConfig, - isPersistentCachingEnabled, - isRelevantWarning, - type EntryIssuesMap, -} from '../shared/lib/turbopack/utils' + +import { turbopackBuild } from './turbopack-build' type Fallback = null | boolean | string @@ -777,8 +757,6 @@ async function getBuildId( .traceAsyncFn(() => generateBuildId(config.generateBuildId, nanoid)) } -const IS_TURBOPACK_BUILD = process.env.TURBOPACK && process.env.TURBOPACK_BUILD - export default async function build( dir: string, reactProductionProfiling = false, @@ -839,6 +817,7 @@ export default async function build( config.distDir = '.next' } const distDir = path.join(dir, config.distDir) + NextBuildContext.distDir = distDir setGlobal('phase', PHASE_PRODUCTION_BUILD) setGlobal('distDir', distDir) @@ -861,7 +840,7 @@ export default async function build( ...rewrites.fallback, ] const hasRewrites = combinedRewrites.length > 0 - + NextBuildContext.hasRewrites = hasRewrites NextBuildContext.originalRewrites = config._originalRewrites NextBuildContext.originalRedirects = config._originalRedirects @@ -1145,7 +1124,7 @@ export default async function build( } // Turbopack already handles conflicting app and page routes. - if (!IS_TURBOPACK_BUILD) { + if (!turboNextBuild) { const numConflictingAppPaths = conflictingAppPagePaths.length if (mappedAppPages && numConflictingAppPaths > 0) { Log.error( @@ -1362,274 +1341,6 @@ export default async function build( PAGES_MANIFEST ) - async function turbopackBuild(): Promise<{ - duration: number - buildTraceContext: undefined - shutdownPromise: Promise - }> { - if (!IS_TURBOPACK_BUILD) { - throw new Error("next build doesn't support turbopack yet") - } - - await validateTurboNextConfig({ - dir, - isDev: false, - }) - - const startTime = process.hrtime() - const bindings = await loadBindings(config?.experimental?.useWasmBinary) - const dev = false - - // const supportedBrowsers = await getSupportedBrowsers(dir, dev) - const supportedBrowsers = [ - 'last 1 Chrome versions, last 1 Firefox versions, last 1 Safari versions, last 1 Edge versions', - ] - - const project = await bindings.turbo.createProject( - { - projectPath: dir, - rootPath: - config.experimental?.turbo?.root || - config.outputFileTracingRoot || - dir, - distDir, - nextConfig: config, - jsConfig: await getTurbopackJsConfig(dir, config), - watch: { - enable: false, - }, - dev, - env: process.env as Record, - defineEnv: createDefineEnv({ - isTurbopack: true, - clientRouterFilters, - config, - dev, - distDir, - fetchCacheKeyPrefix: config.experimental.fetchCacheKeyPrefix, - hasRewrites, - // Implemented separately in Turbopack, doesn't have to be passed here. - middlewareMatchers: undefined, - }), - buildId: NextBuildContext.buildId!, - encryptionKey: NextBuildContext.encryptionKey!, - previewProps: NextBuildContext.previewProps!, - browserslistQuery: supportedBrowsers.join(', '), - }, - { - persistentCaching: isPersistentCachingEnabled(config), - memoryLimit: config.experimental.turbo?.memoryLimit, - } - ) - - await fs.mkdir(path.join(distDir, 'server'), { recursive: true }) - await fs.mkdir(path.join(distDir, 'static', buildId), { - recursive: true, - }) - await fs.writeFile( - path.join(distDir, 'package.json'), - JSON.stringify( - { - type: 'commonjs', - }, - null, - 2 - ) - ) - - // eslint-disable-next-line @typescript-eslint/no-unused-vars - const entrypointsSubscription = project.entrypointsSubscribe() - const currentEntrypoints: Entrypoints = { - global: { - app: undefined, - document: undefined, - error: undefined, - - middleware: undefined, - instrumentation: undefined, - }, - - app: new Map(), - page: new Map(), - } - - const currentEntryIssues: EntryIssuesMap = new Map() - - const manifestLoader = new TurbopackManifestLoader({ - buildId, - distDir, - encryptionKey, - }) - - const entrypointsResult = await entrypointsSubscription.next() - if (entrypointsResult.done) { - throw new Error('Turbopack did not return any entrypoints') - } - entrypointsSubscription.return?.().catch(() => {}) - - const entrypoints = entrypointsResult.value - - const topLevelErrors: { - message: string - }[] = [] - for (const issue of entrypoints.issues) { - topLevelErrors.push({ - message: formatIssue(issue), - }) - } - - if (topLevelErrors.length > 0) { - throw new Error( - `Turbopack build failed with ${ - topLevelErrors.length - } issues:\n${topLevelErrors.map((e) => e.message).join('\n')}` - ) - } - - await handleEntrypoints({ - entrypoints, - currentEntrypoints, - currentEntryIssues, - manifestLoader, - productionRewrites: customRoutes.rewrites, - logErrors: false, - }) - - const progress = createProgress( - currentEntrypoints.page.size + currentEntrypoints.app.size + 1, - 'Building' - ) - const promises: Promise[] = [] - - // Concurrency will start at INITIAL_CONCURRENCY and - // slowly ramp up to CONCURRENCY by increasing the - // concurrency by 1 every time a task is completed. - const INITIAL_CONCURRENCY = 5 - const CONCURRENCY = 10 - - const sema = new Sema(INITIAL_CONCURRENCY) - let remainingRampup = CONCURRENCY - INITIAL_CONCURRENCY - const enqueue = (fn: () => Promise) => { - promises.push( - (async () => { - await sema.acquire() - try { - await fn() - } finally { - sema.release() - if (remainingRampup > 0) { - remainingRampup-- - sema.release() - } - progress.run() - } - })() - ) - } - - if (!appDirOnly) { - for (const [page, route] of currentEntrypoints.page) { - enqueue(() => - handleRouteType({ - page, - route, - currentEntryIssues, - entrypoints: currentEntrypoints, - manifestLoader, - productionRewrites: customRoutes.rewrites, - logErrors: false, - }) - ) - } - } - - for (const [page, route] of currentEntrypoints.app) { - enqueue(() => - handleRouteType({ - page, - route, - currentEntryIssues, - entrypoints: currentEntrypoints, - manifestLoader, - productionRewrites: customRoutes.rewrites, - logErrors: false, - }) - ) - } - - enqueue(() => - handlePagesErrorRoute({ - currentEntryIssues, - entrypoints: currentEntrypoints, - manifestLoader, - productionRewrites: customRoutes.rewrites, - logErrors: false, - }) - ) - await Promise.all(promises) - - await manifestLoader.writeManifests({ - devRewrites: undefined, - productionRewrites: customRoutes.rewrites, - entrypoints: currentEntrypoints, - }) - - const errors: { - page: string - message: string - }[] = [] - const warnings: { - page: string - message: string - }[] = [] - for (const [page, entryIssues] of currentEntryIssues) { - for (const issue of entryIssues.values()) { - if (issue.severity !== 'warning') { - errors.push({ - page, - message: formatIssue(issue), - }) - } else { - if (isRelevantWarning(issue)) { - warnings.push({ - page, - message: formatIssue(issue), - }) - } - } - } - } - - const shutdownPromise = project.shutdown() - - if (warnings.length > 0) { - Log.warn( - `Turbopack build collected ${warnings.length} warnings:\n${warnings - .map((e) => { - return 'Page: ' + e.page + '\n' + e.message - }) - .join('\n')}` - ) - } - - if (errors.length > 0) { - throw new Error( - `Turbopack build failed with ${errors.length} errors:\n${errors - .map((e) => { - return 'Page: ' + e.page + '\n' + e.message - }) - .join('\n')}` - ) - } - - const time = process.hrtime(startTime) - return { - duration: time[0] + time[1] / 1e9, - buildTraceContext: undefined, - shutdownPromise, - } - } - let buildTraceContext: undefined | BuildTraceContext let buildTracesPromise: Promise | undefined = undefined @@ -1678,7 +1389,7 @@ export default async function build( duration: compilerDuration, shutdownPromise: p, ...rest - } = await turbopackBuild() + } = await turbopackBuild(true) shutdownPromise = p traceMemoryUsage('Finished build', nextBuildSpan) diff --git a/packages/next/src/build/turbopack-build/impl.ts b/packages/next/src/build/turbopack-build/impl.ts new file mode 100644 index 0000000000000..84ca19db10ddd --- /dev/null +++ b/packages/next/src/build/turbopack-build/impl.ts @@ -0,0 +1,334 @@ +import path from 'path' +import { validateTurboNextConfig } from '../../lib/turbopack-warning' +import { + formatIssue, + getTurbopackJsConfig, + isPersistentCachingEnabled, + isRelevantWarning, + type EntryIssuesMap, +} from '../../shared/lib/turbopack/utils' +import { NextBuildContext } from '../build-context' +import { createDefineEnv, loadBindings } from '../swc' +import { Sema } from 'next/dist/compiled/async-sema' +import { + handleEntrypoints, + handlePagesErrorRoute, + handleRouteType, +} from '../handle-entrypoints' +import type { Entrypoints } from '../swc/types' +import { TurbopackManifestLoader } from '../../shared/lib/turbopack/manifest-loader' +import { createProgress } from '../progress' +import * as Log from '../output/log' +import { promises as fs } from 'fs' +import { PHASE_PRODUCTION_BUILD } from '../../shared/lib/constants' +import loadConfig from '../../server/config' +import { hasCustomExportOutput } from '../../export/utils' +import { Telemetry } from '../../telemetry/storage' +import { setGlobal } from '../../trace' + +const IS_TURBOPACK_BUILD = process.env.TURBOPACK && process.env.TURBOPACK_BUILD + +export async function turbopackBuild(): Promise<{ + duration: number + buildTraceContext: undefined + shutdownPromise: Promise +}> { + if (!IS_TURBOPACK_BUILD) { + throw new Error("next build doesn't support turbopack yet") + } + + await validateTurboNextConfig({ + dir: NextBuildContext.dir!, + isDev: false, + }) + + const config = NextBuildContext.config! + const dir = NextBuildContext.dir! + const distDir = NextBuildContext.distDir! + const buildId = NextBuildContext.buildId! + const encryptionKey = NextBuildContext.encryptionKey! + const previewProps = NextBuildContext.previewProps! + const hasRewrites = NextBuildContext.hasRewrites! + const rewrites = NextBuildContext.rewrites! + const appDirOnly = NextBuildContext.appDirOnly! + + const startTime = process.hrtime() + const bindings = await loadBindings(config?.experimental?.useWasmBinary) + const dev = false + + // const supportedBrowsers = await getSupportedBrowsers(dir, dev) + const supportedBrowsers = [ + 'last 1 Chrome versions, last 1 Firefox versions, last 1 Safari versions, last 1 Edge versions', + ] + + const project = await bindings.turbo.createProject( + { + projectPath: dir, + rootPath: + config.experimental?.turbo?.root || config.outputFileTracingRoot || dir, + distDir, + nextConfig: config, + jsConfig: await getTurbopackJsConfig(dir, config), + watch: { + enable: false, + }, + dev, + env: process.env as Record, + defineEnv: createDefineEnv({ + isTurbopack: true, + clientRouterFilters: NextBuildContext.clientRouterFilters!, + config, + dev, + distDir, + fetchCacheKeyPrefix: config.experimental.fetchCacheKeyPrefix, + hasRewrites, + // Implemented separately in Turbopack, doesn't have to be passed here. + middlewareMatchers: undefined, + }), + buildId, + encryptionKey, + previewProps, + browserslistQuery: supportedBrowsers.join(', '), + }, + { + persistentCaching: isPersistentCachingEnabled(config), + memoryLimit: config.experimental.turbo?.memoryLimit, + } + ) + + await fs.mkdir(path.join(distDir, 'server'), { recursive: true }) + await fs.mkdir(path.join(distDir, 'static', buildId), { + recursive: true, + }) + await fs.writeFile( + path.join(distDir, 'package.json'), + JSON.stringify( + { + type: 'commonjs', + }, + null, + 2 + ) + ) + + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const entrypointsSubscription = project.entrypointsSubscribe() + const currentEntrypoints: Entrypoints = { + global: { + app: undefined, + document: undefined, + error: undefined, + + middleware: undefined, + instrumentation: undefined, + }, + + app: new Map(), + page: new Map(), + } + + const currentEntryIssues: EntryIssuesMap = new Map() + + const manifestLoader = new TurbopackManifestLoader({ + buildId, + distDir, + encryptionKey, + }) + + const entrypointsResult = await entrypointsSubscription.next() + if (entrypointsResult.done) { + throw new Error('Turbopack did not return any entrypoints') + } + entrypointsSubscription.return?.().catch(() => {}) + + const entrypoints = entrypointsResult.value + + const topLevelErrors: { + message: string + }[] = [] + for (const issue of entrypoints.issues) { + topLevelErrors.push({ + message: formatIssue(issue), + }) + } + + if (topLevelErrors.length > 0) { + throw new Error( + `Turbopack build failed with ${ + topLevelErrors.length + } issues:\n${topLevelErrors.map((e) => e.message).join('\n')}` + ) + } + + await handleEntrypoints({ + entrypoints, + currentEntrypoints, + currentEntryIssues, + manifestLoader, + productionRewrites: rewrites, + logErrors: false, + }) + + const progress = createProgress( + currentEntrypoints.page.size + currentEntrypoints.app.size + 1, + 'Building' + ) + const promises: Promise[] = [] + + // Concurrency will start at INITIAL_CONCURRENCY and + // slowly ramp up to CONCURRENCY by increasing the + // concurrency by 1 every time a task is completed. + const INITIAL_CONCURRENCY = 5 + const CONCURRENCY = 10 + + const sema = new Sema(INITIAL_CONCURRENCY) + let remainingRampup = CONCURRENCY - INITIAL_CONCURRENCY + const enqueue = (fn: () => Promise) => { + promises.push( + (async () => { + await sema.acquire() + try { + await fn() + } finally { + sema.release() + if (remainingRampup > 0) { + remainingRampup-- + sema.release() + } + progress.run() + } + })() + ) + } + + if (!appDirOnly) { + for (const [page, route] of currentEntrypoints.page) { + enqueue(() => + handleRouteType({ + page, + route, + currentEntryIssues, + entrypoints: currentEntrypoints, + manifestLoader, + productionRewrites: rewrites, + logErrors: false, + }) + ) + } + } + + for (const [page, route] of currentEntrypoints.app) { + enqueue(() => + handleRouteType({ + page, + route, + currentEntryIssues, + entrypoints: currentEntrypoints, + manifestLoader, + productionRewrites: rewrites, + logErrors: false, + }) + ) + } + + enqueue(() => + handlePagesErrorRoute({ + currentEntryIssues, + entrypoints: currentEntrypoints, + manifestLoader, + productionRewrites: rewrites, + logErrors: false, + }) + ) + await Promise.all(promises) + + await manifestLoader.writeManifests({ + devRewrites: undefined, + productionRewrites: rewrites, + entrypoints: currentEntrypoints, + }) + + const errors: { + page: string + message: string + }[] = [] + const warnings: { + page: string + message: string + }[] = [] + for (const [page, entryIssues] of currentEntryIssues) { + for (const issue of entryIssues.values()) { + if (issue.severity !== 'warning') { + errors.push({ + page, + message: formatIssue(issue), + }) + } else { + if (isRelevantWarning(issue)) { + warnings.push({ + page, + message: formatIssue(issue), + }) + } + } + } + } + + const shutdownPromise = project.shutdown() + + if (warnings.length > 0) { + Log.warn( + `Turbopack build collected ${warnings.length} warnings:\n${warnings + .map((e) => { + return 'Page: ' + e.page + '\n' + e.message + }) + .join('\n')}` + ) + } + + if (errors.length > 0) { + throw new Error( + `Turbopack build failed with ${errors.length} errors:\n${errors + .map((e) => { + return 'Page: ' + e.page + '\n' + e.message + }) + .join('\n')}` + ) + } + + const time = process.hrtime(startTime) + return { + duration: time[0] + time[1] / 1e9, + buildTraceContext: undefined, + shutdownPromise, + } +} + +export async function workerMain(workerData: { + buildContext: typeof NextBuildContext +}): Promise>> { + // setup new build context from the serialized data passed from the parent + Object.assign(NextBuildContext, workerData.buildContext) + + /// load the config because it's not serializable + NextBuildContext.config = await loadConfig( + PHASE_PRODUCTION_BUILD, + NextBuildContext.dir! + ) + + // Matches handling in build/index.ts + // https://github.com/vercel/next.js/blob/84f347fc86f4efc4ec9f13615c215e4b9fb6f8f0/packages/next/src/build/index.ts#L815-L818 + // Ensures the `config.distDir` option is matched. + if (hasCustomExportOutput(NextBuildContext.config)) { + NextBuildContext.config.distDir = '.next' + } + + // Clone the telemetry for worker + const telemetry = new Telemetry({ + distDir: NextBuildContext.config.distDir, + }) + setGlobal('telemetry', telemetry) + + const result = await turbopackBuild() + return result +} diff --git a/packages/next/src/build/turbopack-build/index.ts b/packages/next/src/build/turbopack-build/index.ts new file mode 100644 index 0000000000000..7ecb71626392d --- /dev/null +++ b/packages/next/src/build/turbopack-build/index.ts @@ -0,0 +1,62 @@ +import path from 'path' +import { + formatNodeOptions, + getParsedNodeOptionsWithoutInspect, +} from '../../server/lib/utils' +import { Worker } from '../../lib/worker' +import { NextBuildContext } from '../build-context' + +async function turbopackBuildWithWorker() { + const nodeOptions = getParsedNodeOptionsWithoutInspect() + + try { + const worker = new Worker(path.join(__dirname, 'impl.js'), { + exposedMethods: ['workerMain'], + numWorkers: 1, + maxRetries: 0, + forkOptions: { + env: { + ...process.env, + NEXT_PRIVATE_BUILD_WORKER: '1', + NODE_OPTIONS: formatNodeOptions(nodeOptions), + }, + }, + }) as Worker & typeof import('./impl') + const { nextBuildSpan, ...prunedBuildContext } = NextBuildContext + const result = await worker.workerMain({ + buildContext: prunedBuildContext, + }) + + // destroy worker so it's not sticking around using memory + await worker.end() + + return result + } catch (err: any) { + // When the error is a serialized `Error` object we need to recreate the `Error` instance + // in order to keep the consistent error reporting behavior. + if (err.type === 'Error') { + const error = new Error(err.message) + if (err.name) { + error.name = err.name + } + if (err.cause) { + error.cause = err.cause + } + error.message = err.message + error.stack = err.stack + throw error + } + throw err + } +} + +export function turbopackBuild( + withWorker: boolean +): ReturnType { + if (withWorker) { + return turbopackBuildWithWorker() + } else { + const build = (require('./impl') as typeof import('./impl')).turbopackBuild + return build() + } +} diff --git a/packages/next/src/build/webpack/plugins/eval-source-map-dev-tool-plugin.ts b/packages/next/src/build/webpack/plugins/eval-source-map-dev-tool-plugin.ts index ae0e7051dfc9e..8d46d2c2b7b8e 100644 --- a/packages/next/src/build/webpack/plugins/eval-source-map-dev-tool-plugin.ts +++ b/packages/next/src/build/webpack/plugins/eval-source-map-dev-tool-plugin.ts @@ -3,6 +3,7 @@ Author Tobias Koppers @sokra Forked to add support for `ignoreList`. + Keep in sync with packages/next/webpack-plugins/eval-source-map-dev-tool-plugin.js */ import { type webpack, diff --git a/packages/next/src/client/components/react-dev-overlay/_experimental/internal/components/dialog/dialog.tsx b/packages/next/src/client/components/react-dev-overlay/_experimental/internal/components/dialog/dialog.tsx index ee574540af7e3..f232086b9172c 100644 --- a/packages/next/src/client/components/react-dev-overlay/_experimental/internal/components/dialog/dialog.tsx +++ b/packages/next/src/client/components/react-dev-overlay/_experimental/internal/components/dialog/dialog.tsx @@ -10,6 +10,12 @@ export type DialogProps = { onClose?: () => void } +const CSS_SELECTORS_TO_EXCLUDE_ON_CLICK_OUTSIDE = [ + '[data-next-mark]', + '[data-issues-open]', + '#nextjs-dev-tools-menu', +] + const Dialog: React.FC = function Dialog({ children, type, @@ -26,7 +32,7 @@ const Dialog: React.FC = function Dialog({ const onDialog = React.useCallback((node: HTMLDivElement | null) => { setDialog(node) }, []) - useOnClickOutside(dialog, (e) => { + useOnClickOutside(dialog, CSS_SELECTORS_TO_EXCLUDE_ON_CLICK_OUTSIDE, (e) => { e.preventDefault() return onClose?.() }) diff --git a/packages/next/src/client/components/react-dev-overlay/_experimental/internal/components/errors/dev-tools-indicator/dev-tools-indicator.tsx b/packages/next/src/client/components/react-dev-overlay/_experimental/internal/components/errors/dev-tools-indicator/dev-tools-indicator.tsx index bc4a394980810..69b1cdf890cfa 100644 --- a/packages/next/src/client/components/react-dev-overlay/_experimental/internal/components/errors/dev-tools-indicator/dev-tools-indicator.tsx +++ b/packages/next/src/client/components/react-dev-overlay/_experimental/internal/components/errors/dev-tools-indicator/dev-tools-indicator.tsx @@ -157,7 +157,7 @@ function DevToolsPopover({ } } - function onIssuesClick() { + function openErrorOverlay() { if (issueCount > 0) { setIsErrorOverlayOpen(true) } @@ -165,7 +165,6 @@ function DevToolsPopover({ function onTriggerClick() { setIsMenuOpen((prev) => !prev) - onIssuesClick() } function closeMenu() { @@ -193,9 +192,9 @@ function DevToolsPopover({ aria-label={`${isMenuOpen ? 'Close' : 'Open'} Next.js Dev Tools`} data-nextjs-dev-tools-button issueCount={issueCount} - onClick={onTriggerClick} + onTriggerClick={onTriggerClick} onKeyDown={onTriggerKeydown} - onIssuesClick={onIssuesClick} + openErrorOverlay={openErrorOverlay} isDevBuilding={useIsDevBuilding()} isDevRendering={useIsDevRendering()} /> @@ -231,7 +230,7 @@ function DevToolsPopover({ index={0} label="Issues" value={{issueCount}} - onClick={onIssuesClick} + onClick={openErrorOverlay} /> { issueCount: number isDevBuilding: boolean isDevRendering: boolean - onClick: () => void - onIssuesClick: () => void + onTriggerClick: () => void + openErrorOverlay: () => void } const SIZE = 36 @@ -18,8 +18,8 @@ export const NextLogo = forwardRef(function NextLogo( issueCount, isDevBuilding, isDevRendering, - onClick, - onIssuesClick, + onTriggerClick, + openErrorOverlay, ...props }: Props, propRef: React.Ref @@ -32,7 +32,6 @@ export const NextLogo = forwardRef(function NextLogo( const isLoading = useMinimumLoadingTimeMultiple( isDevBuilding || isDevRendering ) - return (
@@ -297,7 +296,7 @@ export const NextLogo = forwardRef(function NextLogo(