blob: b3bb55047bd01bf5e5360317607e6982971aeec7 [file] [log] [blame]
import { join, dirname } from 'node:path'
import { rmSync, existsSync } from 'node:fs'
const bazelPackage = process.env['BAZEL_PACKAGE']
if (!process.cwd().endsWith(bazelPackage)) {
throw new Error('This script must be run from Next.js app root')
}
let nextjsStandaloneConfig = process.env['NEXTJS_STANDALONE_CONFIG']
if (nextjsStandaloneConfig.startsWith(process.env.BAZEL_BINDIR)) {
nextjsStandaloneConfig = nextjsStandaloneConfig.slice(
process.env.BAZEL_BINDIR.length + 1
)
}
if (!nextjsStandaloneConfig.startsWith(bazelPackage)) {
throw new Error(
`Next.js config must be relative to the app root: ${nextjsStandaloneConfig}`
)
}
const NEXTJS_OUTDIR = '.next'
log(`Wrapping config: ${nextjsStandaloneConfig}`)
log(`Output dir: ${NEXTJS_OUTDIR}`)
/**
* NextJs within bazel copies node_modules symlinks pointing into .aspect_rules_js within the sandbox.
* Clear all `standalone/node_modules` and assume the bazel rule will include the necessary npm packages.
*/
function nextjsFixSymlinks() {
for (let p = process.env['BAZEL_PACKAGE']; ; p = dirname(p)) {
const d = join(NEXTJS_OUTDIR, 'standalone', p, 'node_modules')
if (existsSync(d)) {
log(`Removing ${d}`)
try {
rmSync(join(NEXTJS_OUTDIR, 'standalone', p, 'node_modules'), {
recursive: true,
force: true,
})
} catch (e) {
// node_modules won't exist at every level, and multiple nextjs node processes
// might all be trying to remove it at the same time.
}
}
if (p === '' || p === '.') {
break
}
}
}
function log(...args) {
console.log(`[NextJs Bazel (${process.pid})]: `, ...args)
}
// Run the symlinks fixes on exit.
process.on('exit', nextjsFixSymlinks)
const nextjsStandaloneConfigRel = nextjsStandaloneConfig.slice(
bazelPackage.length + 1
)
const c = await import(`./${nextjsStandaloneConfigRel}`)
export default c.default || c