UNPKG

@nx/next

Version:

The Next.js plugin for Nx contains executors and generators for managing Next.js applications and libraries within an Nx workspace. It provides: - Scaffolding for creating, building, serving, linting, and testing Next.js applications. - Integration wit

114 lines (113 loc) 5.15 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = serveExecutor; const devkit_1 = require("@nx/devkit"); const path_1 = require("path"); const child_process_1 = require("child_process"); const custom_server_impl_1 = require("./custom-server.impl"); const create_cli_options_1 = require("../../utils/create-cli-options"); const async_iterable_1 = require("@nx/devkit/src/utils/async-iterable"); const wait_for_port_open_1 = require("@nx/web/src/utils/wait-for-port-open"); const runtime_version_utils_1 = require("../../utils/runtime-version-utils"); async function* serveExecutor(options, context) { const buildOptions = (0, devkit_1.readTargetOptions)((0, devkit_1.parseTargetString)(options.buildTarget, context), context); const projectRoot = context.projectsConfigurations.projects[context.projectName].root; // This is required for the default custom server to work. See the @nx/next:app generator. const nextDir = !options.dev && (0, path_1.resolve)(context.root, buildOptions.outputPath); process.env.NX_NEXT_DIR ??= options.dev ? projectRoot : nextDir; if (options.customServerTarget) { return yield* (0, custom_server_impl_1.default)(options, context); } const { keepAliveTimeout, hostname } = options; // Cast to any to overwrite NODE_ENV process.env.NODE_ENV = process.env.NODE_ENV ? process.env.NODE_ENV : options.dev ? 'development' : 'production'; // Setting port that the custom server should use. process.env.PORT = options.port ? `${options.port}` : process.env.PORT; options.port = parseInt(process.env.PORT); const args = (0, create_cli_options_1.createCliOptions)({ port: options.port, hostname }); if (keepAliveTimeout && !options.dev) { args.push(`--keepAliveTimeout=${keepAliveTimeout}`); } const mode = options.dev ? 'dev' : 'start'; // Determine bundler flag based on Next.js version and options let bundlerFlag = ''; if (options.dev) { // Check for conflicting flags if (options.turbo && options.webpack) { throw new Error('Cannot specify both --turbo and --webpack flags. Please use only one bundler option.'); } const nextJsVersion = (0, runtime_version_utils_1.getInstalledNextVersionRuntime)(); const isNext16Plus = nextJsVersion !== null && nextJsVersion >= 16; if (isNext16Plus) { // Next.js 16+: Turbopack is default, use --webpack to opt-in to webpack if (options.webpack) { bundlerFlag = '--webpack'; devkit_1.logger.info('Using webpack bundler (Next.js 16+ detected)'); } else if (options.turbo) { devkit_1.logger.warn('The --turbo flag is redundant in Next.js 16+ as Turbopack is now the default bundler. You can remove this flag.'); } } else { // Next.js 15 and below: webpack is default, use --turbo to opt-in to turbopack if (options.turbo) { bundlerFlag = '--turbo'; } else if (options.webpack) { devkit_1.logger.warn('The --webpack flag is only applicable in Next.js 16 and above. It will be ignored.'); } } } const nextBin = require.resolve('next/dist/bin/next'); yield* (0, async_iterable_1.createAsyncIterable)(async ({ done, next, error }) => { const server = (0, child_process_1.fork)(nextBin, [ mode, ...args, bundlerFlag, ...getExperimentalHttpsFlags(options), ].filter((arg) => arg !== ''), { cwd: options.dev ? projectRoot : nextDir, stdio: 'inherit', }); server.once('exit', (code) => { if (code === 0) { done(); } else { error(new Error(`Next.js app exited with code ${code}`)); } }); const killServer = () => { if (server.connected) { server.kill('SIGTERM'); } }; process.on('exit', () => killServer()); process.on('SIGINT', () => killServer()); process.on('SIGTERM', () => killServer()); process.on('SIGHUP', () => killServer()); await (0, wait_for_port_open_1.waitForPortOpen)(options.port, { host: options.hostname }); next({ success: true, baseUrl: `http://${options.hostname ?? 'localhost'}:${options.port}`, }); }); } function getExperimentalHttpsFlags(options) { if (!options.dev) return []; const flags = []; if (options.experimentalHttps) flags.push('--experimental-https'); if (options.experimentalHttpsKey) flags.push(`--experimental-https-key=${options.experimentalHttpsKey}`); if (options.experimentalHttpsCert) flags.push(`--experimental-https-cert=${options.experimentalHttpsCert}`); if (options.experimentalHttpsCa) flags.push(`--experimental-https-ca=${options.experimentalHttpsCa}`); return flags; }