nx/packages/rspack/src/generators/convert-webpack/convert-webpack.spec.ts
Colum Ferry 76d61ea5e6
feat(module-federation): consolidate module federation utils into module-federation package (#28919)
- feat(module-federation): consolidate module federation utils into
module-federation package
- chore(module-federation): fix tests and linting

<!-- 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 -->
Our current support for Module Federation relies on utilities that are
spread and duplicated across the `@nx/webpack` package and the
`@nx/rspack` package.



## Expected Behavior
<!-- This is the behavior we should expect with the changes in this PR
-->
Now that we have a `@nx/module-federation` package, dedupe the utils and
consolidate them into a single package

## Todo
- [x] Migrations for React + Angular to install `@nx/module-federation`
and point `ModuleFederationConfig` export to that package from
webpack.config and rspack.config files
2024-11-18 14:15:10 -05:00

453 lines
14 KiB
TypeScript

import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing';
import { readProjectConfiguration } from '@nx/devkit';
// nx-ignore-next-line
import { applicationGenerator, hostGenerator } from '@nx/react';
import convertWebpack from './convert-webpack';
describe('Convert webpack', () => {
it('should convert basic webpack project to rspack', async () => {
// ARRANGE
const tree = createTreeWithEmptyWorkspace();
await applicationGenerator(tree, {
directory: 'demo',
bundler: 'webpack',
e2eTestRunner: 'playwright',
linter: 'none',
style: 'css',
addPlugin: false,
});
// ACT
await convertWebpack(tree, { project: 'demo' });
// ASSERT
const project = readProjectConfiguration(tree, 'demo');
expect(tree.exists('demo/rspack.config.js')).toBeTruthy();
expect(tree.read('demo/rspack.config.js', 'utf-8')).toMatchInlineSnapshot(`
"const { withReact } = require('@nx/rspack');
const { withNx } = require('@nx/rspack');
const { composePlugins } = require('@nx/rspack');
// Nx plugins for webpack.
module.exports = composePlugins(
withNx(),
withReact({
// Uncomment this line if you don't want to use SVGR
// See: https://react-svgr.com/
// svgr: false
}),
(config) => {
// Update the webpack config as needed here.
// e.g. \`config.plugins.push(new MyPlugin())\`
return config;
}
);
"
`);
expect(project.targets.build).toMatchInlineSnapshot(`
{
"configurations": {
"development": {
"extractLicenses": false,
"optimization": false,
"sourceMap": true,
"vendorChunk": true,
},
"production": {
"extractLicenses": true,
"fileReplacements": [
{
"replace": "demo/src/environments/environment.ts",
"with": "demo/src/environments/environment.prod.ts",
},
],
"namedChunks": false,
"optimization": true,
"outputHashing": "all",
"sourceMap": false,
"vendorChunk": false,
},
},
"defaultConfiguration": "production",
"executor": "@nx/rspack:rspack",
"options": {
"assets": [
"demo/src/favicon.ico",
"demo/src/assets",
],
"baseHref": "/",
"compiler": "babel",
"index": "demo/src/index.html",
"main": "demo/src/main.tsx",
"outputPath": "dist/demo",
"rspackConfig": "demo/rspack.config.js",
"scripts": [],
"styles": [
"demo/src/styles.css",
],
"target": "web",
"tsConfig": "demo/tsconfig.app.json",
},
"outputs": [
"{options.outputPath}",
],
}
`);
expect(project.targets.serve).toMatchInlineSnapshot(`
{
"configurations": {
"development": {
"buildTarget": "demo:build:development",
},
"production": {
"buildTarget": "demo:build:production",
"hmr": false,
},
},
"defaultConfiguration": "development",
"executor": "@nx/rspack:dev-server",
"options": {
"buildTarget": "demo:build",
"hmr": true,
},
}
`);
});
it('should convert react module federation webpack projects to rspack', async () => {
// ARRANGE
const tree = createTreeWithEmptyWorkspace();
await hostGenerator(tree, {
directory: 'demo',
bundler: 'webpack',
e2eTestRunner: 'playwright',
remotes: ['remote1', 'remote2'],
linter: 'none',
style: 'css',
addPlugin: false,
unitTestRunner: 'none',
typescriptConfiguration: true,
});
// ACT
await convertWebpack(tree, { project: 'demo' });
await convertWebpack(tree, { project: 'remote1' });
await convertWebpack(tree, { project: 'remote2' });
// ASSERT
const project = readProjectConfiguration(tree, 'demo');
expect(tree.exists('demo/rspack.config.ts')).toBeTruthy();
expect(tree.read('demo/rspack.config.ts', 'utf-8')).toMatchInlineSnapshot(`
"import { withModuleFederation } from '@nx/rspack/module-federation';
import { withReact } from '@nx/rspack';
import { withNx } from '@nx/rspack';
import { composePlugins } from '@nx/rspack';
import { ModuleFederationConfig } from '@nx/module-federation';
import baseConfig from './module-federation.config';
const config: ModuleFederationConfig = {
...baseConfig,
};
// Nx plugins for webpack to build config object from Nx options and context.
/**
* DTS Plugin is disabled in Nx Workspaces as Nx already provides Typing support for Module Federation
* The DTS Plugin can be enabled by setting dts: true
* Learn more about the DTS Plugin here: https://module-federation.io/configure/dts.html
*/
export default composePlugins(
withNx(),
withReact(),
withModuleFederation(config, { dts: false })
);
"
`);
expect(project.targets.build).toMatchInlineSnapshot(`
{
"configurations": {
"development": {
"extractLicenses": false,
"optimization": false,
"sourceMap": true,
"vendorChunk": true,
},
"production": {
"extractLicenses": true,
"fileReplacements": [
{
"replace": "demo/src/environments/environment.ts",
"with": "demo/src/environments/environment.prod.ts",
},
],
"namedChunks": false,
"optimization": true,
"outputHashing": "all",
"rspackConfig": "demo/rspack.config.prod.ts",
"sourceMap": false,
"vendorChunk": false,
},
},
"defaultConfiguration": "production",
"executor": "@nx/rspack:rspack",
"options": {
"assets": [
"demo/src/favicon.ico",
"demo/src/assets",
],
"baseHref": "/",
"compiler": "babel",
"index": "demo/src/index.html",
"main": "demo/src/main.ts",
"outputPath": "dist/demo",
"rspackConfig": "demo/rspack.config.ts",
"scripts": [],
"styles": [
"demo/src/styles.css",
],
"target": "web",
"tsConfig": "demo/tsconfig.app.json",
},
"outputs": [
"{options.outputPath}",
],
}
`);
expect(project.targets.serve).toMatchInlineSnapshot(`
{
"configurations": {
"development": {
"buildTarget": "demo:build:development",
},
"production": {
"buildTarget": "demo:build:production",
"hmr": false,
},
},
"defaultConfiguration": "development",
"executor": "@nx/rspack:module-federation-dev-server",
"options": {
"buildTarget": "demo:build",
"hmr": true,
"port": 4200,
},
}
`);
const remote1 = readProjectConfiguration(tree, 'remote1');
expect(tree.exists('remote1/rspack.config.ts')).toBeTruthy();
expect(tree.read('remote1/rspack.config.ts', 'utf-8'))
.toMatchInlineSnapshot(`
"import { withModuleFederation } from '@nx/rspack/module-federation';
import { withReact } from '@nx/rspack';
import { withNx } from '@nx/rspack';
import { composePlugins } from '@nx/rspack';
import baseConfig from './module-federation.config';
const config = {
...baseConfig,
};
// Nx plugins for webpack to build config object from Nx options and context.
/**
* DTS Plugin is disabled in Nx Workspaces as Nx already provides Typing support Module Federation
* The DTS Plugin can be enabled by setting dts: true
* Learn more about the DTS Plugin here: https://module-federation.io/configure/dts.html
*/
export default composePlugins(
withNx(),
withReact(),
withModuleFederation(config, { dts: false })
);
"
`);
expect(tree.exists('remote1/rspack.config.prod.ts')).toBeTruthy();
expect(tree.read('remote1/rspack.config.prod.ts', 'utf-8'))
.toMatchInlineSnapshot(`
"export default require('./rspack.config');
"
`);
expect(project.targets.build).toMatchInlineSnapshot(`
{
"configurations": {
"development": {
"extractLicenses": false,
"optimization": false,
"sourceMap": true,
"vendorChunk": true,
},
"production": {
"extractLicenses": true,
"fileReplacements": [
{
"replace": "demo/src/environments/environment.ts",
"with": "demo/src/environments/environment.prod.ts",
},
],
"namedChunks": false,
"optimization": true,
"outputHashing": "all",
"rspackConfig": "demo/rspack.config.prod.ts",
"sourceMap": false,
"vendorChunk": false,
},
},
"defaultConfiguration": "production",
"executor": "@nx/rspack:rspack",
"options": {
"assets": [
"demo/src/favicon.ico",
"demo/src/assets",
],
"baseHref": "/",
"compiler": "babel",
"index": "demo/src/index.html",
"main": "demo/src/main.ts",
"outputPath": "dist/demo",
"rspackConfig": "demo/rspack.config.ts",
"scripts": [],
"styles": [
"demo/src/styles.css",
],
"target": "web",
"tsConfig": "demo/tsconfig.app.json",
},
"outputs": [
"{options.outputPath}",
],
}
`);
expect(project.targets.serve).toMatchInlineSnapshot(`
{
"configurations": {
"development": {
"buildTarget": "demo:build:development",
},
"production": {
"buildTarget": "demo:build:production",
"hmr": false,
},
},
"defaultConfiguration": "development",
"executor": "@nx/rspack:module-federation-dev-server",
"options": {
"buildTarget": "demo:build",
"hmr": true,
"port": 4200,
},
}
`);
const remote2 = readProjectConfiguration(tree, 'remote2');
expect(tree.exists('remote2/rspack.config.ts')).toBeTruthy();
expect(tree.read('remote2/rspack.config.ts', 'utf-8'))
.toMatchInlineSnapshot(`
"import { withModuleFederation } from '@nx/rspack/module-federation';
import { withReact } from '@nx/rspack';
import { withNx } from '@nx/rspack';
import { composePlugins } from '@nx/rspack';
import baseConfig from './module-federation.config';
const config = {
...baseConfig,
};
// Nx plugins for webpack to build config object from Nx options and context.
/**
* DTS Plugin is disabled in Nx Workspaces as Nx already provides Typing support Module Federation
* The DTS Plugin can be enabled by setting dts: true
* Learn more about the DTS Plugin here: https://module-federation.io/configure/dts.html
*/
export default composePlugins(
withNx(),
withReact(),
withModuleFederation(config, { dts: false })
);
"
`);
expect(tree.exists('remote2/rspack.config.prod.ts')).toBeTruthy();
expect(tree.read('remote2/rspack.config.prod.ts', 'utf-8'))
.toMatchInlineSnapshot(`
"export default require('./rspack.config');
"
`);
expect(project.targets.build).toMatchInlineSnapshot(`
{
"configurations": {
"development": {
"extractLicenses": false,
"optimization": false,
"sourceMap": true,
"vendorChunk": true,
},
"production": {
"extractLicenses": true,
"fileReplacements": [
{
"replace": "demo/src/environments/environment.ts",
"with": "demo/src/environments/environment.prod.ts",
},
],
"namedChunks": false,
"optimization": true,
"outputHashing": "all",
"rspackConfig": "demo/rspack.config.prod.ts",
"sourceMap": false,
"vendorChunk": false,
},
},
"defaultConfiguration": "production",
"executor": "@nx/rspack:rspack",
"options": {
"assets": [
"demo/src/favicon.ico",
"demo/src/assets",
],
"baseHref": "/",
"compiler": "babel",
"index": "demo/src/index.html",
"main": "demo/src/main.ts",
"outputPath": "dist/demo",
"rspackConfig": "demo/rspack.config.ts",
"scripts": [],
"styles": [
"demo/src/styles.css",
],
"target": "web",
"tsConfig": "demo/tsconfig.app.json",
},
"outputs": [
"{options.outputPath}",
],
}
`);
expect(project.targets.serve).toMatchInlineSnapshot(`
{
"configurations": {
"development": {
"buildTarget": "demo:build:development",
},
"production": {
"buildTarget": "demo:build:production",
"hmr": false,
},
},
"defaultConfiguration": "development",
"executor": "@nx/rspack:module-federation-dev-server",
"options": {
"buildTarget": "demo:build",
"hmr": true,
"port": 4200,
},
}
`);
});
});