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 #
97 lines
2.4 KiB
TypeScript
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}`,
|
|
});
|
|
}
|
|
);
|
|
}
|