Skip to content

Commit

Permalink
feat(rspack): add NxAppRspackPlugin and NxReactRspackPlugin (#28987)
Browse files Browse the repository at this point in the history
- feat(rspack): add NxAppRspackPlugin
- feat(rspack): add NxReactRspackPlugin

<!-- 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 currently do not have rspack plugins to encapsulate our app, web and
react support for Rspack. This leads to issues with defining configs
that are supported by Crystal


## Expected Behavior
<!-- This is the behavior we should expect with the changes in this PR
-->
Add and expose two plugins, `NxAppRspackPlugin` and
`NxReactRspackPlugin`, to support building configs that are supported by
crystal

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

Fixes #
  • Loading branch information
Coly010 authored Nov 19, 2024
1 parent 2c53e74 commit 09a01eb
Show file tree
Hide file tree
Showing 7 changed files with 87 additions and 3 deletions.
2 changes: 2 additions & 0 deletions packages/rspack/app-plugin.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export { NxAppRspackPlugin } from './src/plugins/nx-app-rspack-plugin/nx-app-rspack-plugin';
export type { NxAppRspackPluginOptions } from './src/plugins/utils/models';
1 change: 1 addition & 0 deletions packages/rspack/react-plugin.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { NxReactRspackPlugin } from './src/plugins/nx-react-rspack-plugin/nx-react-rspack-plugin';
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import type { Compiler } from '@rspack/core';
import type {
NormalizedNxAppRspackPluginOptions,
NxAppRspackPluginOptions,
} from '../utils/models';
import { normalizeOptions } from '../utils/plugins/normalize-options';
import { applyBaseConfig } from '../utils/apply-base-config';
import { applyWebConfig } from '../utils/apply-web-config';
import { deleteOutputDir } from '../utils/delete-output-path';

/**
* This plugin provides features to build Node and Web applications.
* - TS Support (including tsconfig paths
* - Assets handling
* - Stylesheets handling
* - index.html and package.json generation
*
* Web-only features, such as stylesheets and images, are only supported when `target` is `web` or `webworker`.
*/
export class NxAppRspackPlugin {
private readonly options: NormalizedNxAppRspackPluginOptions;

constructor(options: NxAppRspackPluginOptions = {}) {
// If we're building inferred targets, skip normalizing the build options
if (!global.NX_GRAPH_CREATION) {
this.options = normalizeOptions(options);
}
}

apply(compiler: Compiler) {
// Default's to web
const target = this.options.target ?? compiler.options.target;
this.options.outputPath ??= compiler.options.output?.path;
if (typeof target === 'string') {
this.options.target = target;
}

applyBaseConfig(this.options, compiler.options, {
useNormalizedEntry: true,
});

if (compiler.options.target) {
this.options.target = compiler.options.target;
}

if (this.options.target === 'web' || this.options.target === 'webworker') {
applyWebConfig(this.options, compiler.options, {
useNormalizedEntry: true,
});
}

if (this.options.deleteOutputPath) {
deleteOutputDir(this.options.root, this.options.outputPath);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import type { Compiler } from '@rspack/core';
import { applyReactConfig } from '../utils/apply-react-config';

export class NxReactRspackPlugin {
constructor(private options: { svgr?: boolean } = {}) {}

apply(compiler: Compiler) {
applyReactConfig(this.options, compiler.options);
}
}
5 changes: 3 additions & 2 deletions packages/rspack/src/plugins/utils/apply-web-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
HtmlRspackPlugin,
CssExtractRspackPlugin,
EnvironmentPlugin,
RspackOptionsNormalized,
} from '@rspack/core';
import { instantiateScriptPlugins } from './instantiate-script-plugins';
import { join, resolve } from 'path';
Expand All @@ -21,7 +22,7 @@ import { NormalizedNxAppRspackPluginOptions } from './models';

export function applyWebConfig(
options: NormalizedNxAppRspackPluginOptions,
config: Configuration = {},
config: Partial<RspackOptionsNormalized | Configuration> = {},
{
useNormalizedEntry,
}: {
Expand Down Expand Up @@ -351,7 +352,7 @@ export function applyWebConfig(
});

config.optimization = !isProd
? undefined
? {}
: {
...(config.optimization ?? {}),
minimizer: [...(config.optimization?.minimizer ?? []), ...minimizer],
Expand Down
14 changes: 14 additions & 0 deletions packages/rspack/src/plugins/utils/delete-output-path.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { rmSync } from 'fs';
import { resolve } from 'path';

/**
* Delete an output directory, but error out if it's the root of the project.
*/
export function deleteOutputDir(root: string, outputPath: string) {
const resolvedOutputPath = resolve(root, outputPath);
if (resolvedOutputPath === root) {
throw new Error('Output path MUST not be project root directory!');
}

rmSync(resolvedOutputPath, { recursive: true, force: true });
}
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ export function normalizeOptions(
sourceMap: combinedPluginAndMaybeExecutorOptions.sourceMap ?? !isProd,
sourceRoot,
styles: combinedPluginAndMaybeExecutorOptions.styles ?? [],
target: combinedPluginAndMaybeExecutorOptions.target,
target: combinedPluginAndMaybeExecutorOptions.target ?? 'web',
targetName,
vendorChunk: combinedPluginAndMaybeExecutorOptions.vendorChunk ?? !isProd,
};
Expand Down

0 comments on commit 09a01eb

Please sign in to comment.