nx/packages/angular/src/generators/remote/lib/update-ssr-setup.ts
Colum Ferry 2143ea5e30
fix(angular): set up host and remote ssr apps correctly #29442 (#29447)
## Current Behavior
During the update to support Angular 19, the host and remote generators'
`updateSsrSetup` function was missed.

This led to the creation of a second `server.ts` file, which would
result in the node server trying to instantiate twice.

## Expected Behavior
Fix the path normalization dependent on angular major version to ensure
only one server will be instantiated.

## Related Issue(s)

Fixes #29442
2024-12-20 13:40:40 +00:00

143 lines
3.4 KiB
TypeScript

import type { Tree } from '@nx/devkit';
import {
addDependenciesToPackageJson,
generateFiles,
joinPathFragments,
readProjectConfiguration,
updateProjectConfiguration,
} from '@nx/devkit';
import { join } from 'path';
import {
corsVersion,
moduleFederationNodeVersion,
typesCorsVersion,
} from '../../../utils/versions';
import { getInstalledAngularVersionInfo } from '../../utils/version-utils';
export async function updateSsrSetup(
tree: Tree,
{
appName,
port,
standalone,
typescriptConfiguration,
skipPackageJson,
}: {
appName: string;
port: number;
standalone: boolean;
typescriptConfiguration: boolean;
skipPackageJson?: boolean;
}
) {
const { major: angularMajorVersion } = getInstalledAngularVersionInfo(tree);
let project = readProjectConfiguration(tree, appName);
tree.rename(
joinPathFragments(project.sourceRoot, 'main.server.ts'),
joinPathFragments(project.sourceRoot, 'bootstrap.server.ts')
);
const pathToServerEntry = joinPathFragments(
angularMajorVersion >= 19
? project.sourceRoot ?? joinPathFragments(project.root, 'src')
: project.root,
'server.ts'
);
tree.write(
pathToServerEntry,
`import('./${angularMajorVersion >= 19 ? '' : 'src/'}main.server');`
);
const browserBundleOutput = project.targets.build.options.outputPath;
const serverBundleOutput = project.targets.build.options.outputPath.replace(
/\/browser$/,
'/server'
);
generateFiles(tree, join(__dirname, '../files/common'), project.root, {
appName,
browserBundleOutput,
serverBundleOutput,
standalone,
commonEngineEntryPoint:
angularMajorVersion >= 19 ? '@angular/ssr/node' : '@angular/ssr',
tmpl: '',
});
const pathToTemplateFiles = typescriptConfiguration ? 'base-ts' : 'base';
generateFiles(
tree,
joinPathFragments(__dirname, `../files/${pathToTemplateFiles}`),
project.root,
{
tmpl: '',
}
);
if (standalone) {
generateFiles(
tree,
joinPathFragments(__dirname, '../files/standalone'),
project.root,
{
appName,
standalone,
tmpl: '',
}
);
}
// update project.json
project = readProjectConfiguration(tree, appName);
project.targets.server.executor = '@nx/angular:webpack-server';
project.targets.server.options.customWebpackConfig = {
path: joinPathFragments(
project.root,
`webpack.server.config.${typescriptConfiguration ? 'ts' : 'js'}`
),
};
if (
project.targets.server.configurations &&
project.targets.server.configurations.development
) {
if ('vendorChunk' in project.targets.server.configurations.development) {
delete project.targets.server.configurations.development.vendorChunk;
}
}
project.targets['serve-ssr'].options = {
...(project.targets['serve-ssr'].options ?? {}),
port,
};
project.targets['static-server'] = {
dependsOn: ['build', 'server'],
executor: 'nx:run-commands',
options: {
command: `PORT=${port} node ${joinPathFragments(
project.targets.server.options.outputPath,
'main.js'
)}`,
},
};
updateProjectConfiguration(tree, appName, project);
if (!skipPackageJson) {
return addDependenciesToPackageJson(
tree,
{
cors: corsVersion,
'@module-federation/node': moduleFederationNodeVersion,
},
{
'@types/cors': typesCorsVersion,
}
);
}
return () => {};
}