diff --git a/docs/generated/packages/react/generators/application.json b/docs/generated/packages/react/generators/application.json index c9813e49467159..cde47e340d881e 100644 --- a/docs/generated/packages/react/generators/application.json +++ b/docs/generated/packages/react/generators/application.json @@ -180,7 +180,7 @@ "bundler": { "description": "The bundler to use.", "type": "string", - "enum": ["vite", "webpack"], + "enum": ["vite", "webpack", "rspack"], "x-prompt": "Which bundler do you want to use to build the application?", "default": "webpack", "x-priority": "important" diff --git a/docs/generated/packages/workspace/generators/preset.json b/docs/generated/packages/workspace/generators/preset.json index 651d03ffd18cf5..56ee01be9b0cfe 100644 --- a/docs/generated/packages/workspace/generators/preset.json +++ b/docs/generated/packages/workspace/generators/preset.json @@ -77,7 +77,7 @@ "bundler": { "description": "The bundler to use for building the application.", "type": "string", - "enum": ["webpack", "vite"], + "enum": ["webpack", "vite", "rspack"], "default": "vite" }, "docker": { diff --git a/packages/create-nx-workspace/bin/create-nx-workspace.ts b/packages/create-nx-workspace/bin/create-nx-workspace.ts index 4d17dd28e88576..c19b6585b2dfa3 100644 --- a/packages/create-nx-workspace/bin/create-nx-workspace.ts +++ b/packages/create-nx-workspace/bin/create-nx-workspace.ts @@ -692,6 +692,10 @@ async function determineBundler( name: 'webpack', message: 'Webpack [ https://webpack.js.org/ ]', }, + { + name: 'rspack', + message: 'Rspack [ https://www.rspack.dev/ ]', + }, ]; if (!parsedArgs.bundler) { @@ -725,5 +729,5 @@ async function determineBundler( process.exit(1); } - return Promise.resolve(parsedArgs.bundler); + return parsedArgs.bundler; } diff --git a/packages/create-nx-workspace/bin/types/bundler-list.ts b/packages/create-nx-workspace/bin/types/bundler-list.ts index 6fd3bceee93088..6e241bd33974ce 100644 --- a/packages/create-nx-workspace/bin/types/bundler-list.ts +++ b/packages/create-nx-workspace/bin/types/bundler-list.ts @@ -1,4 +1,4 @@ // Bundler to be used to build the application -export const bundlerList = ['webpack', 'vite']; +export const bundlerList = ['webpack', 'vite', 'rspack']; export type Bundler = typeof bundlerList[number]; diff --git a/packages/react/src/generators/application/application.ts b/packages/react/src/generators/application/application.ts index d24db1b3439708..ad075b275374a4 100644 --- a/packages/react/src/generators/application/application.ts +++ b/packages/react/src/generators/application/application.ts @@ -6,7 +6,7 @@ import { NormalizedSchema, Schema } from './schema'; import { createApplicationFiles } from './lib/create-application-files'; import { updateSpecConfig } from './lib/update-jest-config'; import { normalizeOptions } from './lib/normalize-options'; -import { addProject } from './lib/add-project'; +import { addProject, maybeJs } from './lib/add-project'; import { addCypress } from './lib/add-cypress'; import { addJest } from './lib/add-jest'; import { addRouting } from './lib/add-routing'; @@ -28,6 +28,7 @@ import reactInitGenerator from '../init/init'; import { Linter, lintProjectGenerator } from '@nrwl/linter'; import { mapLintPattern } from '@nrwl/linter/src/generators/lint-project/lint-project'; import { + nxRspackVersion, nxVersion, swcCoreVersion, swcLoaderVersion, @@ -137,6 +138,23 @@ export async function applicationGenerator( skipFormat: true, }); tasks.push(webpackInitTask); + } else if (options.bundler === 'rspack') { + const { configurationGenerator } = ensurePackage( + '@nrwl/rspack', + nxRspackVersion + ); + const rspackTask = await configurationGenerator(host, { + project: options.projectName, + main: joinPathFragments( + options.appProjectRoot, + maybeJs(options, `src/main.tsx`) + ), + tsConfig: joinPathFragments(options.appProjectRoot, 'tsconfig.app.json'), + target: 'web', + newProject: true, + uiFramework: 'react', + }); + tasks.push(rspackTask); } if (options.bundler !== 'vite' && options.unitTestRunner === 'vitest') { diff --git a/packages/react/src/generators/application/files/base-rspack/src/app/__fileName__.spec.tsx__tmpl__ b/packages/react/src/generators/application/files/base-rspack/src/app/__fileName__.spec.tsx__tmpl__ new file mode 100644 index 00000000000000..a156be880642af --- /dev/null +++ b/packages/react/src/generators/application/files/base-rspack/src/app/__fileName__.spec.tsx__tmpl__ @@ -0,0 +1,10 @@ +import { render } from '@testing-library/react'; +<% if (routing) { %> +import { BrowserRouter } from 'react-router-dom'; +<% } %> + +import App from './<%= fileName %>'; + +describe('App', () => { + <%- appTests %> +}); diff --git a/packages/react/src/generators/application/files/base-rspack/src/assets/.gitkeep b/packages/react/src/generators/application/files/base-rspack/src/assets/.gitkeep new file mode 100644 index 00000000000000..e69de29bb2d1d6 diff --git a/packages/react/src/generators/application/files/base-rspack/src/favicon.ico b/packages/react/src/generators/application/files/base-rspack/src/favicon.ico new file mode 100644 index 00000000000000..317ebcb2336e08 Binary files /dev/null and b/packages/react/src/generators/application/files/base-rspack/src/favicon.ico differ diff --git a/packages/react/src/generators/application/files/base-rspack/src/index.html b/packages/react/src/generators/application/files/base-rspack/src/index.html new file mode 100644 index 00000000000000..85edca9f5dbfe1 --- /dev/null +++ b/packages/react/src/generators/application/files/base-rspack/src/index.html @@ -0,0 +1,14 @@ + + + + + <%= className %> + + + + + + +
+ + diff --git a/packages/react/src/generators/application/files/base-rspack/src/main.tsx__tmpl__ b/packages/react/src/generators/application/files/base-rspack/src/main.tsx__tmpl__ new file mode 100644 index 00000000000000..d5a60a7b0dd144 --- /dev/null +++ b/packages/react/src/generators/application/files/base-rspack/src/main.tsx__tmpl__ @@ -0,0 +1,10 @@ +<% if (strict) { %>import { StrictMode } from 'react';<% } %> +import * as ReactDOM from 'react-dom/client'; +<% if (routing) { %>import { BrowserRouter } from 'react-router-dom';<% } %> + +import App from './app/<%= fileName %>'; + +const root = ReactDOM.createRoot(document.getElementById('root') as HTMLElement); +root.render( +<% if (strict) { %><% } %><% if (routing) { %><% } %><% if (routing) { %><% } %><% if (strict) { %><% } %> +); diff --git a/packages/react/src/generators/application/files/base-rspack/tsconfig.app.json__tmpl__ b/packages/react/src/generators/application/files/base-rspack/tsconfig.app.json__tmpl__ new file mode 100644 index 00000000000000..71e273bf2fc3ca --- /dev/null +++ b/packages/react/src/generators/application/files/base-rspack/tsconfig.app.json__tmpl__ @@ -0,0 +1,14 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "<%= offsetFromRoot %>dist/out-tsc", + "types": ["node"] + }, + "files": [ + <% if (style === 'styled-jsx') { %>"<%= offsetFromRoot %>node_modules/@nrwl/react/typings/styled-jsx.d.ts",<% } %> + "<%= offsetFromRoot %>node_modules/@nrwl/react/typings/cssmodule.d.ts", + "<%= offsetFromRoot %>node_modules/@nrwl/react/typings/image.d.ts" + ], + "exclude": ["jest.config.ts","src/**/*.spec.ts", "src/**/*.test.ts", "src/**/*.spec.tsx", "src/**/*.test.tsx", "src/**/*.spec.js", "src/**/*.test.js", "src/**/*.spec.jsx", "src/**/*.test.jsx"], + "include": ["src/**/*.js", "src/**/*.jsx", "src/**/*.ts", "src/**/*.tsx"] +} diff --git a/packages/react/src/generators/application/lib/add-cypress.ts b/packages/react/src/generators/application/lib/add-cypress.ts index e59466e24713ab..82b53bb9b45e10 100644 --- a/packages/react/src/generators/application/lib/add-cypress.ts +++ b/packages/react/src/generators/application/lib/add-cypress.ts @@ -22,7 +22,7 @@ export async function addCypress(host: Tree, options: NormalizedSchema) { name: options.e2eProjectName, directory: options.directory, project: options.projectName, - bundler: options.bundler, + bundler: options.bundler === 'rspack' ? 'webpack' : options.bundler, skipFormat: true, }); } diff --git a/packages/react/src/generators/application/lib/add-project.ts b/packages/react/src/generators/application/lib/add-project.ts index d9744ce2e5461f..3effeab3485e55 100644 --- a/packages/react/src/generators/application/lib/add-project.ts +++ b/packages/react/src/generators/application/lib/add-project.ts @@ -27,7 +27,7 @@ export function addProject(host, options: NormalizedSchema) { }); } -function maybeJs(options: NormalizedSchema, path: string): string { +export function maybeJs(options: NormalizedSchema, path: string): string { return options.js && (path.endsWith('.ts') || path.endsWith('.tsx')) ? path.replace(/\.tsx?$/, '.js') : path; diff --git a/packages/react/src/generators/application/schema.d.ts b/packages/react/src/generators/application/schema.d.ts index 883bb4c0dfc4fa..6a885d8fc0a0ee 100644 --- a/packages/react/src/generators/application/schema.d.ts +++ b/packages/react/src/generators/application/schema.d.ts @@ -29,7 +29,7 @@ export interface Schema { devServerPort?: number; skipPackageJson?: boolean; rootProject?: boolean; - bundler?: 'webpack' | 'vite'; + bundler?: 'webpack' | 'vite' | 'rspack'; minimal?: boolean; } diff --git a/packages/react/src/generators/application/schema.json b/packages/react/src/generators/application/schema.json index 6073454d019798..989117086eae8a 100644 --- a/packages/react/src/generators/application/schema.json +++ b/packages/react/src/generators/application/schema.json @@ -186,7 +186,7 @@ "bundler": { "description": "The bundler to use.", "type": "string", - "enum": ["vite", "webpack"], + "enum": ["vite", "webpack", "rspack"], "x-prompt": "Which bundler do you want to use to build the application?", "default": "webpack", "x-priority": "important" diff --git a/packages/react/src/utils/versions.ts b/packages/react/src/utils/versions.ts index 873004ebce5a00..fd3dffd3f74ad7 100755 --- a/packages/react/src/utils/versions.ts +++ b/packages/react/src/utils/versions.ts @@ -1,4 +1,5 @@ export const nxVersion = require('../../package.json').version; +export const nxRspackVersion = '~15.9.0'; export const reactVersion = '18.2.0'; export const reactDomVersion = '18.2.0'; diff --git a/packages/workspace/src/generators/preset/schema.d.ts b/packages/workspace/src/generators/preset/schema.d.ts index 50c5ecedda24f0..41733da6cb3faf 100644 --- a/packages/workspace/src/generators/preset/schema.d.ts +++ b/packages/workspace/src/generators/preset/schema.d.ts @@ -10,7 +10,7 @@ export interface Schema { standaloneConfig?: boolean; framework?: string; packageManager?: PackageManager; - bundler?: 'vite' | 'webpack'; + bundler?: 'vite' | 'webpack' | 'rspack'; docker?: boolean; routing?: boolean; standaloneApi?: boolean; diff --git a/packages/workspace/src/generators/preset/schema.json b/packages/workspace/src/generators/preset/schema.json index ca6f3c5830df8d..fb830045272939 100644 --- a/packages/workspace/src/generators/preset/schema.json +++ b/packages/workspace/src/generators/preset/schema.json @@ -80,7 +80,7 @@ "bundler": { "description": "The bundler to use for building the application.", "type": "string", - "enum": ["webpack", "vite"], + "enum": ["webpack", "vite", "rspack"], "default": "vite" }, "docker": {