Skip to content

Commit

Permalink
feat(nextjs): Use next.js cli for build and serve targets
Browse files Browse the repository at this point in the history
  • Loading branch information
ndcunningham authored and jaysoo committed May 15, 2023
1 parent b8e9f3d commit 72c7adf
Show file tree
Hide file tree
Showing 15 changed files with 168 additions and 128 deletions.
11 changes: 9 additions & 2 deletions docs/generated/packages/next/executors/build.json
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,15 @@
},
"debug": {
"type": "boolean",
"description": "Enable Next.js debug build logging",
"default": false
"description": "Enable Next.js debug build logging"
},
"profile": {
"type": "boolean",
"description": "Used to enable React Production Profiling"
},
"experimentalAppOnly": {
"type": "boolean",
"description": "Only build 'app' routes"
}
},
"required": ["root", "outputPath"],
Expand Down
1 change: 1 addition & 0 deletions docs/generated/packages/next/executors/export.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
"presets": []
},
"description": "Export a Next.js application. The exported application is located at `dist/$outputPath/exported`.",
"x-deprecated": "Use static exports in next.config.js instead. See: https://nextjs.org/docs/pages/building-your-application/deploying/static-exports.",
"aliases": [],
"hidden": false,
"path": "/packages/next/src/executors/export/schema.json",
Expand Down
4 changes: 4 additions & 0 deletions docs/generated/packages/next/executors/server.json
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,10 @@
"type": "boolean",
"description": "Read buildable libraries from source instead of building them separately.",
"default": true
},
"keepAliveTimeout": {
"type": "number",
"description": "Max milliseconds to wait before closing inactive connection."
}
},
"required": ["buildTarget"],
Expand Down
6 changes: 4 additions & 2 deletions packages/next/executors.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@
"export": {
"implementation": "./src/executors/export/export.impl",
"schema": "./src/executors/export/schema.json",
"description": "Export a Next.js application. The exported application is located at `dist/$outputPath/exported`."
"description": "Export a Next.js application. The exported application is located at `dist/$outputPath/exported`.",
"x-deprecated": "Use static exports in next.config.js instead. See: https://nextjs.org/docs/pages/building-your-application/deploying/static-exports."
}
},
"builders": {
Expand All @@ -30,7 +31,8 @@
"export": {
"implementation": "./src/executors/export/compat",
"schema": "./src/executors/export/schema.json",
"description": "Export a Next.js application. The exported application is located at `dist/$outputPath/exported`."
"description": "Export a Next.js application. The exported application is located at `dist/$outputPath/exported`.",
"x-deprecated": "Use static exports in next.config.js instead. See: https://nextjs.org/docs/pages/building-your-application/deploying/static-exports."
}
}
}
2 changes: 1 addition & 1 deletion packages/next/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
"migrations": "./migrations.json"
},
"peerDependencies": {
"next": "^13.0.0"
"next": ">=13.0.0"
},
"dependencies": {
"@babel/plugin-proposal-decorators": "^7.14.5",
Expand Down
9 changes: 0 additions & 9 deletions packages/next/plugins/with-nx.ts
Original file line number Diff line number Diff line change
Expand Up @@ -153,15 +153,6 @@ function withNx(
_nextConfig = {} as WithNxOptions,
context: WithNxContext = getWithNxContext()
): NextConfigFn {
// If this is not set user will see compile errors in Next.js 13.4.
// See: https://github.com/nrwl/nx/issues/16692, https://github.com/vercel/next.js/issues/49169
// TODO(jack): Remove this once Nx is refactored to invoke CLI directly.
forNextVersion('>=13.4.0', () => {
process.env['__NEXT_PRIVATE_PREBUNDLED_REACT'] =
// Not in Next 13.3 or earlier, so need to access config via string
_nextConfig.experimental?.['serverActions'] ? 'experimental' : 'next';
});

return async (phase: string) => {
const { PHASE_PRODUCTION_SERVER } = await import('next/constants');
if (phase === PHASE_PRODUCTION_SERVER) {
Expand Down
30 changes: 17 additions & 13 deletions packages/next/src/executors/build/build.impl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ import {
readJsonFile,
workspaceRoot,
writeJsonFile,
logger,
} from '@nx/devkit';
import { createLockFile, createPackageJson, getLockFileName } from '@nx/js';
import build from 'next/dist/build';
import { join, resolve } from 'path';
import { copySync, existsSync, mkdir, writeFileSync } from 'fs-extra';
import { lt, gte } from 'semver';
Expand All @@ -17,6 +17,8 @@ import { updatePackageJson } from './lib/update-package-json';
import { createNextConfigFile } from './lib/create-next-config-file';
import { checkPublicDirectory } from './lib/check-project';
import { NextBuildBuilderOptions } from '../../utils/types';
import { ExecSyncOptions, execSync } from 'child_process';
import { createCliOptions } from '../../utils/create-cli-options';

export default async function buildExecutor(
options: NextBuildBuilderOptions,
Expand Down Expand Up @@ -45,19 +47,21 @@ export default async function buildExecutor(
(process.env as any).__NEXT_REACT_ROOT ||= 'true';
}

// Get the installed Next.js version (will be removed after Nx 16 and Next.js update)
const nextVersion = require('next/package.json').version;
const { experimentalAppOnly, profile, debug } = options;

const debug = !!process.env.NX_VERBOSE_LOGGING || options.debug;

// Check the major and minor version numbers
if (lt(nextVersion, '13.2.0')) {
// If the version is lower than 13.2.0, use the second parameter as the config object
await build(root, null, false, debug);
} else {
// Otherwise, use the third parameter as a boolean flag for verbose logging
// @ts-ignore
await build(root, false, debug);
const args = createCliOptions({ experimentalAppOnly, profile, debug });
const command = `npx next build ${args}`;
const execSyncOptions: ExecSyncOptions = {
stdio: 'inherit',
encoding: 'utf-8',
cwd: root,
};
try {
execSync(command, execSyncOptions);
} catch (error) {
logger.error(`Error occurred while trying to run the ${command}`);
logger.error(error);
return { success: false };
}

if (!directoryExists(options.outputPath)) {
Expand Down
11 changes: 9 additions & 2 deletions packages/next/src/executors/build/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,15 @@
},
"debug": {
"type": "boolean",
"description": "Enable Next.js debug build logging",
"default": false
"description": "Enable Next.js debug build logging"
},
"profile": {
"type": "boolean",
"description": "Used to enable React Production Profiling"
},
"experimentalAppOnly": {
"type": "boolean",
"description": "Only build 'app' routes"
}
},
"required": ["root", "outputPath"]
Expand Down
15 changes: 13 additions & 2 deletions packages/next/src/executors/export/export.impl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import {
NextBuildBuilderOptions,
NextExportBuilderOptions,
} from '../../utils/types';
import { PHASE_EXPORT } from '../../utils/constants';

import nextTrace = require('next/dist/trace');
import { platform } from 'os';
import { execFileSync } from 'child_process';
Expand All @@ -25,6 +25,18 @@ import * as chalk from 'chalk';
// platform specific command name
const pmCmd = platform() === 'win32' ? `npx.cmd` : 'npx';

/**
* @deprecated use output inside of your next.config.js
* Example
* const nextConfig = {
nx: {
svgr: false,
},
output: 'export'
};
* Read https://nextjs.org/docs/pages/building-your-application/deploying/static-exports
**/
export default async function exportExecutor(
options: NextExportBuilderOptions,
context: ExecutorContext
Expand All @@ -41,7 +53,6 @@ export default async function exportExecutor(
dependencies = result.dependencies;
}

const libsDir = join(context.root, workspaceLayout().libsDir);
const buildTarget = parseTargetString(
options.buildTarget,
context.projectGraph
Expand Down
67 changes: 67 additions & 0 deletions packages/next/src/executors/server/custom-server.impl.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import 'dotenv/config';
import {
ExecutorContext,
parseTargetString,
readTargetOptions,
runExecutor,
} from '@nx/devkit';
import { join, resolve } from 'path';

import {
NextBuildBuilderOptions,
NextServeBuilderOptions,
} from '../../utils/types';

export default async function* serveExecutor(
options: NextServeBuilderOptions,
context: ExecutorContext
) {
// Cast to any to overwrite NODE_ENV
(process.env as any).NODE_ENV = process.env.NODE_ENV
? process.env.NODE_ENV
: options.dev
? 'development'
: 'production';

// Setting port that the custom server should use.
(process.env as any).PORT = options.port;

const buildOptions = readTargetOptions<NextBuildBuilderOptions>(
parseTargetString(options.buildTarget, context.projectGraph),
context
);
const root = resolve(context.root, buildOptions.root);

yield* runCustomServer(root, options, context);
}

async function* runCustomServer(
root: string,
options: NextServeBuilderOptions,
context: ExecutorContext
) {
process.env.NX_NEXT_DIR = root;
process.env.NX_NEXT_PUBLIC_DIR = join(root, 'public');

const baseUrl = `http://${options.hostname || 'localhost'}:${options.port}`;

const customServerBuild = await runExecutor(
parseTargetString(options.customServerTarget, context.projectGraph),
{
watch: options.dev ? true : false,
},
context
);

for await (const result of customServerBuild) {
if (!result.success) {
return result;
}
yield {
success: true,
baseUrl,
};
}

return { success: true };
}
4 changes: 4 additions & 0 deletions packages/next/src/executors/server/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,10 @@
"type": "boolean",
"description": "Read buildable libraries from source instead of building them separately.",
"default": true
},
"keepAliveTimeout": {
"type": "number",
"description": "Max milliseconds to wait before closing inactive connection."
}
},
"required": ["buildTarget"]
Expand Down
Loading

0 comments on commit 72c7adf

Please sign in to comment.