diff --git a/.eslintrc.js b/.eslintrc.js index 2c9ad7a4c925..cd2489589e3f 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -468,6 +468,7 @@ module.exports = { files: ['packages/react-server-dom-webpack/**/*.js'], globals: { __webpack_chunk_load__: 'readonly', + __webpack_get_script_filename__: 'readonly', __webpack_require__: 'readonly', }, }, diff --git a/compiler/scripts/release/shared/packages.js b/compiler/scripts/release/shared/packages.js index 39970bdde6c3..235ba0f1ddb5 100644 --- a/compiler/scripts/release/shared/packages.js +++ b/compiler/scripts/release/shared/packages.js @@ -7,7 +7,6 @@ const PUBLISHABLE_PACKAGES = [ 'babel-plugin-react-compiler', - 'eslint-plugin-react-compiler', 'react-compiler-healthcheck', 'react-compiler-runtime', ]; diff --git a/packages/react-client/src/ReactFlightClient.js b/packages/react-client/src/ReactFlightClient.js index c4d47bfecc55..2eef555d36f8 100644 --- a/packages/react-client/src/ReactFlightClient.js +++ b/packages/react-client/src/ReactFlightClient.js @@ -55,6 +55,7 @@ import { resolveServerReference, preloadModule, requireModule, + getModuleDebugInfo, dispatchHint, readPartialStringChunk, readFinalStringChunk, @@ -790,8 +791,14 @@ function resolveModuleChunk( resolvedChunk.status = RESOLVED_MODULE; resolvedChunk.value = value; if (__DEV__) { - // We don't expect to have any debug info for this row. - resolvedChunk._debugInfo = null; + const debugInfo = getModuleDebugInfo(value); + if (debugInfo !== null && resolvedChunk._debugInfo != null) { + // Add to the live set if it was already initialized. + // $FlowFixMe[method-unbinding] + resolvedChunk._debugInfo.push.apply(resolvedChunk._debugInfo, debugInfo); + } else { + resolvedChunk._debugInfo = debugInfo; + } } if (resolveListeners !== null) { initializeModuleChunk(resolvedChunk); @@ -3977,7 +3984,11 @@ function flushComponentPerformance( // Track the root most component of the result for deduping logging. result.component = componentInfo; isLastComponent = false; - } else if (candidateInfo.awaited) { + } else if ( + candidateInfo.awaited && + // Skip awaits on client resources since they didn't block the server component. + candidateInfo.awaited.env != null + ) { if (endTime > childrenEndTime) { childrenEndTime = endTime; } @@ -4059,7 +4070,11 @@ function flushComponentPerformance( // Track the root most component of the result for deduping logging. result.component = componentInfo; isLastComponent = false; - } else if (candidateInfo.awaited) { + } else if ( + candidateInfo.awaited && + // Skip awaits on client resources since they didn't block the server component. + candidateInfo.awaited.env != null + ) { // If we don't have an end time for an await, that means we aborted. const asyncInfo: ReactAsyncInfo = candidateInfo; const env = response._rootEnvironmentName; diff --git a/packages/react-client/src/forks/ReactFlightClientConfig.custom.js b/packages/react-client/src/forks/ReactFlightClientConfig.custom.js index 2f204fd51b09..a6c0c933d2a5 100644 --- a/packages/react-client/src/forks/ReactFlightClientConfig.custom.js +++ b/packages/react-client/src/forks/ReactFlightClientConfig.custom.js @@ -35,6 +35,7 @@ export const resolveClientReference = $$$config.resolveClientReference; export const resolveServerReference = $$$config.resolveServerReference; export const preloadModule = $$$config.preloadModule; export const requireModule = $$$config.requireModule; +export const getModuleDebugInfo = $$$config.getModuleDebugInfo; export const dispatchHint = $$$config.dispatchHint; export const prepareDestinationForModule = $$$config.prepareDestinationForModule; diff --git a/packages/react-client/src/forks/ReactFlightClientConfig.dom-bun.js b/packages/react-client/src/forks/ReactFlightClientConfig.dom-bun.js index 75c942966bd9..24caf0df88f5 100644 --- a/packages/react-client/src/forks/ReactFlightClientConfig.dom-bun.js +++ b/packages/react-client/src/forks/ReactFlightClientConfig.dom-bun.js @@ -24,5 +24,6 @@ export const resolveClientReference: any = null; export const resolveServerReference: any = null; export const preloadModule: any = null; export const requireModule: any = null; +export const getModuleDebugInfo: any = null; export const prepareDestinationForModule: any = null; export const usedWithSSR = true; diff --git a/packages/react-client/src/forks/ReactFlightClientConfig.dom-legacy.js b/packages/react-client/src/forks/ReactFlightClientConfig.dom-legacy.js index 5be648ff0ad9..0f7381fc5a3f 100644 --- a/packages/react-client/src/forks/ReactFlightClientConfig.dom-legacy.js +++ b/packages/react-client/src/forks/ReactFlightClientConfig.dom-legacy.js @@ -24,6 +24,7 @@ export const resolveClientReference: any = null; export const resolveServerReference: any = null; export const preloadModule: any = null; export const requireModule: any = null; +export const getModuleDebugInfo: any = null; export const dispatchHint: any = null; export const prepareDestinationForModule: any = null; export const usedWithSSR = true; diff --git a/packages/react-client/src/forks/ReactFlightClientConfig.markup.js b/packages/react-client/src/forks/ReactFlightClientConfig.markup.js index b0b2f198fd97..fcd672450446 100644 --- a/packages/react-client/src/forks/ReactFlightClientConfig.markup.js +++ b/packages/react-client/src/forks/ReactFlightClientConfig.markup.js @@ -62,6 +62,12 @@ export function requireModule(metadata: ClientReference): T { ); } +export function getModuleDebugInfo(metadata: ClientReference): null { + throw new Error( + 'renderToHTML should not have emitted Client References. This is a bug in React.', + ); +} + export const usedWithSSR = true; type HintCode = string; diff --git a/packages/react-server-dom-esm/src/client/ReactFlightClientConfigBundlerESM.js b/packages/react-server-dom-esm/src/client/ReactFlightClientConfigBundlerESM.js index 6a74e6385499..ebd281298331 100644 --- a/packages/react-server-dom-esm/src/client/ReactFlightClientConfigBundlerESM.js +++ b/packages/react-server-dom-esm/src/client/ReactFlightClientConfigBundlerESM.js @@ -11,7 +11,11 @@ import type { Thenable, FulfilledThenable, RejectedThenable, + ReactDebugInfo, + ReactIOInfo, + ReactAsyncInfo, } from 'shared/ReactTypes'; + import type {ModuleLoading} from 'react-client/src/ReactFlightClientConfig'; export type ServerConsumerModuleMap = string; // Module root path @@ -118,3 +122,93 @@ export function requireModule(metadata: ClientReference): T { } return moduleExports[metadata.name]; } + +// We cache ReactIOInfo across requests so that inner refreshes can dedupe with outer. +const moduleIOInfoCache: Map = __DEV__ + ? new Map() + : (null: any); + +export function getModuleDebugInfo( + metadata: ClientReference, +): null | ReactDebugInfo { + if (!__DEV__) { + return null; + } + const filename = metadata.specifier; + let ioInfo = moduleIOInfoCache.get(filename); + if (ioInfo === undefined) { + let href; + try { + // $FlowFixMe + href = new URL(filename, document.baseURI).href; + } catch (_) { + href = filename; + } + let start = -1; + let end = -1; + let byteSize = 0; + // $FlowFixMe[method-unbinding] + if (typeof performance.getEntriesByType === 'function') { + // We may be able to collect the start and end time of this resource from Performance Observer. + const resourceEntries = performance.getEntriesByType('resource'); + for (let i = 0; i < resourceEntries.length; i++) { + const resourceEntry = resourceEntries[i]; + if (resourceEntry.name === href) { + start = resourceEntry.startTime; + end = start + resourceEntry.duration; + // $FlowFixMe[prop-missing] + byteSize = (resourceEntry.transferSize: any) || 0; + } + } + } + const value = Promise.resolve(href); + // $FlowFixMe + value.status = 'fulfilled'; + // Is there some more useful representation for the chunk? + // $FlowFixMe + value.value = href; + // Create a fake stack frame that points to the beginning of the chunk. This is + // probably not source mapped so will link to the compiled source rather than + // any individual file that goes into the chunks. + const fakeStack = new Error('react-stack-top-frame'); + if (fakeStack.stack.startsWith('Error: react-stack-top-frame')) { + // Looks like V8 + fakeStack.stack = + 'Error: react-stack-top-frame\n' + + // Add two frames since we always trim one off the top. + ' at Client Component Bundle (' + + href + + ':1:1)\n' + + ' at Client Component Bundle (' + + href + + ':1:1)'; + } else { + // Looks like Firefox or Safari. + // Add two frames since we always trim one off the top. + fakeStack.stack = + 'Client Component Bundle@' + + href + + ':1:1\n' + + 'Client Component Bundle@' + + href + + ':1:1'; + } + ioInfo = ({ + name: 'script', + start: start, + end: end, + value: value, + debugStack: fakeStack, + }: ReactIOInfo); + if (byteSize > 0) { + // $FlowFixMe[cannot-write] + ioInfo.byteSize = byteSize; + } + moduleIOInfoCache.set(filename, ioInfo); + } + // We could dedupe the async info too but conceptually each request is its own await. + const asyncInfo: ReactAsyncInfo = { + awaited: ioInfo, + }; + return [asyncInfo]; +} diff --git a/packages/react-server-dom-parcel/src/client/ReactFlightClientConfigBundlerParcel.js b/packages/react-server-dom-parcel/src/client/ReactFlightClientConfigBundlerParcel.js index 1d380a305910..6c652c93c22d 100644 --- a/packages/react-server-dom-parcel/src/client/ReactFlightClientConfigBundlerParcel.js +++ b/packages/react-server-dom-parcel/src/client/ReactFlightClientConfigBundlerParcel.js @@ -7,7 +7,7 @@ * @flow */ -import type {Thenable} from 'shared/ReactTypes'; +import type {Thenable, ReactDebugInfo} from 'shared/ReactTypes'; import type {ImportMetadata} from '../shared/ReactFlightImportMetadata'; @@ -80,3 +80,10 @@ export function requireModule(metadata: ClientReference): T { const moduleExports = parcelRequire(metadata[ID]); return moduleExports[metadata[NAME]]; } + +export function getModuleDebugInfo( + metadata: ClientReference, +): null | ReactDebugInfo { + // TODO + return null; +} diff --git a/packages/react-server-dom-turbopack/src/client/ReactFlightClientConfigBundlerTurbopack.js b/packages/react-server-dom-turbopack/src/client/ReactFlightClientConfigBundlerTurbopack.js index fa20f032e054..ba1c220fa4f3 100644 --- a/packages/react-server-dom-turbopack/src/client/ReactFlightClientConfigBundlerTurbopack.js +++ b/packages/react-server-dom-turbopack/src/client/ReactFlightClientConfigBundlerTurbopack.js @@ -11,6 +11,7 @@ import type { Thenable, FulfilledThenable, RejectedThenable, + ReactDebugInfo, } from 'shared/ReactTypes'; import type { @@ -28,7 +29,10 @@ import { import {prepareDestinationWithChunks} from 'react-client/src/ReactFlightClientConfig'; -import {loadChunk} from 'react-client/src/ReactFlightClientConfig'; +import { + loadChunk, + addChunkDebugInfo, +} from 'react-client/src/ReactFlightClientConfig'; export type ServerConsumerModuleMap = null | { [clientId: string]: { @@ -231,3 +235,19 @@ export function requireModule(metadata: ClientReference): T { } return moduleExports[metadata[NAME]]; } + +export function getModuleDebugInfo( + metadata: ClientReference, +): null | ReactDebugInfo { + if (!__DEV__) { + return null; + } + const chunks = metadata[CHUNKS]; + const debugInfo: ReactDebugInfo = []; + let i = 0; + while (i < chunks.length) { + const chunkFilename = chunks[i++]; + addChunkDebugInfo(debugInfo, chunkFilename); + } + return debugInfo; +} diff --git a/packages/react-server-dom-turbopack/src/client/ReactFlightClientConfigBundlerTurbopackBrowser.js b/packages/react-server-dom-turbopack/src/client/ReactFlightClientConfigBundlerTurbopackBrowser.js index 59aab436cbc2..b00fe3cb06f0 100644 --- a/packages/react-server-dom-turbopack/src/client/ReactFlightClientConfigBundlerTurbopackBrowser.js +++ b/packages/react-server-dom-turbopack/src/client/ReactFlightClientConfigBundlerTurbopackBrowser.js @@ -7,6 +7,102 @@ * @flow */ +import type { + ReactDebugInfo, + ReactIOInfo, + ReactAsyncInfo, +} from 'shared/ReactTypes'; + export function loadChunk(filename: string): Promise { return __turbopack_load_by_url__(filename); } + +// We cache ReactIOInfo across requests so that inner refreshes can dedupe with outer. +const chunkIOInfoCache: Map = __DEV__ + ? new Map() + : (null: any); + +export function addChunkDebugInfo( + target: ReactDebugInfo, + filename: string, +): void { + if (!__DEV__) { + return; + } + let ioInfo = chunkIOInfoCache.get(filename); + if (ioInfo === undefined) { + let href; + try { + // $FlowFixMe + href = new URL(filename, document.baseURI).href; + } catch (_) { + href = filename; + } + let start = -1; + let end = -1; + let byteSize = 0; + // $FlowFixMe[method-unbinding] + if (typeof performance.getEntriesByType === 'function') { + // We may be able to collect the start and end time of this resource from Performance Observer. + const resourceEntries = performance.getEntriesByType('resource'); + for (let i = 0; i < resourceEntries.length; i++) { + const resourceEntry = resourceEntries[i]; + if (resourceEntry.name === href) { + start = resourceEntry.startTime; + end = start + resourceEntry.duration; + // $FlowFixMe[prop-missing] + byteSize = (resourceEntry.transferSize: any) || 0; + } + } + } + const value = Promise.resolve(href); + // $FlowFixMe + value.status = 'fulfilled'; + // Is there some more useful representation for the chunk? + // $FlowFixMe + value.value = href; + // Create a fake stack frame that points to the beginning of the chunk. This is + // probably not source mapped so will link to the compiled source rather than + // any individual file that goes into the chunks. + const fakeStack = new Error('react-stack-top-frame'); + if (fakeStack.stack.startsWith('Error: react-stack-top-frame')) { + // Looks like V8 + fakeStack.stack = + 'Error: react-stack-top-frame\n' + + // Add two frames since we always trim one off the top. + ' at Client Component Bundle (' + + href + + ':1:1)\n' + + ' at Client Component Bundle (' + + href + + ':1:1)'; + } else { + // Looks like Firefox or Safari. + // Add two frames since we always trim one off the top. + fakeStack.stack = + 'Client Component Bundle@' + + href + + ':1:1\n' + + 'Client Component Bundle@' + + href + + ':1:1'; + } + ioInfo = ({ + name: 'script', + start: start, + end: end, + value: value, + debugStack: fakeStack, + }: ReactIOInfo); + if (byteSize > 0) { + // $FlowFixMe[cannot-write] + ioInfo.byteSize = byteSize; + } + chunkIOInfoCache.set(filename, ioInfo); + } + // We could dedupe the async info too but conceptually each request is its own await. + const asyncInfo: ReactAsyncInfo = { + awaited: ioInfo, + }; + target.push(asyncInfo); +} diff --git a/packages/react-server-dom-turbopack/src/client/ReactFlightClientConfigBundlerTurbopackServer.js b/packages/react-server-dom-turbopack/src/client/ReactFlightClientConfigBundlerTurbopackServer.js index 59aab436cbc2..600f80c6fc7a 100644 --- a/packages/react-server-dom-turbopack/src/client/ReactFlightClientConfigBundlerTurbopackServer.js +++ b/packages/react-server-dom-turbopack/src/client/ReactFlightClientConfigBundlerTurbopackServer.js @@ -7,6 +7,16 @@ * @flow */ +import type {ReactDebugInfo} from 'shared/ReactTypes'; + export function loadChunk(filename: string): Promise { return __turbopack_load_by_url__(filename); } + +export function addChunkDebugInfo( + target: ReactDebugInfo, + filename: string, +): void { + // We don't emit any debug info on the server since we assume the loading + // of the bundle is insignificant on the server. +} diff --git a/packages/react-server-dom-webpack/src/__tests__/utils/WebpackMock.js b/packages/react-server-dom-webpack/src/__tests__/utils/WebpackMock.js index 654bcdc9b6d5..5574b069a490 100644 --- a/packages/react-server-dom-webpack/src/__tests__/utils/WebpackMock.js +++ b/packages/react-server-dom-webpack/src/__tests__/utils/WebpackMock.js @@ -27,6 +27,9 @@ global.__webpack_require__ = function (id) { } return webpackClientModules[id] || webpackServerModules[id]; }; +global.__webpack_get_script_filename__ = function (id) { + return id; +}; const previousCompile = Module.prototype._compile; diff --git a/packages/react-server-dom-webpack/src/client/ReactFlightClientConfigBundlerNode.js b/packages/react-server-dom-webpack/src/client/ReactFlightClientConfigBundlerNode.js index e560275cd1fb..de38569e52a5 100644 --- a/packages/react-server-dom-webpack/src/client/ReactFlightClientConfigBundlerNode.js +++ b/packages/react-server-dom-webpack/src/client/ReactFlightClientConfigBundlerNode.js @@ -160,3 +160,9 @@ export function requireModule(metadata: ClientReference): T { } return moduleExports[metadata.name]; } + +export function getModuleDebugInfo(metadata: ClientReference): null { + // We don't emit any debug info on the server since we assume the loading + // of the bundle is insignificant on the server. + return null; +} diff --git a/packages/react-server-dom-webpack/src/client/ReactFlightClientConfigBundlerWebpack.js b/packages/react-server-dom-webpack/src/client/ReactFlightClientConfigBundlerWebpack.js index a43c26ac82bb..550e10eb0082 100644 --- a/packages/react-server-dom-webpack/src/client/ReactFlightClientConfigBundlerWebpack.js +++ b/packages/react-server-dom-webpack/src/client/ReactFlightClientConfigBundlerWebpack.js @@ -11,6 +11,7 @@ import type { Thenable, FulfilledThenable, RejectedThenable, + ReactDebugInfo, } from 'shared/ReactTypes'; import type { @@ -28,7 +29,10 @@ import { import {prepareDestinationWithChunks} from 'react-client/src/ReactFlightClientConfig'; -import {loadChunk} from 'react-client/src/ReactFlightClientConfig'; +import { + loadChunk, + addChunkDebugInfo, +} from 'react-client/src/ReactFlightClientConfig'; export type ServerConsumerModuleMap = null | { [clientId: string]: { @@ -251,3 +255,20 @@ export function requireModule(metadata: ClientReference): T { } return moduleExports[metadata[NAME]]; } + +export function getModuleDebugInfo( + metadata: ClientReference, +): null | ReactDebugInfo { + if (!__DEV__) { + return null; + } + const chunks = metadata[CHUNKS]; + const debugInfo: ReactDebugInfo = []; + let i = 0; + while (i < chunks.length) { + const chunkId = chunks[i++]; + const chunkFilename = chunks[i++]; + addChunkDebugInfo(debugInfo, chunkId, chunkFilename); + } + return debugInfo; +} diff --git a/packages/react-server-dom-webpack/src/client/ReactFlightClientConfigBundlerWebpackBrowser.js b/packages/react-server-dom-webpack/src/client/ReactFlightClientConfigBundlerWebpackBrowser.js index 48779fb1e65e..7f49e9fd15a8 100644 --- a/packages/react-server-dom-webpack/src/client/ReactFlightClientConfigBundlerWebpackBrowser.js +++ b/packages/react-server-dom-webpack/src/client/ReactFlightClientConfigBundlerWebpackBrowser.js @@ -7,6 +7,12 @@ * @flow */ +import type { + ReactDebugInfo, + ReactIOInfo, + ReactAsyncInfo, +} from 'shared/ReactTypes'; + const chunkMap: Map = new Map(); /** @@ -26,3 +32,98 @@ export function loadChunk(chunkId: string, filename: string): Promise { chunkMap.set(chunkId, filename); return __webpack_chunk_load__(chunkId); } + +// We cache ReactIOInfo across requests so that inner refreshes can dedupe with outer. +const chunkIOInfoCache: Map = __DEV__ + ? new Map() + : (null: any); + +export function addChunkDebugInfo( + target: ReactDebugInfo, + chunkId: string, + filename: string, +): void { + if (!__DEV__) { + return; + } + let ioInfo = chunkIOInfoCache.get(chunkId); + if (ioInfo === undefined) { + const scriptFilename = __webpack_get_script_filename__(chunkId); + let href; + try { + // $FlowFixMe + href = new URL(scriptFilename, document.baseURI).href; + } catch (_) { + href = scriptFilename; + } + let start = -1; + let end = -1; + let byteSize = 0; + // $FlowFixMe[method-unbinding] + if (typeof performance.getEntriesByType === 'function') { + // We may be able to collect the start and end time of this resource from Performance Observer. + const resourceEntries = performance.getEntriesByType('resource'); + for (let i = 0; i < resourceEntries.length; i++) { + const resourceEntry = resourceEntries[i]; + if (resourceEntry.name === href) { + start = resourceEntry.startTime; + end = start + resourceEntry.duration; + // $FlowFixMe[prop-missing] + byteSize = (resourceEntry.transferSize: any) || 0; + } + } + } + const value = Promise.resolve(href); + // $FlowFixMe + value.status = 'fulfilled'; + // $FlowFixMe + value.value = { + chunkId: chunkId, + href: href, + // Is there some more useful representation for the chunk? + }; + // Create a fake stack frame that points to the beginning of the chunk. This is + // probably not source mapped so will link to the compiled source rather than + // any individual file that goes into the chunks. + const fakeStack = new Error('react-stack-top-frame'); + if (fakeStack.stack.startsWith('Error: react-stack-top-frame')) { + // Looks like V8 + fakeStack.stack = + 'Error: react-stack-top-frame\n' + + // Add two frames since we always trim one off the top. + ' at Client Component Bundle (' + + href + + ':1:1)\n' + + ' at Client Component Bundle (' + + href + + ':1:1)'; + } else { + // Looks like Firefox or Safari. + // Add two frames since we always trim one off the top. + fakeStack.stack = + 'Client Component Bundle@' + + href + + ':1:1\n' + + 'Client Component Bundle@' + + href + + ':1:1'; + } + ioInfo = ({ + name: 'script', + start: start, + end: end, + value: value, + debugStack: fakeStack, + }: ReactIOInfo); + if (byteSize > 0) { + // $FlowFixMe[cannot-write] + ioInfo.byteSize = byteSize; + } + chunkIOInfoCache.set(chunkId, ioInfo); + } + // We could dedupe the async info too but conceptually each request is its own await. + const asyncInfo: ReactAsyncInfo = { + awaited: ioInfo, + }; + target.push(asyncInfo); +} diff --git a/packages/react-server-dom-webpack/src/client/ReactFlightClientConfigBundlerWebpackServer.js b/packages/react-server-dom-webpack/src/client/ReactFlightClientConfigBundlerWebpackServer.js index 8eeb39a24a3e..7dcbdf3fb2b8 100644 --- a/packages/react-server-dom-webpack/src/client/ReactFlightClientConfigBundlerWebpackServer.js +++ b/packages/react-server-dom-webpack/src/client/ReactFlightClientConfigBundlerWebpackServer.js @@ -7,6 +7,17 @@ * @flow */ +import type {ReactDebugInfo} from 'shared/ReactTypes'; + export function loadChunk(chunkId: string, filename: string): Promise { return __webpack_chunk_load__(chunkId); } + +export function addChunkDebugInfo( + target: ReactDebugInfo, + chunkId: string, + filename: string, +): void { + // We don't emit any debug info on the server since we assume the loading + // of the bundle is insignificant on the server. +} diff --git a/scripts/flow/environment.js b/scripts/flow/environment.js index f52e6fd428e2..823defbd8df2 100644 --- a/scripts/flow/environment.js +++ b/scripts/flow/environment.js @@ -146,6 +146,7 @@ declare module 'EventListener' { } declare function __webpack_chunk_load__(id: string): Promise; +declare function __webpack_get_script_filename__(id: string): string; declare const __webpack_require__: ((id: string) => any) & { u: string => string, }; diff --git a/scripts/rollup/validate/eslintrc.cjs.js b/scripts/rollup/validate/eslintrc.cjs.js index e4cf904e5974..57b9043c9bd9 100644 --- a/scripts/rollup/validate/eslintrc.cjs.js +++ b/scripts/rollup/validate/eslintrc.cjs.js @@ -62,6 +62,7 @@ module.exports = { // Flight Webpack __webpack_chunk_load__: 'readonly', + __webpack_get_script_filename__: 'readonly', __webpack_require__: 'readonly', // Flight Turbopack diff --git a/scripts/rollup/validate/eslintrc.cjs2015.js b/scripts/rollup/validate/eslintrc.cjs2015.js index 4cda9b06a636..c9757ecd8708 100644 --- a/scripts/rollup/validate/eslintrc.cjs2015.js +++ b/scripts/rollup/validate/eslintrc.cjs2015.js @@ -59,6 +59,7 @@ module.exports = { // Flight Webpack __webpack_chunk_load__: 'readonly', + __webpack_get_script_filename__: 'readonly', __webpack_require__: 'readonly', // Flight Turbopack diff --git a/scripts/rollup/validate/eslintrc.esm.js b/scripts/rollup/validate/eslintrc.esm.js index 98fdc56c48c5..26592005311d 100644 --- a/scripts/rollup/validate/eslintrc.esm.js +++ b/scripts/rollup/validate/eslintrc.esm.js @@ -62,6 +62,7 @@ module.exports = { // Flight Webpack __webpack_chunk_load__: 'readonly', + __webpack_get_script_filename__: 'readonly', __webpack_require__: 'readonly', // Flight Turbopack