Jason Jean 23bebd91e7
feat(devkit): bump compatibility to Nx 19 - 21.x (#28243)
BREAKING CHANGE

<!-- Please make sure you have read the submission guidelines before
posting an PR -->
<!--
https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr
-->

<!-- Please make sure that your commit message follows our format -->
<!-- Example: `fix(nx): must begin with lowercase` -->

<!-- If this is a particularly complex change or feature addition, you
can request a dedicated Nx release for this pull request branch. Mention
someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they
will confirm if the PR warrants its own release for testing purposes,
and generate it for you if appropriate. -->

## Current Behavior
<!-- This is the behavior we have today -->

* `@nx/devkit` supports Nx 17 - 20.
* Node 18 - 22 is supported 
* `ExecutorContext.projectGraph`, `ExecutorContext.nxJsonConfiguration`,
and `ExecutorContext.projectsConfigurations` is marked as optional
because `ExecutorContext` in some versions of Nx did not have them.
* `ExecutorContext.workspace` is marked as optional because
`ExecutorContext` in some versions of Nx did not have the above
properties which contain the same information.
* `ProjectGraphNode` is deprecated.
* `NxPluginV1.processProjectGraph` was deprecated long ago and there has
been a warning since.
* `appRootPath` has been deprecated for a long time.
* `parseTargetString` had a variant that did not take either the project
graph or the executor context.
* `readNxJson` has a variant which does not take a tree. This was not
clearly deprecated.
* There are handlers to require from `@nx/` instead of `@nrwl`
* Nx tries to get a root install from `@nrwl/cli`


## Expected Behavior
<!-- This is the behavior we should expect with the changes in this PR
-->

* `@nx/devkit` supports Nx 19 - 21.
* Node 20 - 22 is supported 
* `ExecutorContext.projectGraph`, `ExecutorContext.nxJsonConfiguration`,
and `ExecutorContext.projectsConfigurations` is marked as required
because `ExecutorContext` in Nx 19+ is guaranteed to have them.
* `ExecutorContext.workspace` is removed because the same information is
available in the above properties
* `ProjectGraphNode` is removed.
* `NxPluginV1` is no more. All plugins should be `NxPluginV2`.
* `workspaceRoot` is the replacement for `appRootPath`. `appRootPath` is
removed.
* `parseTargetString` no longer has a variant that did not take either
the project graph or the executor context.
* `readNxJson` still has a variant which does not take a tree but it's
clearly deprecated to be removed in Nx 21.
* `@nrwl` packages are no more so we don't have to redirect requires
anymore.
* `@nrwl/cli` is no more so Nx shouldn't try to get a root install there
* 

## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->

Fixes #
2024-10-03 17:35:47 -04:00

97 lines
2.4 KiB
TypeScript

import { workspaceRoot, type ExecutorContext } from '@nx/devkit';
import { createAsyncIterable } from '@nx/devkit/src/utils/async-iterable';
import { waitForPortOpen } from '@nx/web/src/utils/wait-for-port-open';
import { fork } from 'node:child_process';
import { join } from 'node:path';
import { type RemixServeSchema } from './schema';
function normalizeOptions(schema: RemixServeSchema) {
return {
...schema,
port: schema.port ?? 4200,
debug: schema.debug ?? false,
manual: schema.manual ?? false,
} as RemixServeSchema;
}
function buildRemixDevArgs(options: RemixServeSchema) {
const args = [];
if (options.command) {
args.push(`--command=${options.command}`);
}
if (options.devServerPort) {
args.push(`--port=${options.devServerPort}`);
}
if (options.debug) {
args.push(`--debug`);
}
if (options.manual) {
args.push(`--manual`);
}
if (options.tlsKey) {
args.push(`--tls-key=${options.tlsKey}`);
}
if (options.tlsCert) {
args.push(`--tls-cert=${options.tlsCert}`);
}
return args;
}
export default async function* serveExecutor(
schema: RemixServeSchema,
context: ExecutorContext
) {
const options = normalizeOptions(schema);
const projectRoot =
context.projectsConfigurations.projects[context.projectName].root;
const remixBin = require.resolve('@remix-run/dev/dist/cli');
const args = buildRemixDevArgs(options);
// Cast to any to overwrite NODE_ENV
(process.env as any).NODE_ENV = process.env.NODE_ENV
? process.env.NODE_ENV
: 'development';
process.env.PORT = `${options.port}`;
yield* createAsyncIterable<{ success: boolean; baseUrl: string }>(
async ({ done, next, error }) => {
const server = fork(remixBin, ['dev', ...args], {
cwd: join(workspaceRoot, projectRoot),
stdio: 'inherit',
});
server.once('exit', (code) => {
if (code === 0) {
done();
} else {
error(new Error(`Remix 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 waitForPortOpen(options.port);
next({
success: true,
baseUrl: `http://localhost:${options.port}`,
});
}
);
}