Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(rsbuild): add react and vue support for app generation #29349

Merged
merged 14 commits into from
Dec 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@
"bundler": {
"description": "The bundler to use.",
"type": "string",
"enum": ["vite", "webpack", "rspack"],
"enum": ["vite", "webpack", "rspack", "rsbuild"],
"x-prompt": "Which bundler do you want to use to build the application?",
"default": "vite",
"x-priority": "important"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@
"description": "Path relative to the workspace root for the tsconfig file to build with. Defaults to '<projectRoot>/tsconfig.app.json'.",
"x-priority": "important"
},
"devServerPort": {
"type": "number",
"description": "The port for the dev server to listen on.",
"default": 4200
},
"target": {
"type": "string",
"description": "Target platform for the build, same as the Rsbuild output.target config option.",
Expand Down
8 changes: 8 additions & 0 deletions docs/generated/packages/vue/generators/application.json
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,14 @@
]
}
},
"bundler": {
"description": "The bundler to use.",
"type": "string",
"enum": ["vite", "rsbuild"],
"x-prompt": "Which bundler do you want to use to build the application?",
"default": "vite",
"x-priority": "important"
},
"routing": {
"type": "boolean",
"description": "Generate application with routes.",
Expand Down
110 changes: 110 additions & 0 deletions e2e/react/src/react-rsbuild.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
import {
checkFilesExist,
cleanupProject,
newProject,
runCLI,
runCLIAsync,
runE2ETests,
uniq,
} from '@nx/e2e/utils';

describe('Build React applications and libraries with Rsbuild', () => {
Coly010 marked this conversation as resolved.
Show resolved Hide resolved
beforeAll(() => {
newProject({
packages: ['@nx/react'],
});
});

afterAll(() => {
cleanupProject();
});

it('should test and lint app with bundler=rsbuild', async () => {
const rsbuildApp = uniq('rsbuildapp');

runCLI(
`generate @nx/react:app apps/${rsbuildApp} --bundler=rsbuild --unitTestRunner=vitest --no-interactive --linter=eslint`
);

const appTestResults = await runCLIAsync(`test ${rsbuildApp}`);
expect(appTestResults.combinedOutput).toContain(
'Successfully ran target test'
);

const appLintResults = await runCLIAsync(`lint ${rsbuildApp}`);
expect(appLintResults.combinedOutput).toContain(
'Successfully ran target lint'
);

await runCLIAsync(`build ${rsbuildApp}`);
checkFilesExist(`apps/${rsbuildApp}/dist/index.html`);
}, 300_000);

it('should test and lint app with bundler=rsbuild', async () => {
const rsbuildApp = uniq('rsbuildapp');

runCLI(
`generate @nx/react:app apps/${rsbuildApp} --bundler=rsbuild --unitTestRunner=vitest --no-interactive --linter=eslint`
);

const appTestResults = await runCLIAsync(`test ${rsbuildApp}`);
expect(appTestResults.combinedOutput).toContain(
'Successfully ran target test'
);

const appLintResults = await runCLIAsync(`lint ${rsbuildApp}`);
expect(appLintResults.combinedOutput).toContain(
'Successfully ran target lint'
);

await runCLIAsync(`build ${rsbuildApp}`);
checkFilesExist(`apps/${rsbuildApp}/dist/index.html`);
}, 300_000);

it('should test and lint app with bundler=rsbuild and inSourceTests', async () => {
const rsbuildApp = uniq('rsbuildapp');

runCLI(
`generate @nx/react:app apps/${rsbuildApp} --bundler=rsbuild --unitTestRunner=vitest --inSourceTests --no-interactive --linter=eslint`
);
expect(() => {
checkFilesExist(`apps/${rsbuildApp}/src/app/app.spec.tsx`);
}).toThrow();

const appTestResults = await runCLIAsync(`test ${rsbuildApp}`);
expect(appTestResults.combinedOutput).toContain(
'Successfully ran target test'
);

const appLintResults = await runCLIAsync(`lint ${rsbuildApp}`);
expect(appLintResults.combinedOutput).toContain(
'Successfully ran target lint'
);

await runCLIAsync(`build ${rsbuildApp}`);
checkFilesExist(`apps/${rsbuildApp}/dist/index.html`);
}, 300_000);

it('should support bundling with Rsbuild and Jest', async () => {
const rsbuildApp = uniq('rsbuildapp');

runCLI(
`generate @nx/react:app apps/${rsbuildApp} --bundler=rsbuild --unitTestRunner=jest --no-interactive --linter=eslint`
);

const appTestResults = await runCLIAsync(`test ${rsbuildApp}`);
expect(appTestResults.combinedOutput).toContain(
'Successfully ran target test'
);

await runCLIAsync(`build ${rsbuildApp}`);
checkFilesExist(`apps/${rsbuildApp}/dist/index.html`);

if (runE2ETests()) {
const result = runCLI(`e2e ${rsbuildApp}-e2e --verbose`);
expect(result).toContain(
`Successfully ran target e2e for project ${rsbuildApp}-e2e`
);
}
}, 300_000);
});
32 changes: 31 additions & 1 deletion e2e/vue/src/vue.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
import { cleanupProject, newProject, runCLI, uniq } from '@nx/e2e/utils';
import {
cleanupProject,
killPorts,
newProject,
runCLI,
runE2ETests,
uniq,
} from '@nx/e2e/utils';

describe('Vue Plugin', () => {
let proj: string;
Expand Down Expand Up @@ -33,6 +40,29 @@ describe('Vue Plugin', () => {
// }
}, 200_000);

it('should serve application in dev mode with rsbuild', async () => {
const app = uniq('app');

runCLI(
`generate @nx/vue:app ${app} --bundler=rsbuild --unitTestRunner=vitest --e2eTestRunner=playwright`
);
let result = runCLI(`test ${app}`);
expect(result).toContain(`Successfully ran target test for project ${app}`);

result = runCLI(`build ${app}`);
expect(result).toContain(
`Successfully ran target build for project ${app}`
);

// TODO: enable this when tests are passing again.
// Colum confirmed locally that the generated config and the playwright tests are working.
// if (runE2ETests()) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

image image

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The other vue e2e test also has the runE2e block commented out.
We should investigate why it doesn't like CI later

// const e2eResults = runCLI(`e2e ${app}-e2e --no-watch`);
// expect(e2eResults).toContain('Successfully ran target e2e');
// expect(await killPorts()).toBeTruthy();
// }
}, 200_000);

it('should build library', async () => {
const lib = uniq('lib');

Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -83,11 +83,12 @@
"@nx/powerpack-enterprise-cloud": "1.1.0-beta.9",
"@nx/powerpack-license": "1.1.0-beta.9",
"@nx/react": "20.3.0-beta.0",
"@nx/rsbuild": "20.3.0-beta.0",
"@nx/rspack": "20.3.0-beta.0",
"@nx/storybook": "20.3.0-beta.0",
"@nx/vite": "20.3.0-beta.0",
"@nx/web": "20.3.0-beta.0",
"@nx/webpack": "20.3.0-beta.0",
"@nx/vite": "20.3.0-beta.0",
"@phenomnomnominal/tsquery": "~5.0.1",
"@playwright/test": "^1.36.1",
"@pmmmwh/react-refresh-webpack-plugin": "^0.5.7",
Expand Down
1 change: 1 addition & 0 deletions packages/react/.eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
"@nx/playwright",
"@nx/jest",
"@nx/rollup",
"@nx/rsbuild",
"@nx/storybook",
"@nx/vite",
"@nx/webpack",
Expand Down
Loading
Loading