Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .github/actions/next-stats-action/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,9 @@ if (!allowedActions.has(actionInfo.actionName) && !actionInfo.isRelease) {
usePnpm
? // --no-frozen-lockfile is used here to tolerate lockfile
// changes from merging latest changes
` && pnpm install --no-frozen-lockfile`
// --package-import-method=copy avoids EXDEV hardlink failures
// on self-hosted runners where pnpm store/workdirs cross devices.
` && pnpm install --no-frozen-lockfile --package-import-method=copy`
: ' && yarn install --network-timeout 1000000'
}`,
{ env: { PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: '1' } }
Expand Down
2 changes: 1 addition & 1 deletion .github/actions/next-stats-action/src/run/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -296,7 +296,7 @@ async function linkPkgs(pkgDir = '', pkgPaths) {
await fs.writeFile(pkgJsonPath, JSON.stringify(pkgData, null, 2), 'utf8')

await exec(
`cd ${pkgDir} && pnpm install --strict-peer-dependencies=false`,
`cd ${pkgDir} && pnpm install --strict-peer-dependencies=false --package-import-method=copy`,
false
)
}
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/build_reusable.yml
Original file line number Diff line number Diff line change
Expand Up @@ -322,7 +322,7 @@ jobs:
# Jest has a global cache, so PRs that poison the cache can bring down CI
- name: Clean up stray files
if: ${{ always() }}
run: rm -f /tmp/package-lock.json .jest-cache
run: rm -f /tmp/package-lock.json

- name: Upload artifact
uses: actions/upload-artifact@v4
Expand Down
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,6 @@ test-timings.json
*.tsbuildinfo
.swc/
.turbo
.jest-cache/

# Storybook
*storybook.log
Expand Down
5 changes: 0 additions & 5 deletions jest.config.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
const path = require('path')
const nextJest = require('next/jest')

const createJestConfig = nextJest()
Expand Down Expand Up @@ -28,10 +27,6 @@ const customJestConfig = {
},
}

if (process.env.CI) {
customJestConfig.cacheDirectory = path.join(__dirname, '.jest-cache')
}

// Check if the environment variable is set to enable test report,
// Insert a reporter to generate a junit report to upload.
//
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ function createFlightRouterStateFromLoaderTreeImpl(

let childHasLoadingBoundary = false
const children: FlightRouterState[1] = {}
Object.keys(parallelRoutes).forEach((parallelRouteKey) => {
for (const parallelRouteKey in parallelRoutes) {
const child = createFlightRouterStateFromLoaderTreeImpl(
parallelRoutes[parallelRouteKey],
getDynamicParamFromSegment,
Expand All @@ -45,7 +45,7 @@ function createFlightRouterStateFromLoaderTreeImpl(
childHasLoadingBoundary = true
}
children[parallelRouteKey] = child
})
}
segmentTree[1] = children

if (includeHasLoadingBoundary) {
Expand Down
74 changes: 50 additions & 24 deletions packages/next/src/server/load-manifest.external.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,22 +30,36 @@ export function loadManifest<T extends object>(
): DeepReadonly<T>
export function loadManifest<T extends object>(
path: string,
shouldCache?: true,
shouldCache?: boolean,
cache?: Map<string, unknown>,
skipParse?: boolean
skipParse?: boolean,
handleMissing?: boolean
): DeepReadonly<T>
export function loadManifest<T extends object>(
path: string,
shouldCache: boolean = true,
cache = sharedCache,
skipParse = false
skipParse = false,
handleMissing?: boolean
): T {
const cached = shouldCache && cache.get(path)
if (cached) {
return cached as T
}

let manifest: any = readFileSync(/* turbopackIgnore: true */ path, 'utf8')
let manifest: any

if (handleMissing) {
try {
manifest = readFileSync(/* turbopackIgnore: true */ path, 'utf8')
} catch (err) {
let result = {} as any
cache.set(path, result)
return result
}
} else {
manifest = readFileSync(/* turbopackIgnore: true */ path, 'utf8')
}

if (!skipParse) {
manifest = JSON.parse(manifest)
Expand All @@ -70,7 +84,8 @@ export function evalManifest<T extends object>(
export function evalManifest<T extends object>(
path: string,
shouldCache?: boolean,
cache?: Map<string, unknown>
cache?: Map<string, unknown>,
handleMissing?: boolean
): DeepReadonly<T>
export function evalManifest<T extends object>(
path: string,
Expand All @@ -80,14 +95,27 @@ export function evalManifest<T extends object>(
export function evalManifest<T extends object>(
path: string,
shouldCache: boolean = true,
cache = sharedCache
cache = sharedCache,
handleMissing?: boolean
): T {
const cached = shouldCache && cache.get(path)
if (cached) {
return cached as T
}

const content = readFileSync(/* turbopackIgnore: true */ path, 'utf8')
let content: any
if (handleMissing) {
try {
content = readFileSync(/* turbopackIgnore: true */ path, 'utf8')
} catch (err) {
let result = {} as any
cache.set(path, result)
return result
}
} else {
content = readFileSync(/* turbopackIgnore: true */ path, 'utf8')
}

if (content.length === 0) {
throw new Error('Manifest file is empty')
}
Expand Down Expand Up @@ -128,24 +156,22 @@ export function loadManifestFromRelativePath<T extends object>({
handleMissing?: boolean
useEval?: boolean
}): DeepReadonly<T> {
try {
const manifestPath = join(
/* turbopackIgnore: true */ projectDir,
distDir,
manifest
)

if (useEval) {
return evalManifest<T>(manifestPath, shouldCache, cache)
}
return loadManifest<T>(manifestPath, shouldCache, cache, skipParse)
} catch (err) {
if (handleMissing) {
// TODO: should this be undefined
return {} as DeepReadonly<T>
}
throw err
const manifestPath = join(
/* turbopackIgnore: true */ projectDir,
distDir,
manifest
)

if (useEval) {
return evalManifest<T>(manifestPath, shouldCache, cache, handleMissing)
}
return loadManifest<T>(
manifestPath,
shouldCache,
cache,
skipParse,
handleMissing
)
}

export function clearManifestCache(path: string, cache = sharedCache): boolean {
Expand Down
9 changes: 9 additions & 0 deletions run-tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -497,6 +497,7 @@ ${ENDGROUP}`)
...(process.env.CI ? ['--ci'] : []),
'--runInBand',
'--forceExit',
'--no-cache',
'--verbose',
...(isTestJob
? ['--json', `--outputFile=${test.file}${RESULTS_EXT}`]
Expand All @@ -509,6 +510,7 @@ ${ENDGROUP}`)
`^(?!(?:${test.excludedCases.map(escapeRegexp).join('|')})$).`,
]),
]
const deferNextTestWasm = !!process.env.NEXT_TEST_WASM
const env = {
// run tests in headless mode by default
HEADLESS: 'true',
Expand Down Expand Up @@ -547,6 +549,13 @@ ${ENDGROUP}`)
.filter(Boolean)
.join(':'),
}),
...(deferNextTestWasm
? {
// Let Next/Jest initialize native SWC for the transformer first.
NEXT_TEST_WASM: undefined,
NEXT_TEST_WASM_AFTER_JEST: process.env.NEXT_TEST_WASM,
}
: {}),
...(isFinalRun
? {
// Events can be finicky in CI. This switches to a more
Expand Down
11 changes: 7 additions & 4 deletions test/lib/e2e-utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,12 @@ export const isNextDeploy = testMode === 'deploy'
*/
export const isNextStart = !isNextDev && !isNextDeploy

if (!process.env.NEXT_TEST_WASM && process.env.NEXT_TEST_WASM_AFTER_JEST) {
process.env.NEXT_TEST_WASM = process.env.NEXT_TEST_WASM_AFTER_JEST
}

export const isRspack = !!process.env.NEXT_RSPACK
const isNextTestWasm = !!process.env.NEXT_TEST_WASM

if (!testMode) {
throw new Error(
Expand Down Expand Up @@ -230,7 +235,7 @@ export async function createNext(

setupTracing()
return await trace('createNext').traceAsyncFn(async (rootSpan) => {
const useTurbo = !!process.env.NEXT_TEST_WASM
const useTurbo = isNextTestWasm
? false
: (opts?.turbo ?? shouldUseTurbopack())

Expand Down Expand Up @@ -363,9 +368,7 @@ export function nextTestSetup(
return isNextStart
},
get isTurbopack() {
return Boolean(
!process.env.NEXT_TEST_WASM && (options.turbo ?? shouldUseTurbopack())
)
return Boolean(!isNextTestWasm && (options.turbo ?? shouldUseTurbopack()))
},
get isRspack() {
return isRspack
Expand Down
5 changes: 5 additions & 0 deletions test/lib/next-modes/base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,11 @@ export class NextInstance {
constructor(opts: NextInstanceOpts) {
this.env = {}
Object.assign(this, opts)
const nextTestWasm =
process.env.NEXT_TEST_WASM ?? process.env.NEXT_TEST_WASM_AFTER_JEST
if (nextTestWasm) {
this.env.NEXT_TEST_WASM = nextTestWasm
}

if (!isNextDeploy) {
this.env = {
Expand Down
1 change: 1 addition & 0 deletions test/lib/next-modes/next-dev.ts
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ export class NextDevInstance extends NextInstance {

const useTurbo =
!process.env.NEXT_TEST_WASM &&
!process.env.NEXT_TEST_WASM_AFTER_JEST &&
((this as any).turbo || (this as any).experimentalTurbo)

let startArgs = [
Expand Down
2 changes: 1 addition & 1 deletion test/lib/turbo.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
let loggedTurbopack = false

export function shouldUseTurbopack(): boolean {
if (!!process.env.NEXT_TEST_WASM) {
if (!!process.env.NEXT_TEST_WASM || !!process.env.NEXT_TEST_WASM_AFTER_JEST) {
return false
}

Expand Down
2 changes: 1 addition & 1 deletion test/production/pages-dir/production/test/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import { nextTestSetup } from 'e2e-utils'

const glob = promisify(globOriginal)

if (process.env.NEXT_TEST_WASM) {
if (process.env.NEXT_TEST_WASM || process.env.NEXT_TEST_WASM_AFTER_JEST) {
jest.setTimeout(120 * 1000)
}

Expand Down
Loading
Loading