Skip to content

Commit 42b1c40

Browse files
authored
Turbopack build: Fix type: module with output: standalone (#79292)
## What? This PR ensures we first clean the `.next/standalone` folder before writing into it. Currently the order is: 1. Write package.json to `.next/standalone/package.json` 1. Delete `.next/standalone` 1. Check `.nft.json` files and write the files listed there to `.next/standalone` Which in turn causes the package.json to not exist. So why does this not fail with webpack? Well, what I found is that the `_app` `.nft.json` file somehow lists the project root `package.json` even though it does not use it. This means that after we delete `.next/standalone` the `package.json` will still end up in the eventual directory regardless. It fails with Turbopack because Turbopack correctly does not include the package.json (as it's not used) and then the `package.json` is missing at runtime, causing the `server.js` which uses ESM to fail (because the detection for ESM is still valid regardless of deleting the folder). New order is: 1. Delete `.next/standalone` 1. Write package.json to `.next/standalone/package.json` 1. Check `.nft.json` files and write the files listed there to `.next/standalone`
1 parent f270834 commit 42b1c40

File tree

6 files changed

+23
-29
lines changed

6 files changed

+23
-29
lines changed

packages/next/src/build/utils.ts

+4-1
Original file line numberDiff line numberDiff line change
@@ -1539,6 +1539,10 @@ export async function copyTracedFiles(
15391539
staticPages: Set<string>
15401540
) {
15411541
const outputPath = path.join(distDir, 'standalone')
1542+
1543+
// Clean up standalone directory first.
1544+
await fs.rm(outputPath, { recursive: true, force: true })
1545+
15421546
let moduleType = false
15431547
const nextConfig = {
15441548
...serverConfig,
@@ -1561,7 +1565,6 @@ export async function copyTracedFiles(
15611565
await fs.writeFile(packageJsonOutputPath, packageJsonContent)
15621566
} catch {}
15631567
const copiedFiles = new Set()
1564-
await fs.rm(outputPath, { recursive: true, force: true })
15651568

15661569
async function handleTraceFiles(traceFilePath: string) {
15671570
const traceData = JSON.parse(await fs.readFile(traceFilePath, 'utf8')) as {

test/production/standalone-mode/type-module/index.test.ts

+8-26
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
import { createNext } from 'e2e-utils'
2-
import { NextInstance } from 'e2e-utils'
1+
import { nextTestSetup } from 'e2e-utils'
32
import { join } from 'path'
43
import fs from 'fs-extra'
54
import {
@@ -10,38 +9,21 @@ import {
109
} from 'next-test-utils'
1110

1211
describe('type-module', () => {
13-
let next: NextInstance
14-
15-
beforeAll(async () => {
16-
next = await createNext({
17-
files: {
18-
'pages/index.js': `
19-
export default function Page() {
20-
return <p>hello world</p>
21-
}
22-
`,
23-
'next.config.mjs': `export default ${JSON.stringify({
24-
output: 'standalone',
25-
})}`,
26-
},
27-
packageJson: { type: 'module' },
28-
})
29-
await next.stop()
12+
const { next } = nextTestSetup({
13+
files: __dirname,
14+
packageJson: {
15+
type: 'module',
16+
},
3017
})
3118

32-
afterAll(() => next.destroy())
33-
3419
it('should work', async () => {
20+
await next.stop()
3521
const standalonePath = join(next.testDir, '.next/standalone')
36-
const staticSrc = join(next.testDir, '.next/static')
37-
38-
const staticDest = join(standalonePath, '.next/static')
39-
40-
await fs.move(staticSrc, staticDest)
4122

4223
expect(fs.existsSync(join(standalonePath, 'package.json'))).toBe(true)
4324

4425
const serverFile = join(standalonePath, 'server.js')
26+
4527
const appPort = await findPort()
4628
const server = await initNextServerScript(
4729
serverFile,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export default {
2+
output: 'standalone',
3+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"type": "module"
3+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export default function Page() {
2+
return <p>hello world</p>
3+
}

test/turbopack-build-tests-manifest.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -19583,8 +19583,8 @@
1958319583
"runtimeError": false
1958419584
},
1958519585
"test/production/standalone-mode/type-module/index.test.ts": {
19586-
"passed": [],
19587-
"failed": ["type-module should work"],
19586+
"passed": ["type-module should work"],
19587+
"failed": [],
1958819588
"pending": [],
1958919589
"flakey": [],
1959019590
"runtimeError": false

0 commit comments

Comments
 (0)