Skip to content

Commit 97dc7ee

Browse files
committed
feat(create-rstack): add React app templates
1 parent 09f06d8 commit 97dc7ee

28 files changed

Lines changed: 309 additions & 64 deletions

File tree

‎packages/create-rstack/README.md‎

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,16 +13,18 @@ npm create rstack@latest
1313
Using CLI flags:
1414

1515
```bash
16-
npx create-rstack --dir my-project --template app-ts
16+
npx create-rstack --dir my-project --template app-vanilla-ts
1717

1818
# Using abbreviations
19-
npx create-rstack -d my-project -t app-ts
19+
npx create-rstack -d my-project -t app-vanilla-ts
2020
```
2121

2222
## Templates
2323

24-
- `app-js` - JavaScript application
25-
- `app-ts` - TypeScript application
24+
- `app-vanilla-js` - JavaScript Vanilla application
25+
- `app-vanilla-ts` - TypeScript Vanilla application
26+
- `app-react-js` - JavaScript React application
27+
- `app-react-ts` - TypeScript React application
2628
- `lib-js` - JavaScript Node.js library
2729
- `lib-ts` - TypeScript Node.js library
2830

Lines changed: 33 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,18 @@
1-
import {
2-
type Argv,
3-
checkCancel,
4-
create,
5-
type ESLintTemplateName,
6-
type RslintTemplateName,
7-
select,
8-
} from '@rstackjs/create-toolkit';
1+
import { type Argv, checkCancel, create, select } from '@rstackjs/create-toolkit';
92
import path from 'node:path';
103

114
const getTemplateName = async ({ template }: Argv): Promise<string> => {
125
if (typeof template === 'string') {
6+
if (template === 'app' || template.startsWith('app-')) {
7+
const [, framework = 'vanilla', language = 'js'] = template.split('-');
8+
9+
if (framework === 'js' || framework === 'ts') {
10+
return `app-vanilla-${framework}`;
11+
}
12+
13+
return `app-${framework}-${language}`;
14+
}
15+
1316
const [type, language = 'js'] = template.split('-');
1417
return `${type}-${language}`;
1518
}
@@ -24,6 +27,19 @@ const getTemplateName = async ({ template }: Argv): Promise<string> => {
2427
}),
2528
);
2629

30+
const framework =
31+
projectType === 'app'
32+
? checkCancel<string>(
33+
await select({
34+
message: 'Select framework',
35+
options: [
36+
{ value: 'vanilla', label: 'Vanilla' },
37+
{ value: 'react', label: 'React' },
38+
],
39+
}),
40+
)
41+
: undefined;
42+
2743
const language = checkCancel<string>(
2844
await select({
2945
message: 'Select language',
@@ -34,21 +50,20 @@ const getTemplateName = async ({ template }: Argv): Promise<string> => {
3450
}),
3551
);
3652

37-
return `${projectType}-${language}`;
53+
return framework ? `${projectType}-${framework}-${language}` : `${projectType}-${language}`;
3854
};
3955

40-
const mapESLintTemplate = (templateName: string): ESLintTemplateName =>
41-
templateName.endsWith('-ts') ? 'vanilla-ts' : 'vanilla-js';
42-
43-
const mapRslintTemplate = (templateName: string): RslintTemplateName =>
44-
templateName.endsWith('-ts') ? 'vanilla-ts' : 'vanilla-js';
45-
4656
await create({
4757
root: path.join(import.meta.dirname, '..'),
4858
name: 'rstack',
49-
templates: ['app-js', 'app-ts', 'lib-js', 'lib-ts'],
59+
templates: [
60+
'app-vanilla-js',
61+
'app-vanilla-ts',
62+
'app-react-js',
63+
'app-react-ts',
64+
'lib-js',
65+
'lib-ts',
66+
],
5067
builtinTools: [],
5168
getTemplateName,
52-
mapESLintTemplate,
53-
mapRslintTemplate,
5469
});
File renamed without changes.
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"name": "rstack-app-react-js",
3+
"version": "1.0.0",
4+
"private": true,
5+
"type": "module",
6+
"scripts": {
7+
"build": "rs build",
8+
"dev": "rs dev --open",
9+
"preview": "rs preview"
10+
},
11+
"dependencies": {
12+
"react": "^19.2.8",
13+
"react-dom": "^19.2.8"
14+
},
15+
"devDependencies": {
16+
"@rsbuild/plugin-react": "^2.1.0",
17+
"rstack": "^0.3.5"
18+
}
19+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// @ts-check
2+
// Rstack configuration guide: https://rstack.rs/config
3+
import { define } from 'rstack';
4+
5+
define.app(async () => {
6+
const { pluginReact } = await import('@rsbuild/plugin-react');
7+
8+
return {
9+
plugins: [pluginReact()],
10+
};
11+
});

packages/create-rstack/template-app-js/src/index.css renamed to packages/create-rstack/template-app-react-js/src/App.css

File renamed without changes.
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import './App.css';
2+
3+
const App = () => {
4+
return (
5+
<div className="content">
6+
<h1>Rstack with React</h1>
7+
<p>Start building amazing things with Rstack.</p>
8+
</div>
9+
);
10+
};
11+
12+
export default App;
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import React from 'react';
2+
import ReactDOM from 'react-dom/client';
3+
import App from './App';
4+
5+
const root = ReactDOM.createRoot(document.getElementById('root'));
6+
root.render(
7+
<React.StrictMode>
8+
<App />
9+
</React.StrictMode>,
10+
);
File renamed without changes.
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
{
2+
"name": "rstack-app-react-ts",
3+
"version": "1.0.0",
4+
"private": true,
5+
"type": "module",
6+
"scripts": {
7+
"build": "rs build",
8+
"dev": "rs dev --open",
9+
"preview": "rs preview"
10+
},
11+
"dependencies": {
12+
"react": "^19.2.8",
13+
"react-dom": "^19.2.8"
14+
},
15+
"devDependencies": {
16+
"@rsbuild/plugin-react": "^2.1.0",
17+
"@types/node": "^24.13.3",
18+
"@types/react": "^19.2.18",
19+
"@types/react-dom": "^19.2.4",
20+
"rstack": "^0.3.5",
21+
"typescript": "^7.0.2"
22+
}
23+
}

0 commit comments

Comments
 (0)