diff --git a/Cargo.lock b/Cargo.lock index e2f6a79162b5e..6ba937b45fca0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2761,7 +2761,7 @@ dependencies = [ "httpdate", "itoa", "pin-project-lite", - "socket2 0.5.6", + "socket2 0.4.9", "tokio", "tower-service", "tracing", @@ -3399,9 +3399,9 @@ dependencies = [ [[package]] name = "lightningcss" -version = "1.0.0-alpha.61" +version = "1.0.0-alpha.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20c9e1f991b3861d25bf872ecca2eb6a73f7a9fe671da047cd1f9b49c65cbc40" +checksum = "8a75fcbcdbcc84fc1ae7c60c31f99337560b620757a9bfc1c9f84df3cff8ac24" dependencies = [ "ahash 0.8.11", "bitflags 2.5.0", @@ -3439,9 +3439,9 @@ dependencies = [ [[package]] name = "lightningcss-napi" -version = "0.4.0" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f76d2c3181b0c8c499a629034f141177fef173af08aa19c8b7dab4268ca61e30" +checksum = "8f5e41d371670417f71b779fe6d66959a68c21fbda563a747d795ac525f72450" dependencies = [ "cssparser", "lightningcss", @@ -4484,9 +4484,9 @@ dependencies = [ [[package]] name = "parcel_selectors" -version = "0.28.0" +version = "0.28.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7645c578d3a5c4cdf667af1ad39765f5f751c4883d251e050d5e1204b5cad0a9" +checksum = "dccbc6fb560df303a44e511618256029410efbc87779018f751ef12c488271fe" dependencies = [ "bitflags 2.5.0", "cssparser", @@ -6195,10 +6195,11 @@ dependencies = [ [[package]] name = "static-self" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "253e76c8c993a7b1b201b0539228b334582153cd4364292822d2c30776d469c7" +checksum = "f6635404b73efc136af3a7956e53c53d4f34b2f16c95a15c438929add0f69412" dependencies = [ + "indexmap 2.5.0", "smallvec", "static-self-derive", ] diff --git a/Cargo.toml b/Cargo.toml index 73d1d287cfe1c..ca78b97a68aca 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -151,12 +151,12 @@ indoc = "2.0.0" itertools = "0.10.5" lazy_static = "1.4.0" log = "0.4.17" -lightningcss = { version = "1.0.0-alpha.61", features = [ +lightningcss = { version = "1.0.0-alpha.63", features = [ "serde", "visitor", "into_owned", ] } -lightningcss-napi = { version = "0.4.0", default-features = false, features = [ +lightningcss-napi = { version = "0.4.3", default-features = false, features = [ "visitor" ]} markdown = "1.0.0-alpha.18" @@ -165,7 +165,7 @@ nohash-hasher = "0.2.0" notify = "6.1.1" once_cell = "1.17.1" owo-colors = "3.5.0" -parcel_selectors = "0.28.0" +parcel_selectors = "0.28.1" parking_lot = "0.12.1" pathdiff = "0.2.1" petgraph = "0.6.3" diff --git a/lerna.json b/lerna.json index b582745f1f9b5..645a6ae6f0f66 100644 --- a/lerna.json +++ b/lerna.json @@ -16,5 +16,5 @@ "registry": "https://registry.npmjs.org/" } }, - "version": "15.2.0-canary.2" + "version": "15.2.0-canary.3" } diff --git a/packages/create-next-app/package.json b/packages/create-next-app/package.json index 83ca1f187b61a..0a53ee13a5392 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.2", + "version": "15.2.0-canary.3", "keywords": [ "react", "next", diff --git a/packages/eslint-config-next/package.json b/packages/eslint-config-next/package.json index 314f64f1b5369..3967bac97f241 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.2", + "version": "15.2.0-canary.3", "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.2", + "@next/eslint-plugin-next": "15.2.0-canary.3", "@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-plugin-next/package.json b/packages/eslint-plugin-next/package.json index a8f82c2655352..51d4bb48c591e 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.2", + "version": "15.2.0-canary.3", "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 9a7b84169fa33..c560a496d9512 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.2", + "version": "15.2.0-canary.3", "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 ea55923ad1037..6777c583fb9ac 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.2", + "version": "15.2.0-canary.3", "main": "index.js", "types": "index.d.ts", "license": "MIT", diff --git a/packages/next-codemod/package.json b/packages/next-codemod/package.json index a64cd4c6a985f..7d60e789e6944 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.2", + "version": "15.2.0-canary.3", "license": "MIT", "repository": { "type": "git", diff --git a/packages/next-env/package.json b/packages/next-env/package.json index e0a2b26276f8d..35a968a94518a 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.2", + "version": "15.2.0-canary.3", "keywords": [ "react", "next", diff --git a/packages/next-mdx/package.json b/packages/next-mdx/package.json index fce76e417bd73..92a243d9a7742 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.2", + "version": "15.2.0-canary.3", "main": "index.js", "license": "MIT", "repository": { diff --git a/packages/next-plugin-storybook/package.json b/packages/next-plugin-storybook/package.json index 8d51e716c3f90..c6e050c963fe2 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.2", + "version": "15.2.0-canary.3", "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 ff4564ee1e9d5..f5b8f6ef1a6fc 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.2", + "version": "15.2.0-canary.3", "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 545e0383f2b5d..1d1d75d341934 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.2", + "version": "15.2.0-canary.3", "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 7decc2cf353d4..b0357a4237e58 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.2", + "version": "15.2.0-canary.3", "private": true, "scripts": { "clean": "node ../../scripts/rm.mjs native", diff --git a/packages/next/package.json b/packages/next/package.json index 2d92caec32268..8f69ba1e4bee9 100644 --- a/packages/next/package.json +++ b/packages/next/package.json @@ -1,6 +1,6 @@ { "name": "next", - "version": "15.2.0-canary.2", + "version": "15.2.0-canary.3", "description": "The React Framework", "main": "./dist/server/next.js", "license": "MIT", @@ -99,7 +99,7 @@ ] }, "dependencies": { - "@next/env": "15.2.0-canary.2", + "@next/env": "15.2.0-canary.3", "@swc/counter": "0.1.3", "@swc/helpers": "0.5.15", "busboy": "1.6.0", @@ -164,11 +164,11 @@ "@jest/types": "29.5.0", "@mswjs/interceptors": "0.23.0", "@napi-rs/triples": "1.2.0", - "@next/font": "15.2.0-canary.2", - "@next/polyfill-module": "15.2.0-canary.2", - "@next/polyfill-nomodule": "15.2.0-canary.2", - "@next/react-refresh-utils": "15.2.0-canary.2", - "@next/swc": "15.2.0-canary.2", + "@next/font": "15.2.0-canary.3", + "@next/polyfill-module": "15.2.0-canary.3", + "@next/polyfill-nomodule": "15.2.0-canary.3", + "@next/react-refresh-utils": "15.2.0-canary.3", + "@next/swc": "15.2.0-canary.3", "@opentelemetry/api": "1.6.0", "@playwright/test": "1.41.2", "@storybook/addon-essentials": "^8.4.7", diff --git a/packages/next/src/client/components/react-dev-overlay/internal/helpers/attach-hydration-error-state.ts b/packages/next/src/client/components/errors/attach-hydration-error-state.ts similarity index 97% rename from packages/next/src/client/components/react-dev-overlay/internal/helpers/attach-hydration-error-state.ts rename to packages/next/src/client/components/errors/attach-hydration-error-state.ts index 9cb6758344573..9c282fef14aed 100644 --- a/packages/next/src/client/components/react-dev-overlay/internal/helpers/attach-hydration-error-state.ts +++ b/packages/next/src/client/components/errors/attach-hydration-error-state.ts @@ -1,7 +1,7 @@ import { isHydrationError, getDefaultHydrationErrorMessage, -} from '../../../is-hydration-error' +} from '../is-hydration-error' import { hydrationErrorState, getReactHydrationDiffSegments, diff --git a/packages/next/src/client/components/react-dev-overlay/_experimental/internal/helpers/console-error.ts b/packages/next/src/client/components/errors/console-error.ts similarity index 100% rename from packages/next/src/client/components/react-dev-overlay/_experimental/internal/helpers/console-error.ts rename to packages/next/src/client/components/errors/console-error.ts diff --git a/packages/next/src/client/components/react-dev-overlay/internal/helpers/enqueue-client-error.ts b/packages/next/src/client/components/errors/enqueue-client-error.ts similarity index 92% rename from packages/next/src/client/components/react-dev-overlay/internal/helpers/enqueue-client-error.ts rename to packages/next/src/client/components/errors/enqueue-client-error.ts index bc1009207eabe..6f394a6cfdcc3 100644 --- a/packages/next/src/client/components/react-dev-overlay/internal/helpers/enqueue-client-error.ts +++ b/packages/next/src/client/components/errors/enqueue-client-error.ts @@ -1,4 +1,4 @@ -import { isHydrationError } from '../../../is-hydration-error' +import { isHydrationError } from '../is-hydration-error' // Dedupe the two consecutive errors: If the previous one is same as current one, ignore the current one. export function enqueueConsecutiveDedupedError( diff --git a/packages/next/src/client/components/react-dev-overlay/internal/helpers/hydration-error-info.ts b/packages/next/src/client/components/errors/hydration-error-info.ts similarity index 98% rename from packages/next/src/client/components/react-dev-overlay/internal/helpers/hydration-error-info.ts rename to packages/next/src/client/components/errors/hydration-error-info.ts index 3ca474eeedb1a..633fed4e60cc0 100644 --- a/packages/next/src/client/components/react-dev-overlay/internal/helpers/hydration-error-info.ts +++ b/packages/next/src/client/components/errors/hydration-error-info.ts @@ -1,4 +1,4 @@ -import { getHydrationErrorStackInfo } from '../../../is-hydration-error' +import { getHydrationErrorStackInfo } from '../is-hydration-error' export type HydrationErrorState = { // Hydration warning template format: diff --git a/packages/next/src/client/components/react-dev-overlay/internal/helpers/runtime-error-handler.ts b/packages/next/src/client/components/errors/runtime-error-handler.ts similarity index 100% rename from packages/next/src/client/components/react-dev-overlay/internal/helpers/runtime-error-handler.ts rename to packages/next/src/client/components/errors/runtime-error-handler.ts diff --git a/packages/next/src/client/components/react-dev-overlay/internal/helpers/stitched-error.ts b/packages/next/src/client/components/errors/stitched-error.ts similarity index 96% rename from packages/next/src/client/components/react-dev-overlay/internal/helpers/stitched-error.ts rename to packages/next/src/client/components/errors/stitched-error.ts index b4ee634169e27..cfed44f3cd052 100644 --- a/packages/next/src/client/components/react-dev-overlay/internal/helpers/stitched-error.ts +++ b/packages/next/src/client/components/errors/stitched-error.ts @@ -1,5 +1,5 @@ import React from 'react' -import isError from '../../../../../lib/is-error' +import isError from '../../../lib/is-error' const REACT_ERROR_STACK_BOTTOM_FRAME = 'react-stack-bottom-frame' const REACT_ERROR_STACK_BOTTOM_FRAME_REGEX = new RegExp( diff --git a/packages/next/src/client/components/react-dev-overlay/internal/helpers/use-error-handler.ts b/packages/next/src/client/components/errors/use-error-handler.ts similarity index 93% rename from packages/next/src/client/components/react-dev-overlay/internal/helpers/use-error-handler.ts rename to packages/next/src/client/components/errors/use-error-handler.ts index a7ad315cc6bed..c09c7a8d24359 100644 --- a/packages/next/src/client/components/react-dev-overlay/internal/helpers/use-error-handler.ts +++ b/packages/next/src/client/components/errors/use-error-handler.ts @@ -1,12 +1,12 @@ import { useEffect } from 'react' import { attachHydrationErrorState } from './attach-hydration-error-state' -import { isNextRouterError } from '../../../is-next-router-error' +import { isNextRouterError } from '../is-next-router-error' import { storeHydrationErrorStateFromConsoleArgs } from './hydration-error-info' -import { formatConsoleArgs } from '../../../../lib/console' -import isError from '../../../../../lib/is-error' +import { formatConsoleArgs } from '../../lib/console' +import isError from '../../../lib/is-error' import { createUnhandledError } from './console-error' import { enqueueConsecutiveDedupedError } from './enqueue-client-error' -import { getReactStitchedError } from './stitched-error' +import { getReactStitchedError } from '../errors/stitched-error' const queueMicroTask = globalThis.queueMicrotask || ((cb: () => void) => Promise.resolve().then(cb)) diff --git a/packages/next/src/client/components/globals/handle-global-errors.ts b/packages/next/src/client/components/globals/handle-global-errors.ts index 69fedce605ca5..691bd76748710 100644 --- a/packages/next/src/client/components/globals/handle-global-errors.ts +++ b/packages/next/src/client/components/globals/handle-global-errors.ts @@ -1,3 +1,3 @@ -import { handleGlobalErrors } from '../react-dev-overlay/internal/helpers/use-error-handler' +import { handleGlobalErrors } from '../errors/use-error-handler' handleGlobalErrors() diff --git a/packages/next/src/client/components/globals/intercept-console-error.ts b/packages/next/src/client/components/globals/intercept-console-error.ts index 38c5e7035bdd3..a6d999d8ec256 100644 --- a/packages/next/src/client/components/globals/intercept-console-error.ts +++ b/packages/next/src/client/components/globals/intercept-console-error.ts @@ -1,6 +1,6 @@ import isError from '../../../lib/is-error' import { isNextRouterError } from '../is-next-router-error' -import { handleClientError } from '../react-dev-overlay/internal/helpers/use-error-handler' +import { handleClientError } from '../errors/use-error-handler' export const originConsoleError = window.console.error diff --git a/packages/next/src/client/components/react-dev-overlay/_experimental/internal/container/Errors.tsx b/packages/next/src/client/components/react-dev-overlay/_experimental/internal/container/Errors.tsx index 115ce814181dc..ce26b5adac913 100644 --- a/packages/next/src/client/components/react-dev-overlay/_experimental/internal/container/Errors.tsx +++ b/packages/next/src/client/components/react-dev-overlay/_experimental/internal/container/Errors.tsx @@ -18,11 +18,11 @@ import { PseudoHtmlDiff } from './RuntimeError/component-stack-pseudo-html' import { type HydrationErrorState, getHydrationWarningType, -} from '../helpers/hydration-error-info' +} from '../../../../errors/hydration-error-info' import { getUnhandledErrorType, isUnhandledConsoleOrRejection, -} from '../helpers/console-error' +} from '../../../../errors/console-error' import { extractNextErrorCode } from '../../../../../../lib/error-telemetry-utils' import { DevToolsIndicator } from '../components/Errors/dev-tools-indicator/dev-tools-indicator' import { ErrorOverlayLayout } from '../components/Errors/error-overlay-layout/error-overlay-layout' diff --git a/packages/next/src/client/components/react-dev-overlay/_experimental/internal/helpers/attach-hydration-error-state.ts b/packages/next/src/client/components/react-dev-overlay/_experimental/internal/helpers/attach-hydration-error-state.ts deleted file mode 100644 index 8ee6c80c707be..0000000000000 --- a/packages/next/src/client/components/react-dev-overlay/_experimental/internal/helpers/attach-hydration-error-state.ts +++ /dev/null @@ -1,46 +0,0 @@ -import { - isHydrationError, - getDefaultHydrationErrorMessage, -} from '../../../../is-hydration-error' -import { - hydrationErrorState, - getReactHydrationDiffSegments, -} from './hydration-error-info' - -export function attachHydrationErrorState(error: Error) { - if ( - isHydrationError(error) && - !error.message.includes( - 'https://nextjs.org/docs/messages/react-hydration-error' - ) - ) { - const reactHydrationDiffSegments = getReactHydrationDiffSegments( - error.message - ) - let parsedHydrationErrorState: typeof hydrationErrorState = {} - if (reactHydrationDiffSegments) { - parsedHydrationErrorState = { - ...(error as any).details, - ...hydrationErrorState, - warning: hydrationErrorState.warning || [ - getDefaultHydrationErrorMessage(), - ], - notes: reactHydrationDiffSegments[0], - reactOutputComponentDiff: reactHydrationDiffSegments[1], - } - } else { - // If there's any extra information in the error message to display, - // append it to the error message details property - if (hydrationErrorState.warning) { - // The patched console.error found hydration errors logged by React - // Append the logged warning to the error message - parsedHydrationErrorState = { - ...(error as any).details, - // It contains the warning, component stack, server and client tag names - ...hydrationErrorState, - } - } - } - ;(error as any).details = parsedHydrationErrorState - } -} diff --git a/packages/next/src/client/components/react-dev-overlay/_experimental/internal/helpers/enqueue-client-error.ts b/packages/next/src/client/components/react-dev-overlay/_experimental/internal/helpers/enqueue-client-error.ts deleted file mode 100644 index 8e2df164dddd2..0000000000000 --- a/packages/next/src/client/components/react-dev-overlay/_experimental/internal/helpers/enqueue-client-error.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { isHydrationError } from '../../../../is-hydration-error' - -// Dedupe the two consecutive errors: If the previous one is same as current one, ignore the current one. -export function enqueueConsecutiveDedupedError( - queue: Array, - error: Error -) { - const isFront = isHydrationError(error) - const previousError = isFront ? queue[0] : queue[queue.length - 1] - // Compare the error stack to dedupe the consecutive errors - if (previousError && previousError.stack === error.stack) { - return - } - // TODO: change all to push error into errorQueue, - // currently there's a async api error is always erroring while hydration error showing up. - // Move hydration error to the front of the queue to unblock. - if (isFront) { - queue.unshift(error) - } else { - queue.push(error) - } -} diff --git a/packages/next/src/client/components/react-dev-overlay/_experimental/internal/helpers/hydration-error-info.ts b/packages/next/src/client/components/react-dev-overlay/_experimental/internal/helpers/hydration-error-info.ts deleted file mode 100644 index 0b1fbb6389169..0000000000000 --- a/packages/next/src/client/components/react-dev-overlay/_experimental/internal/helpers/hydration-error-info.ts +++ /dev/null @@ -1,105 +0,0 @@ -import { getHydrationErrorStackInfo } from '../../../../is-hydration-error' - -export type HydrationErrorState = { - // Hydration warning template format: - warning?: [string, string, string] - componentStack?: string - serverContent?: string - clientContent?: string - // React 19 hydration diff format: - notes?: string - reactOutputComponentDiff?: string -} - -type NullableText = string | null | undefined - -export const hydrationErrorState: HydrationErrorState = {} - -// https://github.com/facebook/react/blob/main/packages/react-dom/src/__tests__/ReactDOMHydrationDiff-test.js used as a reference -const htmlTagsWarnings = new Set([ - 'Warning: In HTML, %s cannot be a child of <%s>.%s\nThis will cause a hydration error.%s', - 'Warning: In HTML, %s cannot be a descendant of <%s>.\nThis will cause a hydration error.%s', - 'Warning: In HTML, text nodes cannot be a child of <%s>.\nThis will cause a hydration error.', - "Warning: In HTML, whitespace text nodes cannot be a child of <%s>. Make sure you don't have any extra whitespace between tags on each line of your source code.\nThis will cause a hydration error.", - 'Warning: Expected server HTML to contain a matching <%s> in <%s>.%s', - 'Warning: Did not expect server HTML to contain a <%s> in <%s>.%s', -]) -const textAndTagsMismatchWarnings = new Set([ - 'Warning: Expected server HTML to contain a matching text node for "%s" in <%s>.%s', - 'Warning: Did not expect server HTML to contain the text node "%s" in <%s>.%s', -]) -const textMismatchWarning = - 'Warning: Text content did not match. Server: "%s" Client: "%s"%s' - -export const getHydrationWarningType = ( - message: NullableText -): 'tag' | 'text' | 'text-in-tag' => { - if (typeof message !== 'string') { - // TODO: Doesn't make sense to treat no message as a hydration error message. - // We should bail out somewhere earlier. - return 'text' - } - - const normalizedMessage = message.startsWith('Warning: ') - ? message - : `Warning: ${message}` - - if (isHtmlTagsWarning(normalizedMessage)) return 'tag' - if (isTextInTagsMismatchWarning(normalizedMessage)) return 'text-in-tag' - - return 'text' -} - -const isHtmlTagsWarning = (message: string) => htmlTagsWarnings.has(message) - -const isTextMismatchWarning = (message: string) => - textMismatchWarning === message -const isTextInTagsMismatchWarning = (msg: string) => - textAndTagsMismatchWarnings.has(msg) - -const isKnownHydrationWarning = (message: NullableText) => { - if (typeof message !== 'string') { - return false - } - // React 18 has the `Warning: ` prefix. - // React 19 does not. - const normalizedMessage = message.startsWith('Warning: ') - ? message - : `Warning: ${message}` - - return ( - isHtmlTagsWarning(normalizedMessage) || - isTextInTagsMismatchWarning(normalizedMessage) || - isTextMismatchWarning(normalizedMessage) - ) -} - -export const getReactHydrationDiffSegments = (msg: NullableText) => { - if (msg) { - const { message, diff } = getHydrationErrorStackInfo(msg) - if (message) return [message, diff] - } - return undefined -} - -/** - * Patch console.error to capture hydration errors. - * If any of the knownHydrationWarnings are logged, store the message and component stack. - * When the hydration runtime error is thrown, the message and component stack are added to the error. - * This results in a more helpful error message in the error overlay. - */ - -export function storeHydrationErrorStateFromConsoleArgs(...args: any[]) { - const [msg, serverContent, clientContent, componentStack] = args - if (isKnownHydrationWarning(msg)) { - hydrationErrorState.warning = [ - // remove the last %s from the message - msg, - serverContent, - clientContent, - ] - hydrationErrorState.componentStack = componentStack - hydrationErrorState.serverContent = serverContent - hydrationErrorState.clientContent = clientContent - } -} diff --git a/packages/next/src/client/components/react-dev-overlay/_experimental/internal/helpers/stitched-error.ts b/packages/next/src/client/components/react-dev-overlay/_experimental/internal/helpers/stitched-error.ts deleted file mode 100644 index fbe2ba6f2d7f8..0000000000000 --- a/packages/next/src/client/components/react-dev-overlay/_experimental/internal/helpers/stitched-error.ts +++ /dev/null @@ -1,49 +0,0 @@ -import React from 'react' -import isError from '../../../../../../lib/is-error' - -const REACT_ERROR_STACK_BOTTOM_FRAME = 'react-stack-bottom-frame' -const REACT_ERROR_STACK_BOTTOM_FRAME_REGEX = new RegExp( - `(at ${REACT_ERROR_STACK_BOTTOM_FRAME} )|(${REACT_ERROR_STACK_BOTTOM_FRAME}\\@)` -) - -const captureOwnerStack = (React as any).captureOwnerStack - ? (React as any).captureOwnerStack - : () => '' - -export function getReactStitchedError(err: T): Error | T { - if (typeof (React as any).captureOwnerStack !== 'function') { - return err - } - const isErrorInstance = isError(err) - const originStack = isErrorInstance ? err.stack || '' : '' - const originMessage = isErrorInstance ? err.message : '' - const stackLines = originStack.split('\n') - const indexOfSplit = stackLines.findIndex((line) => - REACT_ERROR_STACK_BOTTOM_FRAME_REGEX.test(line) - ) - const isOriginalReactError = indexOfSplit >= 0 // has the react-stack-bottom-frame - let newStack = isOriginalReactError - ? stackLines.slice(0, indexOfSplit).join('\n') - : originStack - - const newError = new Error(originMessage) - // Copy all enumerable properties, e.g. digest - Object.assign(newError, err) - newError.stack = newStack - - // Avoid duplicate overriding stack frames - appendOwnerStack(newError) - - return newError -} - -function appendOwnerStack(error: Error) { - let stack = error.stack || '' - // Avoid duplicate overriding stack frames - const ownerStack = captureOwnerStack() - if (ownerStack && stack.endsWith(ownerStack) === false) { - stack += ownerStack - // Override stack - error.stack = stack - } -} diff --git a/packages/next/src/client/components/react-dev-overlay/app/OldReactDevOverlay.tsx b/packages/next/src/client/components/react-dev-overlay/app/OldReactDevOverlay.tsx index def9d8db35352..b16971ffed495 100644 --- a/packages/next/src/client/components/react-dev-overlay/app/OldReactDevOverlay.tsx +++ b/packages/next/src/client/components/react-dev-overlay/app/OldReactDevOverlay.tsx @@ -9,7 +9,7 @@ import { ComponentStyles } from '../internal/styles/ComponentStyles' import { CssReset } from '../internal/styles/CssReset' import { RootLayoutMissingTagsError } from '../internal/container/RootLayoutMissingTagsError' import type { Dispatcher } from './hot-reloader-client' -import { RuntimeErrorHandler } from '../internal/helpers/runtime-error-handler' +import { RuntimeErrorHandler } from '../../errors/runtime-error-handler' interface ReactDevOverlayState { isReactError: boolean diff --git a/packages/next/src/client/components/react-dev-overlay/app/hot-reloader-client.tsx b/packages/next/src/client/components/react-dev-overlay/app/hot-reloader-client.tsx index 0b1a2dc339362..2b027edd4c8b4 100644 --- a/packages/next/src/client/components/react-dev-overlay/app/hot-reloader-client.tsx +++ b/packages/next/src/client/components/react-dev-overlay/app/hot-reloader-client.tsx @@ -24,8 +24,8 @@ import { } from '../shared' import { parseStack } from '../internal/helpers/parse-stack' import ReactDevOverlay from './ReactDevOverlay' -import { useErrorHandler } from '../internal/helpers/use-error-handler' -import { RuntimeErrorHandler } from '../internal/helpers/runtime-error-handler' +import { useErrorHandler } from '../../errors/use-error-handler' +import { RuntimeErrorHandler } from '../../errors/runtime-error-handler' import { useSendMessage, useTurbopack, @@ -41,10 +41,10 @@ import type { } from '../../../../server/dev/hot-reloader-types' import { extractModulesFromTurbopackMessage } from '../../../../server/dev/extract-modules-from-turbopack-message' import { REACT_REFRESH_FULL_RELOAD_FROM_ERROR } from '../shared' -import type { HydrationErrorState } from '../internal/helpers/hydration-error-info' +import type { HydrationErrorState } from '../../errors/hydration-error-info' import type { DebugInfo } from '../types' import { useUntrackedPathname } from '../../navigation-untracked' -import { getReactStitchedError } from '../internal/helpers/stitched-error' +import { getReactStitchedError } from '../../errors/stitched-error' import { shouldRenderRootLevelErrorOverlay } from '../../../lib/is-error-thrown-while-rendering-rsc' import { handleDevBuildIndicatorHmrEvents } from '../../../dev/dev-build-indicator/internal/handle-dev-build-indicator-hmr-events' diff --git a/packages/next/src/client/components/react-dev-overlay/internal/container/Errors.tsx b/packages/next/src/client/components/react-dev-overlay/internal/container/Errors.tsx index b617d0fcdc105..c46ac62bc2198 100644 --- a/packages/next/src/client/components/react-dev-overlay/internal/container/Errors.tsx +++ b/packages/next/src/client/components/react-dev-overlay/internal/container/Errors.tsx @@ -28,13 +28,13 @@ import { PseudoHtmlDiff } from './RuntimeError/component-stack-pseudo-html' import { type HydrationErrorState, getHydrationWarningType, -} from '../helpers/hydration-error-info' +} from '../../../errors/hydration-error-info' import { NodejsInspectorCopyButton } from '../components/nodejs-inspector' import { CopyButton } from '../components/copy-button' import { getUnhandledErrorType, isUnhandledConsoleOrRejection, -} from '../helpers/console-error' +} from '../../../errors/console-error' import { extractNextErrorCode } from '../../../../../lib/error-telemetry-utils' export type SupportedErrorEvent = { diff --git a/packages/next/src/client/components/react-dev-overlay/internal/helpers/console-error.ts b/packages/next/src/client/components/react-dev-overlay/internal/helpers/console-error.ts deleted file mode 100644 index 225452dcc4abd..0000000000000 --- a/packages/next/src/client/components/react-dev-overlay/internal/helpers/console-error.ts +++ /dev/null @@ -1,29 +0,0 @@ -// To distinguish from React error.digest, we use a different symbol here to determine if the error is from console.error or unhandled promise rejection. -const digestSym = Symbol.for('next.console.error.digest') -const consoleTypeSym = Symbol.for('next.console.error.type') - -// Represent non Error shape unhandled promise rejections or console.error errors. -// Those errors will be captured and displayed in Error Overlay. -type UnhandledError = Error & { - [digestSym]: 'NEXT_UNHANDLED_ERROR' - [consoleTypeSym]: 'string' | 'error' -} - -export function createUnhandledError(message: string | Error): UnhandledError { - const error = ( - typeof message === 'string' ? new Error(message) : message - ) as UnhandledError - error[digestSym] = 'NEXT_UNHANDLED_ERROR' - error[consoleTypeSym] = typeof message === 'string' ? 'string' : 'error' - return error -} - -export const isUnhandledConsoleOrRejection = ( - error: any -): error is UnhandledError => { - return error && error[digestSym] === 'NEXT_UNHANDLED_ERROR' -} - -export const getUnhandledErrorType = (error: UnhandledError) => { - return error[consoleTypeSym] -} diff --git a/packages/next/src/client/components/react-dev-overlay/pages/client.ts b/packages/next/src/client/components/react-dev-overlay/pages/client.ts index 69f4f997166a8..c549a796a7d26 100644 --- a/packages/next/src/client/components/react-dev-overlay/pages/client.ts +++ b/packages/next/src/client/components/react-dev-overlay/pages/client.ts @@ -4,7 +4,7 @@ import { parseComponentStack } from '../internal/helpers/parse-component-stack' import { hydrationErrorState, storeHydrationErrorStateFromConsoleArgs, -} from '../internal/helpers/hydration-error-info' +} from '../../errors/hydration-error-info' import { ACTION_BEFORE_REFRESH, ACTION_BUILD_ERROR, @@ -15,7 +15,7 @@ import { ACTION_VERSION_INFO, } from '../shared' import type { VersionInfo } from '../../../../server/dev/parse-version-info' -import { attachHydrationErrorState } from '../internal/helpers/attach-hydration-error-state' +import { attachHydrationErrorState } from '../../errors/attach-hydration-error-state' let isRegistered = false let stackTraceLimit: number | undefined = undefined diff --git a/packages/next/src/client/components/react-dev-overlay/pages/hot-reloader-client.ts b/packages/next/src/client/components/react-dev-overlay/pages/hot-reloader-client.ts index 748ef35f2384c..636b9d943ebce 100644 --- a/packages/next/src/client/components/react-dev-overlay/pages/hot-reloader-client.ts +++ b/packages/next/src/client/components/react-dev-overlay/pages/hot-reloader-client.ts @@ -46,7 +46,7 @@ import type { } from '../../../../server/dev/hot-reloader-types' import { extractModulesFromTurbopackMessage } from '../../../../server/dev/extract-modules-from-turbopack-message' import { REACT_REFRESH_FULL_RELOAD_FROM_ERROR } from '../shared' -import { RuntimeErrorHandler } from '../internal/helpers/runtime-error-handler' +import { RuntimeErrorHandler } from '../../errors/runtime-error-handler' // This alternative WebpackDevServer combines the functionality of: // https://github.com/webpack/webpack-dev-server/blob/webpack-1/client/index.js // https://github.com/webpack/webpack/blob/webpack-1/hot/dev-server.js diff --git a/packages/next/src/client/page-bootstrap.ts b/packages/next/src/client/page-bootstrap.ts index 54c5f49405e12..db50a3684071e 100644 --- a/packages/next/src/client/page-bootstrap.ts +++ b/packages/next/src/client/page-bootstrap.ts @@ -11,7 +11,7 @@ import { urlQueryToSearchParams, } from '../shared/lib/router/utils/querystring' import { HMR_ACTIONS_SENT_TO_BROWSER } from '../server/dev/hot-reloader-types' -import { RuntimeErrorHandler } from './components/react-dev-overlay/internal/helpers/runtime-error-handler' +import { RuntimeErrorHandler } from './components/errors/runtime-error-handler' import { REACT_REFRESH_FULL_RELOAD_FROM_ERROR } from './components/react-dev-overlay/shared' import { performFullReload } from './components/react-dev-overlay/pages/hot-reloader-client' import { initializeDevBuildIndicatorForPageRouter } from './dev/dev-build-indicator/initialize-for-page-router' diff --git a/packages/next/src/client/react-client-callbacks/error-boundary-callbacks.ts b/packages/next/src/client/react-client-callbacks/error-boundary-callbacks.ts index 099769656ad14..ceba2be7b8aba 100644 --- a/packages/next/src/client/react-client-callbacks/error-boundary-callbacks.ts +++ b/packages/next/src/client/react-client-callbacks/error-boundary-callbacks.ts @@ -1,8 +1,8 @@ // This file is only used in app router due to the specific error state handling. import type { HydrationOptions } from 'react-dom/client' -import { getReactStitchedError } from '../components/react-dev-overlay/internal/helpers/stitched-error' -import { handleClientError } from '../components/react-dev-overlay/internal/helpers/use-error-handler' +import { getReactStitchedError } from '../components/errors/stitched-error' +import { handleClientError } from '../components/errors/use-error-handler' import { isNextRouterError } from '../components/is-next-router-error' import { isBailoutToCSRError } from '../../shared/lib/lazy-dynamic/bailout-to-csr' import { reportGlobalError } from './report-global-error' diff --git a/packages/next/src/client/react-client-callbacks/on-recoverable-error.ts b/packages/next/src/client/react-client-callbacks/on-recoverable-error.ts index 9347e75a89fd2..a5805eea4fbc2 100644 --- a/packages/next/src/client/react-client-callbacks/on-recoverable-error.ts +++ b/packages/next/src/client/react-client-callbacks/on-recoverable-error.ts @@ -3,7 +3,7 @@ import type { HydrationOptions } from 'react-dom/client' import { isBailoutToCSRError } from '../../shared/lib/lazy-dynamic/bailout-to-csr' import { reportGlobalError } from './report-global-error' -import { getReactStitchedError } from '../components/react-dev-overlay/internal/helpers/stitched-error' +import { getReactStitchedError } from '../components/errors/stitched-error' import isError from '../../lib/is-error' export const onRecoverableError: HydrationOptions['onRecoverableError'] = ( diff --git a/packages/next/src/server/typescript/rules/metadata.ts b/packages/next/src/server/typescript/rules/metadata.ts index 282427f0872f1..93e410d4fa00c 100644 --- a/packages/next/src/server/typescript/rules/metadata.ts +++ b/packages/next/src/server/typescript/rules/metadata.ts @@ -9,8 +9,8 @@ import { import type tsModule from 'typescript/lib/tsserverlibrary' -const TYPE_ANOTATION = ': Metadata' -const TYPE_ANOTATION_ASYNC = ': Promise' +const TYPE_ANNOTATION = ': Metadata | null' +const TYPE_ANNOTATION_ASYNC = ': Promise' const TYPE_IMPORT = `\n\nimport type { Metadata } from 'next'` // Find the `export const metadata = ...` node. @@ -152,7 +152,7 @@ function updateVirtualFileWithType( const source = getSource(fileName) if (!source) return - // We annotate with the type in a vritual language service + // We annotate with the type in a virtual language service const sourceText = source.getFullText() let nodeEnd: number let annotation: string @@ -164,13 +164,13 @@ function updateVirtualFileWithType( const isAsync = node.modifiers?.some( (m) => m.kind === ts.SyntaxKind.AsyncKeyword ) - annotation = isAsync ? TYPE_ANOTATION_ASYNC : TYPE_ANOTATION + annotation = isAsync ? TYPE_ANNOTATION_ASYNC : TYPE_ANNOTATION } else { return } } else { nodeEnd = node.name.getFullStart() + node.name.getFullWidth() - annotation = TYPE_ANOTATION + annotation = TYPE_ANNOTATION } const newSource = @@ -234,7 +234,7 @@ const metadata = { const ts = getTs() - // We annotate with the type in a vritual language service + // We annotate with the type in a virtual language service const pos = updateVirtualFileWithType(fileName, node) if (pos === undefined) return prior @@ -335,7 +335,7 @@ const metadata = { if (node.name?.getText() === 'generateMetadata') { if (isTyped(node)) return [] - // We annotate with the type in a vritual language service + // We annotate with the type in a virtual language service const pos = updateVirtualFileWithType(fileName, node, true) if (!pos) return [] @@ -346,7 +346,7 @@ const metadata = { if (declaration.name.getText() === 'metadata') { if (isTyped(declaration)) break - // We annotate with the type in a vritual language service + // We annotate with the type in a virtual language service const pos = updateVirtualFileWithType(fileName, declaration) if (!pos) break @@ -409,7 +409,7 @@ const metadata = { declaration.getSourceFile().fileName const isSameFile = declarationFileName === fileName - // We annotate with the type in a vritual language service + // We annotate with the type in a virtual language service const pos = updateVirtualFileWithType( declarationFileName, declaration @@ -461,7 +461,7 @@ const metadata = { if (!node) return if (isTyped(node)) return - // We annotate with the type in a vritual language service + // We annotate with the type in a virtual language service const pos = updateVirtualFileWithType(fileName, node) if (pos === undefined) return @@ -485,7 +485,7 @@ const metadata = { if (!node) return if (isTyped(node)) return - // We annotate with the type in a vritual language service + // We annotate with the type in a virtual language service const pos = updateVirtualFileWithType(fileName, node) if (pos === undefined) return @@ -500,7 +500,7 @@ const metadata = { if (!node) return if (isTyped(node)) return if (!isPositionInsideNode(position, node)) return - // We annotate with the type in a vritual language service + // We annotate with the type in a virtual language service const pos = updateVirtualFileWithType(fileName, node) if (pos === undefined) return const { languageService } = getProxiedLanguageService() diff --git a/packages/react-refresh-utils/package.json b/packages/react-refresh-utils/package.json index ffabe5b69b9b0..f4e9f791cb7d0 100644 --- a/packages/react-refresh-utils/package.json +++ b/packages/react-refresh-utils/package.json @@ -1,6 +1,6 @@ { "name": "@next/react-refresh-utils", - "version": "15.2.0-canary.2", + "version": "15.2.0-canary.3", "description": "An experimental package providing utilities for React Refresh.", "repository": { "url": "vercel/next.js", diff --git a/packages/third-parties/package.json b/packages/third-parties/package.json index 6bc15539281d4..b48859d486760 100644 --- a/packages/third-parties/package.json +++ b/packages/third-parties/package.json @@ -1,6 +1,6 @@ { "name": "@next/third-parties", - "version": "15.2.0-canary.2", + "version": "15.2.0-canary.3", "repository": { "url": "vercel/next.js", "directory": "packages/third-parties" @@ -26,7 +26,7 @@ "third-party-capital": "1.0.20" }, "devDependencies": { - "next": "15.2.0-canary.2", + "next": "15.2.0-canary.3", "outdent": "0.8.0", "prettier": "2.5.1", "typescript": "5.7.2" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 30a55e3ecad82..a7bda117d930b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -793,7 +793,7 @@ importers: packages/eslint-config-next: dependencies: '@next/eslint-plugin-next': - specifier: 15.2.0-canary.2 + specifier: 15.2.0-canary.3 version: link:../eslint-plugin-next '@rushstack/eslint-patch': specifier: ^1.10.3 @@ -857,7 +857,7 @@ importers: packages/next: dependencies: '@next/env': - specifier: 15.2.0-canary.2 + specifier: 15.2.0-canary.3 version: link:../next-env '@swc/counter': specifier: 0.1.3 @@ -985,19 +985,19 @@ importers: specifier: 1.2.0 version: 1.2.0 '@next/font': - specifier: 15.2.0-canary.2 + specifier: 15.2.0-canary.3 version: link:../font '@next/polyfill-module': - specifier: 15.2.0-canary.2 + specifier: 15.2.0-canary.3 version: link:../next-polyfill-module '@next/polyfill-nomodule': - specifier: 15.2.0-canary.2 + specifier: 15.2.0-canary.3 version: link:../next-polyfill-nomodule '@next/react-refresh-utils': - specifier: 15.2.0-canary.2 + specifier: 15.2.0-canary.3 version: link:../react-refresh-utils '@next/swc': - specifier: 15.2.0-canary.2 + specifier: 15.2.0-canary.3 version: link:../next-swc '@opentelemetry/api': specifier: 1.6.0 @@ -1661,7 +1661,7 @@ importers: version: 1.0.20 devDependencies: next: - specifier: 15.2.0-canary.2 + specifier: 15.2.0-canary.3 version: link:../next outdent: specifier: 0.8.0 diff --git a/test/development/acceptance-app/ReactRefreshRequire.test.ts b/test/development/acceptance-app/ReactRefreshRequire.test.ts index 467dc5b6c27fc..16b1e1121d708 100644 --- a/test/development/acceptance-app/ReactRefreshRequire.test.ts +++ b/test/development/acceptance-app/ReactRefreshRequire.test.ts @@ -42,8 +42,6 @@ describe('ReactRefreshRequire app', () => { // We only edited Bar, and it accepted. // So we expect it to re-run alone. await session.evaluate(() => ((window as any).log = [])) - expect(await session.evaluate(() => (window as any).log)).toEqual([]) - await session.patch( './bar.js', `window.log.push('init BarV2'); export default function Bar() { return null; };` @@ -55,8 +53,6 @@ describe('ReactRefreshRequire app', () => { // We only edited Bar, and it accepted. // So we expect it to re-run alone. await session.evaluate(() => ((window as any).log = [])) - expect(await session.evaluate(() => (window as any).log)).toEqual([]) - await session.patch( './bar.js', `window.log.push('init BarV3'); export default function Bar() { return null; };` diff --git a/test/integration/css/test/css-compilation.test.js b/test/integration/css/test/css-compilation.test.js index effef08e4e037..dc383a710628f 100644 --- a/test/integration/css/test/css-compilation.test.js +++ b/test/integration/css/test/css-compilation.test.js @@ -87,7 +87,7 @@ module.exports = { ) } else if (useLightningcss) { expect(cssContentWithoutSourceMap).toMatchInlineSnapshot( - `"@media (min-width:480px) and (max-width:767.999px){::placeholder{color:green}}.flex-parsing{flex:0 0 calc(50% - var(--vertical-gutter))}.transform-parsing{transform:translate3d(0,0)}.css-grid-shorthand{grid-column:span 2}.g-docs-sidenav .filter::-webkit-input-placeholder{opacity:.8}"` + `"@media (min-width:480px) and (not (min-width:768px)){::placeholder{color:green}}.flex-parsing{flex:0 0 calc(50% - var(--vertical-gutter))}.transform-parsing{transform:translate3d(0,0)}.css-grid-shorthand{grid-column:span 2}.g-docs-sidenav .filter::-webkit-input-placeholder{opacity:.8}"` ) } else { expect(cssContentWithoutSourceMap).toMatchInlineSnapshot( @@ -234,37 +234,37 @@ module.exports = { `) } else if (useLightningcss) { expect(sourceMapContentParsed).toMatchInlineSnapshot(` - { - "mappings": "AAAA,mDACE,cACE,WACF,CACF,CAEA,cACE,2CACF,CAEA,mBACE,0BACF,CAEA,oBACE,kBACF,CAEA,mDACE,UACF", - "names": [], - "sourceRoot": "", - "sourcesContent": [ - "@media (min-width: 480px) and (max-width: 767.999px) { - ::placeholder { - color: green; - } - } - - .flex-parsing { - flex: 0 0 calc(50% - var(--vertical-gutter)); - } - - .transform-parsing { - transform: translate3d(0px, 0px); - } - - .css-grid-shorthand { - grid-column: span 2; - } - - .g-docs-sidenav .filter::-webkit-input-placeholder { - opacity: .8; - } - - ", - ], - "version": 3, - } + { + "mappings": "AAAA,qDACE,cACE,WACF,CACF,CAEA,cACE,2CACF,CAEA,mBACE,0BACF,CAEA,oBACE,kBACF,CAEA,mDACE,UACF", + "names": [], + "sourceRoot": "", + "sourcesContent": [ + "@media (min-width: 480px) and (not (min-width: 768px)) { + ::placeholder { + color: green; + } + } + + .flex-parsing { + flex: 0 0 calc(50% - var(--vertical-gutter)); + } + + .transform-parsing { + transform: translate3d(0px, 0px); + } + + .css-grid-shorthand { + grid-column: span 2; + } + + .g-docs-sidenav .filter::-webkit-input-placeholder { + opacity: .8; + } + + ", + ], + "version": 3, + } `) } else { expect(sourceMapContentParsed).toMatchInlineSnapshot(` @@ -549,19 +549,19 @@ module.exports = { if (process.env.TURBOPACK && useLightningcss) { expect(cssContent.replace(/\/\*.*?\*\//g, '').trim()) .toMatchInlineSnapshot(` -".other{color:#00f} + ".other{color:#00f} -.test{color:red}" -`) + .test{color:red}" + `) } else if (process.env.TURBOPACK && !useLightningcss) { expect(cssContent.replace(/\/\*.*?\*\//g, '').trim()) .toMatchInlineSnapshot(` -".other{color:#00f} + ".other{color:#00f} -.test{color:red}" -`) + .test{color:red}" + `) } else if (useLightningcss) { expect( cssContent.replace(/\/\*.*?\*\//g, '').trim() diff --git a/test/turbopack-dev-tests-manifest.json b/test/turbopack-dev-tests-manifest.json index c9f60b7ca914a..fffce66e89d68 100644 --- a/test/turbopack-dev-tests-manifest.json +++ b/test/turbopack-dev-tests-manifest.json @@ -1661,13 +1661,13 @@ "ReactRefreshRequire app provides fresh value for ES6 named import in parents", "ReactRefreshRequire app provides fresh value for exports.* in parents", "ReactRefreshRequire app provides fresh value for module.exports in parents", - "ReactRefreshRequire app re-runs accepted modules", "ReactRefreshRequire app runs dependencies before dependents", "ReactRefreshRequire app stops update propagation after module-level errors" ], "failed": [], "pending": [ - "ReactRefreshRequire app propagates a module that stops accepting in next version" + "ReactRefreshRequire app propagates a module that stops accepting in next version", + "ReactRefreshRequire app re-runs accepted modules" ], "flakey": [], "runtimeError": false diff --git a/turbopack/crates/turbopack-core/src/introspect/module.rs b/turbopack/crates/turbopack-core/src/introspect/module.rs index 2875d9bc0f52d..b4b2401a80e52 100644 --- a/turbopack/crates/turbopack-core/src/introspect/module.rs +++ b/turbopack/crates/turbopack-core/src/introspect/module.rs @@ -1,6 +1,6 @@ use anyhow::Result; use turbo_rcstr::RcStr; -use turbo_tasks::{ValueToString, Vc}; +use turbo_tasks::{ResolvedVc, ValueToString, Vc}; use super::{ utils::{children_from_module_references, content_to_details}, @@ -8,16 +8,16 @@ use super::{ }; use crate::{asset::Asset, module::Module}; -#[turbo_tasks::value(local)] -pub struct IntrospectableModule(Vc>); +#[turbo_tasks::value] +pub struct IntrospectableModule(ResolvedVc>); #[turbo_tasks::value_impl] impl IntrospectableModule { #[turbo_tasks::function] - pub async fn new(asset: Vc>) -> Result>> { - Ok(Vc::try_resolve_sidecast::>(asset) + pub async fn new(asset: ResolvedVc>) -> Result>> { + Ok(*ResolvedVc::try_sidecast::>(asset) .await? - .unwrap_or_else(|| Vc::upcast(IntrospectableModule(asset).cell()))) + .unwrap_or_else(|| ResolvedVc::upcast(IntrospectableModule(asset).resolved_cell()))) } } diff --git a/turbopack/crates/turbopack-core/src/introspect/source.rs b/turbopack/crates/turbopack-core/src/introspect/source.rs index 687c09a91de4b..456013615ffc5 100644 --- a/turbopack/crates/turbopack-core/src/introspect/source.rs +++ b/turbopack/crates/turbopack-core/src/introspect/source.rs @@ -1,20 +1,20 @@ use anyhow::Result; use turbo_rcstr::RcStr; -use turbo_tasks::{ValueToString, Vc}; +use turbo_tasks::{ResolvedVc, ValueToString, Vc}; use super::{utils::content_to_details, Introspectable}; use crate::{asset::Asset, source::Source}; -#[turbo_tasks::value(local)] -pub struct IntrospectableSource(Vc>); +#[turbo_tasks::value] +pub struct IntrospectableSource(ResolvedVc>); #[turbo_tasks::value_impl] impl IntrospectableSource { #[turbo_tasks::function] - pub async fn new(asset: Vc>) -> Result>> { - Ok(Vc::try_resolve_sidecast::>(asset) + pub async fn new(asset: ResolvedVc>) -> Result>> { + Ok(*ResolvedVc::try_sidecast::>(asset) .await? - .unwrap_or_else(|| Vc::upcast(IntrospectableSource(asset).cell()))) + .unwrap_or_else(|| ResolvedVc::upcast(IntrospectableSource(asset).resolved_cell()))) } }