nx/packages/react/src/migrations/update-19-6-0/update-ssr-server-port.spec.ts
Colum Ferry 7351a1a25e
feat(react): add rspack module federation support (#27696)
- feat(react): add remote rspack module federation support
- feat(react): add host rspack module federation support
- feat(react): add federate module rspack module federation support
- fix(react): migration test

<!-- 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 -->
We do not have an option to generate a react host and remote with rspack


## Expected Behavior
<!-- This is the behavior we should expect with the changes in this PR
-->
Add rspack as an option when generating host and remote

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

Fixes #
2024-09-06 09:54:27 -04:00

207 lines
6.2 KiB
TypeScript

import { readProjectConfiguration, type Tree } from '@nx/devkit';
import { createTreeWithEmptyWorkspace } from 'nx/src/devkit-testing-exports';
import hostGenerator from '../../generators/host/host';
import { Linter } from '@nx/eslint';
import updateSsrServerPort from './update-ssr-server-port';
describe('update-19-6-0 update-ssr-server-port migration', () => {
let tree: Tree;
beforeEach(() => {
tree = createTreeWithEmptyWorkspace();
});
it('should update host and remote port server files', async () => {
await hostGenerator(tree, {
name: 'shell',
e2eTestRunner: 'none',
unitTestRunner: 'none',
ssr: true,
linter: Linter.EsLint,
projectNameAndRootFormat: 'as-provided',
style: 'css',
remotes: ['product'],
bundler: 'webpack',
});
const remotePort = readProjectConfiguration(tree, 'product').targets.serve
.options.port;
const shellPort = readProjectConfiguration(tree, 'shell').targets.serve
.options.port;
// This should already exists in the generated project
tree.write(
'product/server.ts',
tree
.read('product/server.ts', 'utf-8')
.replace('const port = 4201;', `const port = process.env.PORT || 4200;`)
);
updateSsrServerPort(tree);
expect(tree.read('product/server.ts', 'utf-8')).toContain(
`port = process.env['PORT'] || ${remotePort}`
);
expect(tree.read('product/server.ts', 'utf-8')).toMatchInlineSnapshot(`
"import * as path from 'path';
import express from 'express';
import cors from 'cors';
import { handleRequest } from './src/main.server';
const port = process.env['PORT'] || 4201;
const app = express();
const browserDist = path.join(process.cwd(), 'dist/product/browser');
const serverDist = path.join(process.cwd(), 'dist/product/server');
const indexPath = path.join(browserDist, 'index.html');
app.use(cors());
// Client-side static bundles
app.get(
'*.*',
express.static(browserDist, {
maxAge: '1y',
})
);
// Static bundles for server-side module federation
app.use(
'/server',
express.static(serverDist, {
maxAge: '1y',
})
);
app.use('*', handleRequest(indexPath));
const server = app.listen(port, () => {
console.log(\`Express server listening on http://localhost:\${port}\`);
/**
* DO NOT REMOVE IF USING @nx/react:module-federation-dev-ssr executor
* to serve your Host application with this Remote application.
* This message allows Nx to determine when the Remote is ready to be
* consumed by the Host.
*/
process.send?.('nx.server.ready');
});
server.on('error', console.error);
"
`);
tree.write(
'shell/server.ts',
tree
.read('shell/server.ts', 'utf-8')
.replace(
'const port = 4200;',
`const port = process.env['PORT'] || 4200;`
)
);
updateSsrServerPort(tree);
expect(tree.read('shell/server.ts', 'utf-8')).toContain(
`port = process.env.PORT || ${shellPort}`
);
expect(tree.read('shell/server.ts', 'utf-8')).toMatchInlineSnapshot(`
"import * as path from 'path';
import express from 'express';
import cors from 'cors';
import { handleRequest } from './src/main.server';
const port = process.env.PORT || 4200;
const app = express();
const browserDist = path.join(process.cwd(), 'dist/shell/browser');
const indexPath = path.join(browserDist, 'index.html');
app.use(cors());
app.get('*.*', express.static(browserDist, {
maxAge: '1y',
}));
app.use('*', handleRequest(indexPath));
const server = app.listen(port, () => {
console.log(\`Express server listening on http://localhost:\${port}\`);
});
server.on('error', console.error);
"
`);
});
it('should update a host project server file', async () => {
await hostGenerator(tree, {
name: 'host',
e2eTestRunner: 'none',
unitTestRunner: 'none',
ssr: true,
linter: Linter.EsLint,
projectNameAndRootFormat: 'as-provided',
style: 'css',
bundler: 'webpack',
});
const hostPort = readProjectConfiguration(tree, 'host').targets.serve
.options.port;
tree.write(
'host/server.ts',
tree
.read('host/server.ts', 'utf-8')
.replace(
'const port = 4200;',
`const port = process.env['PORT'] || 4200;`
)
);
updateSsrServerPort(tree);
expect(tree.read('host/server.ts', 'utf-8')).toContain(
`port = process.env.PORT || ${hostPort}`
);
expect(tree.read('host/server.ts', 'utf-8')).toMatchInlineSnapshot(`
"import * as path from 'path';
import express from 'express';
import cors from 'cors';
import { handleRequest } from './src/main.server';
const port = process.env.PORT || 4200;
const app = express();
const browserDist = path.join(process.cwd(), 'dist/host/browser');
const indexPath = path.join(browserDist, 'index.html');
app.use(cors());
app.get('*.*', express.static(browserDist, {
maxAge: '1y',
}));
app.use('*', handleRequest(indexPath));
const server = app.listen(port, () => {
console.log(\`Express server listening on http://localhost:\${port}\`);
});
server.on('error', console.error);
"
`);
});
it('should not update a mfe project that is not ssr', async () => {
await hostGenerator(tree, {
name: 'shell-not-ssr',
e2eTestRunner: 'none',
unitTestRunner: 'none',
ssr: false,
linter: Linter.EsLint,
projectNameAndRootFormat: 'as-provided',
style: 'css',
bundler: 'webpack',
});
tree.write('shell-not-ssr/server.ts', 'const port = 9999;');
const shellPort = readProjectConfiguration(tree, 'shell-not-ssr').targets
.serve.options.port;
updateSsrServerPort(tree);
expect(tree.read('shell-not-ssr/server.ts', 'utf-8')).not.toContain(
`port = ${shellPort}`
);
expect(tree.read('shell-not-ssr/server.ts', 'utf-8')).toMatchInlineSnapshot(
`"const port = 9999;"`
);
});
});