Skip to content

Commit

Permalink
Fix symlink and copy logic to standalone directory when using `outp…
Browse files Browse the repository at this point in the history
…utStandalone` (#35535)

* fix symlink logic with outputStandalone

* refactored and commented copy function

* faster symlink check

* removed Dockerfile

* removed console.logs from test

* fix symlinksOutsideRoot test

* removed a console.log for files out of root

* added missing types to copy

* removed custom copy function, fix symlink code

* test outputStandalone and pnpm

* appProcess is no more a promise

Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
  • Loading branch information
remorses and kodiakhq[bot] committed Apr 15, 2022
1 parent aaeb349 commit 5a785e4
Show file tree
Hide file tree
Showing 5 changed files with 102 additions and 10 deletions.
5 changes: 1 addition & 4 deletions packages/next/build/utils.ts
Expand Up @@ -1172,10 +1172,7 @@ export async function copyTracedFiles(

if (symlink) {
console.log('symlink', path.relative(tracingRoot, symlink))
await fs.symlink(
path.relative(tracingRoot, symlink),
fileOutputPath
)
await fs.symlink(symlink, fileOutputPath)
} else {
await fs.copyFile(tracedFilePath, fileOutputPath)
}
Expand Down
2 changes: 2 additions & 0 deletions test/integration/pnpm-support/app-multi-page/.npmrc
@@ -0,0 +1,2 @@
# put modules outside of the app folder, to simulate what happens in a pnpm workspace
virtual-store-dir=../pnpm
9 changes: 9 additions & 0 deletions test/integration/pnpm-support/app-multi-page/next.config.js
@@ -0,0 +1,9 @@
const path = require('path')

module.exports = {
experimental: {
outputStandalone: true,
// pnpm virtual-store-dir is outside the app directory
outputFileTracingRoot: path.resolve(__dirname, '../'),
},
}
5 changes: 5 additions & 0 deletions test/integration/pnpm-support/app/next.config.js
@@ -0,0 +1,5 @@
module.exports = {
experimental: {
outputStandalone: true,
},
}
91 changes: 85 additions & 6 deletions test/integration/pnpm-support/test/index.test.js
Expand Up @@ -13,8 +13,33 @@ const APP_DIRS = {
'app-multi-page': path.join(__dirname, '..', 'app-multi-page'),
}

// runs a command showing logs and returning the stdout
const runCommand = (cwd, cmd, args) => {
const proc = execa(cmd, [...args], {
cwd,
stdio: [process.stdin, 'pipe', process.stderr],
})

let stdout = ''
proc.stdout.on('data', (data) => {
const s = data.toString()
process.stdout.write(s)
stdout += s
})
return new Promise((resolve, reject) => {
proc.on('exit', (code) => {
if (code === 0) {
return resolve({ ...proc, stdout })
}
reject(
new Error(`Command ${cmd} ${args.join(' ')} failed with code ${code}`)
)
})
})
}

const runNpm = (cwd, ...args) => execa('npm', [...args], { cwd })
const runPnpm = (cwd, ...args) => execa('npx', ['pnpm', ...args], { cwd })
const runPnpm = (cwd, ...args) => runCommand(cwd, 'npx', ['pnpm', ...args])

async function usingTempDir(fn) {
const folder = path.join(os.tmpdir(), Math.random().toString(36).substring(2))
Expand Down Expand Up @@ -134,24 +159,78 @@ describe('pnpm support', () => {
expect(packageJson.pnpm.overrides[dependency]).toMatch(/^file:/)
}

const { stdout, stderr } = await runPnpm(appDir, 'run', 'build')
console.log(stdout, stderr)
const { stdout } = await runPnpm(appDir, 'run', 'build')

expect(stdout).toMatch(/Compiled successfully/)
})
})

it('should execute client-side JS on each page in outputStandalone', async () => {
await usingPnpmCreateNextApp(APP_DIRS['app-multi-page'], async (appDir) => {
const { stdout } = await runPnpm(appDir, 'run', 'build')

expect(stdout).toMatch(/Compiled successfully/)

let appPort
let appProcess
let browser
try {
appPort = await findPort()
const standaloneDir = path.resolve(appDir, '.next/standalone/app')

// simulate what happens in a Dockerfile
await fs.remove(path.join(appDir, 'node_modules'))
await fs.copy(
path.resolve(appDir, './.next/static'),
path.resolve(standaloneDir, './.next/static'),
{ overwrite: true }
)
appProcess = execa('node', ['server.js'], {
cwd: standaloneDir,
env: {
PORT: appPort,
},
stdio: 'inherit',
})

await waitFor(1000)

await renderViaHTTP(appPort, '/')

browser = await webdriver(appPort, '/', {
waitHydration: false,
})
expect(await browser.waitForElementByCss('#world').text()).toBe('World')
await browser.close()

browser = await webdriver(appPort, '/about', {
waitHydration: false,
})
expect(await browser.waitForElementByCss('#world').text()).toBe('World')
await browser.close()
} finally {
await killProcess(appProcess.pid)
await waitFor(5000)
}
})
})

it('should execute client-side JS on each page', async () => {
await usingPnpmCreateNextApp(APP_DIRS['app-multi-page'], async (appDir) => {
const { stdout, stderr } = await runPnpm(appDir, 'run', 'build')
console.log(stdout, stderr)
const { stdout } = await runPnpm(appDir, 'run', 'build')

expect(stdout).toMatch(/Compiled successfully/)

let appPort
let appProcess
let browser
try {
appPort = await findPort()
appProcess = runPnpm(appDir, 'run', 'start', '--', '--port', appPort)
appProcess = execa('pnpm', ['run', 'start', '--', '--port', appPort], {
cwd: appDir,
stdio: 'inherit',
})

await waitFor(5000)

await renderViaHTTP(appPort, '/')
Expand Down

0 comments on commit 5a785e4

Please sign in to comment.