Skip to content

Commit

Permalink
feat(rspack): Update configuration generator to support NxRspackAppPl…
Browse files Browse the repository at this point in the history
…ugin (#29024)

WIP

<!-- 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 -->

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

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

Fixes #

---------

Co-authored-by: Colum Ferry <[email protected]>
  • Loading branch information
ndcunningham and Coly010 authored Nov 22, 2024
1 parent a1efb63 commit 5bd8f4f
Show file tree
Hide file tree
Showing 9 changed files with 410 additions and 188 deletions.
81 changes: 0 additions & 81 deletions packages/react/src/generators/application/application.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1241,85 +1241,4 @@ describe('app', () => {
}
`);
});

it('should add project to excludes when @nx/rspack/plugin is setup as object and --bundler=rspack', async () => {
// ARRANGE
const tree = createTreeWithEmptyWorkspace();
let nxJson = readNxJson(tree);
delete nxJson.targetDefaults;
nxJson.plugins ??= [];
nxJson.plugins.push({
plugin: '@nx/rspack/plugin',
options: {
buildTargetName: 'build-base',
},
});
updateNxJson(tree, nxJson);

// ACT
await applicationGenerator(tree, {
directory: 'myapp',
addPlugin: true,
linter: Linter.None,
style: 'none',
bundler: 'rspack',
e2eTestRunner: 'none',
});

// ASSERT
nxJson = readNxJson(tree);
expect(
nxJson.plugins.find((p) =>
typeof p === 'string'
? p === '@nx/rspack/plugin'
: p.plugin === '@nx/rspack/plugin'
)
).toMatchInlineSnapshot(`
{
"exclude": [
"myapp/**",
],
"options": {
"buildTargetName": "build-base",
},
"plugin": "@nx/rspack/plugin",
}
`);
});
it('should add project to excludes when @nx/rspack/plugin is setup as string and --bundler=rspack', async () => {
// ARRANGE
const tree = createTreeWithEmptyWorkspace();
let nxJson = readNxJson(tree);
delete nxJson.targetDefaults;
nxJson.plugins ??= [];
nxJson.plugins.push('@nx/rspack/plugin');
updateNxJson(tree, nxJson);

// ACT
await applicationGenerator(tree, {
directory: 'myapp',
addPlugin: true,
linter: Linter.None,
style: 'none',
bundler: 'rspack',
e2eTestRunner: 'none',
});

// ASSERT
nxJson = readNxJson(tree);
expect(
nxJson.plugins.find((p) =>
typeof p === 'string'
? p === '@nx/rspack/plugin'
: p.plugin === '@nx/rspack/plugin'
)
).toMatchInlineSnapshot(`
{
"exclude": [
"myapp/**",
],
"plugin": "@nx/rspack/plugin",
}
`);
});
});
33 changes: 11 additions & 22 deletions packages/react/src/generators/application/application.ts
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,17 @@ export async function applicationGeneratorInternal(
);
tasks.push(ensureDependencies(host, { uiFramework: 'react' }));
}
} else if (options.bundler === 'rspack') {
const { rspackInitGenerator } = ensurePackage(
'@nx/rspack',
nxRspackVersion
);
const rspackInitTask = await rspackInitGenerator(host, {
...options,
addPlugin: false,
skipFormat: true,
});
tasks.push(rspackInitTask);
}

if (!options.rootProject) {
Expand Down Expand Up @@ -227,28 +238,6 @@ export async function applicationGeneratorInternal(
false
);
} else if (options.bundler === 'rspack') {
const { configurationGenerator } = ensurePackage(
'@nx/rspack',
nxRspackVersion
);
const rspackTask = await configurationGenerator(host, {
project: options.projectName,
main: joinPathFragments(
options.appProjectRoot,
maybeJs(
{
js: options.js,
useJsx: true,
},
`src/main.tsx`
)
),
tsConfig: joinPathFragments(options.appProjectRoot, 'tsconfig.app.json'),
target: 'web',
newProject: true,
framework: 'react',
});
tasks.push(rspackTask);
addProjectRootToRspackPluginExcludesIfExists(host, options.appProjectRoot);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<%_ if (rspackPluginOptions) { _%>
const { NxAppRspackPlugin } = require('@nx/rspack/app-plugin');
const { NxReactRspackPlugin } = require('@nx/rspack/react-plugin');
const { join } = require('path');

module.exports = {
output: {
path: join(__dirname, '<%= offsetFromRoot %><%= rspackPluginOptions.outputPath %>'),
},
devServer: {
port: 4200,
historyApiFallback: {
index: '/index.html',
disableDotRule: true,
htmlAcceptHeaders: ['text/html', 'application/xhtml+xml'],
},
},
plugins: [
new NxAppRspackPlugin({
tsConfig: '<%= rspackPluginOptions.tsConfig %>',
main: '<%= rspackPluginOptions.main %>',
index: '<%= rspackPluginOptions.index %>',
baseHref: '<%= rspackPluginOptions.baseHref %>',
assets: <%- JSON.stringify(rspackPluginOptions.assets) %>,
styles: <%- JSON.stringify(rspackPluginOptions.styles) %>,
outputHashing: process.env['NODE_ENV'] === 'production' ? 'all' : 'none',
optimization: process.env['NODE_ENV'] === 'production',
}),
new NxReactRspackPlugin({
// Uncomment this line if you don't want to use SVGR
// See: https://react-svgr.com/
// svgr: false
}),
],
};
<%_ } else { _%>
const { composePlugins, withNx, withReact } = require('@nx/rspack');

// Nx plugins for rspack.
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 rspack config as needed here.
// e.g. `config.plugins.push(new MyPlugin())`
return config;
}
);
<%_ } _%>
83 changes: 83 additions & 0 deletions packages/react/src/generators/application/lib/add-project.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
} from '@nx/devkit';
import { hasWebpackPlugin } from '../../../utils/has-webpack-plugin';
import { maybeJs } from '../../../utils/maybe-js';
import { hasRspackPlugin } from '../../../utils/has-rspack-plugin';

export function addProject(host: Tree, options: NormalizedSchema) {
const project: ProjectConfiguration = {
Expand All @@ -25,13 +26,95 @@ export function addProject(host: Tree, options: NormalizedSchema) {
serve: createServeTarget(options),
};
}
} else if (
options.bundler === 'rspack' &&
(!hasRspackPlugin(host) || !options.addPlugin)
) {
project.targets = {
build: createRspackBuildTarget(options),
serve: createRspackServeTarget(options),
};
}

addProjectConfiguration(host, options.projectName, {
...project,
});
}

function createRspackBuildTarget(
options: NormalizedSchema
): TargetConfiguration {
return {
executor: '@nx/rspack:rspack',
outputs: ['{options.outputPath}'],
defaultConfiguration: 'production',
options: {
outputPath: joinPathFragments('dist', options.appProjectRoot),
index: joinPathFragments(options.appProjectRoot, 'src/index.html'),
baseHref: '/',
main: joinPathFragments(
options.appProjectRoot,
maybeJs(options, `src/main.tsx`)
),
tsConfig: joinPathFragments(options.appProjectRoot, 'tsconfig.app.json'),
assets: [
joinPathFragments(options.appProjectRoot, 'src/favicon.ico'),
joinPathFragments(options.appProjectRoot, 'src/assets'),
],
rspackConfig: joinPathFragments(
options.appProjectRoot,
'rspack.config.js'
),
styles:
options.styledModule || !options.hasStyles
? []
: [
joinPathFragments(
options.appProjectRoot,
`src/styles.${options.style}`
),
],
scripts: [],
configurations: {
development: {
mode: 'development',
},
production: {
mode: 'production',
optimization: true,
sourceMap: false,
outputHashing: 'all',
namedChunks: false,
extractLicenses: true,
vendorChunk: false,
},
},
},
};
}

function createRspackServeTarget(
options: NormalizedSchema
): TargetConfiguration {
return {
executor: '@nx/rspack:dev-server',
defaultConfiguration: 'development',
options: {
buildTarget: `${options.projectName}:build`,
hmr: true,
},
configurations: {
development: {
buildTarget: `${options.projectName}:build:development`,
},
production: {
buildTarget: `${options.projectName}:build:production`,
hmr: false,
},
},
};
}

function createBuildTarget(options: NormalizedSchema): TargetConfiguration {
return {
executor: '@nx/webpack:webpack',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import {
getNxCloudAppOnBoardingUrl,
createNxCloudOnboardingURLForWelcomeApp,
} from 'nx/src/nx-cloud/utilities/onboarding';
import { hasRspackPlugin } from '../../../utils/has-rspack-plugin';

export async function createApplicationFiles(
host: Tree,
Expand Down Expand Up @@ -145,7 +146,12 @@ export async function createApplicationFiles(
host,
join(__dirname, '../files/base-rspack'),
options.appProjectRoot,
templateVariables
{
...templateVariables,
rspackPluginOptions: hasRspackPlugin(host)
? createNxRspackPluginOptions(options)
: null,
}
);
}

Expand Down Expand Up @@ -226,3 +232,36 @@ function createNxWebpackPluginOptions(
],
};
}

function createNxRspackPluginOptions(
options: NormalizedSchema
): WithNxOptions & WithReactOptions {
return {
target: 'web',
outputPath: joinPathFragments(
'dist',
options.appProjectRoot != '.'
? options.appProjectRoot
: options.projectName
),
index: './src/index.html',
baseHref: '/',
main: maybeJs(
{
js: options.js,
useJsx: true,
},
`./src/main.tsx`
),
tsConfig: './tsconfig.app.json',
assets: ['./src/favicon.ico', './src/assets'],
styles:
options.styledModule || !options.hasStyles
? []
: [
`./src/styles.${
options.style !== 'tailwind' ? options.style : 'css'
}`,
],
};
}
12 changes: 8 additions & 4 deletions packages/react/src/rules/update-module-federation-project.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ export function updateModuleFederationProject(
if (options.bundler === 'rspack') {
projectConfig.targets.build.executor = '@nx/rspack:rspack';
projectConfig.targets.build.options = {
...projectConfig.targets.build.options,
...(projectConfig.targets.build.options ?? {}),
main: maybeJs(
{ js: options.js, useJsx: true },
`${options.appProjectRoot}/src/main.ts`
Expand All @@ -37,23 +37,27 @@ export function updateModuleFederationProject(
target: 'web',
};

projectConfig.targets.build.configurations ??= {};

projectConfig.targets.build.configurations.production = {
...projectConfig.targets.build.configurations.production,
...(projectConfig.targets.build.configurations?.production ?? {}),
rspackConfig: `${options.appProjectRoot}/rspack.config.prod.${
options.typescriptConfiguration && !options.js ? 'ts' : 'js'
}`,
};
} else {
projectConfig.targets.build.options = {
...projectConfig.targets.build.options,
...(projectConfig.targets.build.options ?? {}),
main: maybeJs(options, `${options.appProjectRoot}/src/main.ts`),
webpackConfig: `${options.appProjectRoot}/webpack.config.${
options.typescriptConfiguration && !options.js ? 'ts' : 'js'
}`,
};

projectConfig.targets.build.configurations ??= {};

projectConfig.targets.build.configurations.production = {
...projectConfig.targets.build.configurations.production,
...(projectConfig.targets.build.configurations?.production ?? {}),
webpackConfig: `${options.appProjectRoot}/webpack.config.prod.${
options.typescriptConfiguration && !options.js ? 'ts' : 'js'
}`,
Expand Down
Loading

0 comments on commit 5bd8f4f

Please sign in to comment.