Skip to content

Commit

Permalink
feat(nextjs): allow withNx to be used with other executors such as ru…
Browse files Browse the repository at this point in the history
…n-commands (#17819)
  • Loading branch information
jaysoo authored Jun 27, 2023
1 parent 836cd34 commit 77ca8d7
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 63 deletions.
26 changes: 20 additions & 6 deletions e2e/next/src/next.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -296,7 +296,7 @@ describe('Next.js Applications', () => {
await killPorts();
}, 300_000);

it('should support custom next.config.js and output it in dist', async () => {
it('should support custom webpack and run-commands using withNx', async () => {
const appName = uniq('app');

runCLI(
Expand All @@ -306,7 +306,7 @@ describe('Next.js Applications', () => {
updateFile(
`apps/${appName}/next.config.js`,
`
const { withNx } = require('@nx/next/plugins/with-nx');
const { withNx } = require('@nx/next');
const nextConfig = {
nx: {
svgr: false,
Expand Down Expand Up @@ -341,18 +341,32 @@ describe('Next.js Applications', () => {
updateFile(
`apps/${appName}/next.config.js`,
`
const { withNx } = require('@nx/next/plugins/with-nx');
const { withNx } = require('@nx/next');
// Not including "nx" entry should still work.
const nextConfig = {};
module.exports = withNx(nextConfig);
`
);

rmDist();
runCLI(`build ${appName}`);

checkFilesExist(`dist/apps/${appName}/next.config.js`);

// Make sure withNx works with run-commands.
updateProjectConfig(appName, (json) => {
json.targets.build = {
command: 'npx next build',
outputs: [`apps/${appName}/.next`],
options: {
cwd: `apps/${appName}`,
},
};
return json;
});
expect(() => {
runCLI(`build ${appName}`);
}).not.toThrow();
checkFilesExist(`apps/${appName}/.next/build-manifest.json`);
}, 300_000);

it('should support --js flag', async () => {
Expand Down Expand Up @@ -421,7 +435,7 @@ describe('Next.js Applications', () => {
checkUnitTest: false,
checkLint: false,
checkE2E: false,
checkExport: true,
checkExport: false,
});
}, 300_000);

Expand Down
95 changes: 38 additions & 57 deletions packages/next/plugins/with-nx.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
* WARNING: Do not add development dependencies to top-level imports.
* Instead, `require` them inline during the build phase.
*/
import * as path from 'path';
import type { NextConfig } from 'next';
import type { NextConfigFn } from '../src/utils/config';
import type { NextBuildBuilderOptions } from '../src/utils/types';
Expand Down Expand Up @@ -44,21 +43,6 @@ function getWithNxContext(): WithNxContext {
};
}

function getTargetConfig(graph: ProjectGraph, target: Target) {
const projectNode = graph.nodes[target.project];
return projectNode.data.targets[target.target];
}

function getOptions(graph: ProjectGraph, target: Target) {
const targetConfig = getTargetConfig(graph, target);
const options = targetConfig.options;
if (target.configuration) {
Object.assign(options, targetConfig.configurations[target.configuration]);
}

return options;
}

function getNxContext(
graph: ProjectGraph,
target: Target
Expand All @@ -70,46 +54,39 @@ function getNxContext(
configurationName?: string;
} {
const { parseTargetString } = require('@nx/devkit');
const targetConfig = getTargetConfig(graph, target);

if (
'@nx/next:build' === targetConfig.executor ||
'@nrwl/next:build' === targetConfig.executor
) {
return {
node: graph.nodes[target.project],
options: getOptions(graph, target),
projectName: target.project,
targetName: target.target,
configurationName: target.configuration,
};
const projectNode = graph.nodes[target.project];
const targetConfig = projectNode.data.targets[target.target];
const targetOptions = targetConfig.options;
if (target.configuration) {
Object.assign(
targetOptions,
targetConfig.configurations[target.configuration]
);
}

const targetOptions = getOptions(graph, target);

// If we are running serve or export pull the options from the dependent target first (ex. build)
if (targetOptions.devServerTarget) {
const devServerTarget = parseTargetString(
targetOptions.devServerTarget,
graph
// Executors such as @nx/cypress:cypress define the devServerTarget option.
return getNxContext(
graph,
parseTargetString(targetOptions.devServerTarget, graph)
);

return getNxContext(graph, devServerTarget);
} else if (
[
'@nx/next:server',
'@nx/next:export',
'@nrwl/next:server',
'@nrwl/next:export',
].includes(targetConfig.executor)
) {
const buildTarget = parseTargetString(targetOptions.buildTarget, graph);
return getNxContext(graph, buildTarget);
} else {
throw new Error(
'Could not determine the config for this Next application.'
} else if (targetOptions.buildTarget) {
// Executors such as @nx/next:server or @nx/next:export define the buildTarget option.
return getNxContext(
graph,
parseTargetString(targetOptions.buildTarget, graph)
);
}

// Default case, return info for current target.
// This could be a build using @nx/next:build or run-commands without using our executors.
return {
node: graph.nodes[target.project],
options: targetOptions,
projectName: target.project,
targetName: target.target,
configurationName: target.configuration,
};
}

/**
Expand Down Expand Up @@ -194,13 +171,17 @@ function withNx(
}
});

const outputDir = `${offsetFromRoot(projectDirectory)}${
options.outputPath
}`;
nextConfig.distDir =
nextConfig.distDir && nextConfig.distDir !== '.next'
? joinPathFragments(outputDir, nextConfig.distDir)
: joinPathFragments(outputDir, '.next');
// outputPath may be undefined if using run-commands or other executors other than @nx/next:build.
// In this case, the user should set distDir in their next.config.js.
if (options.outputPath) {
const outputDir = `${offsetFromRoot(projectDirectory)}${
options.outputPath
}`;
nextConfig.distDir =
nextConfig.distDir && nextConfig.distDir !== '.next'
? joinPathFragments(outputDir, nextConfig.distDir)
: joinPathFragments(outputDir, '.next');
}

const userWebpackConfig = nextConfig.webpack;

Expand Down

1 comment on commit 77ca8d7

@vercel
Copy link

@vercel vercel bot commented on 77ca8d7 Jun 27, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

nx-dev – ./

nx-dev-git-master-nrwl.vercel.app
nx-five.vercel.app
nx-dev-nrwl.vercel.app
nx.dev

Please sign in to comment.