create-react-starter-kit 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +119 -0
- package/bin/create-react-starter-kit.js +7 -0
- package/dist/cli-args.d.ts +15 -0
- package/dist/cli-args.d.ts.map +1 -0
- package/dist/cli-args.js +78 -0
- package/dist/cli-args.js.map +1 -0
- package/dist/generator/dependencies.d.ts +8 -0
- package/dist/generator/dependencies.d.ts.map +1 -0
- package/dist/generator/dependencies.js +356 -0
- package/dist/generator/dependencies.js.map +1 -0
- package/dist/generator/index.d.ts +5 -0
- package/dist/generator/index.d.ts.map +1 -0
- package/dist/generator/index.js +358 -0
- package/dist/generator/index.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +38 -0
- package/dist/index.js.map +1 -0
- package/dist/prompts/index.d.ts +3 -0
- package/dist/prompts/index.d.ts.map +1 -0
- package/dist/prompts/index.js +267 -0
- package/dist/prompts/index.js.map +1 -0
- package/dist/templates/.env.example.ejs +21 -0
- package/dist/templates/.husky/commit-msg +2 -0
- package/dist/templates/.husky/pre-commit +2 -0
- package/dist/templates/README.md.ejs +169 -0
- package/dist/templates/__js__/jsconfig.json +9 -0
- package/dist/templates/__ts__/src/vite-env.d.ts +16 -0
- package/dist/templates/__ts__/tsconfig.json +24 -0
- package/dist/templates/__when_buildTool_esbuild__/scripts/esbuild.build.mjs.ejs +23 -0
- package/dist/templates/__when_buildTool_esbuild__/scripts/esbuild.dev.mjs.ejs +48 -0
- package/dist/templates/__when_buildTool_parcel__/.parcelrc +9 -0
- package/dist/templates/__when_buildTool_rollup__/rollup.config.js.ejs +33 -0
- package/dist/templates/__when_buildTool_rspack__/rspack.config.js.ejs +36 -0
- package/dist/templates/__when_buildTool_vite__/vite.config.ts.ejs +37 -0
- package/dist/templates/__when_buildTool_webpack__/webpack.config.js.ejs +68 -0
- package/dist/templates/__when_e2eTesting_cypress__/cypress/e2e/home.cy.ts.ejs +6 -0
- package/dist/templates/__when_e2eTesting_cypress__/cypress.config.ts.ejs +8 -0
- package/dist/templates/__when_e2eTesting_playwright__/playwright.config.ts.ejs +16 -0
- package/dist/templates/__when_e2eTesting_playwright__/tests/e2e/home.spec.ts.ejs +6 -0
- package/dist/templates/__when_formatting_prettier__/.prettierrc +7 -0
- package/dist/templates/__when_formatting_stylelint__/.stylelintrc.json +3 -0
- package/dist/templates/__when_linting_biome__/biome.json +19 -0
- package/dist/templates/__when_linting_eslint__/eslint.config.js.ejs +42 -0
- package/dist/templates/__when_serverState_rtk-query__/src/store/postsApi.ts.ejs +19 -0
- package/dist/templates/__when_stateManagement_context__/src/store/context.tsx.ejs +57 -0
- package/dist/templates/__when_styling_tailwind__/postcss.config.js +6 -0
- package/dist/templates/__when_styling_tailwind__/tailwind.config.js.ejs +23 -0
- package/dist/templates/__when_unitTesting_jest__/jest.config.json.ejs +11 -0
- package/dist/templates/__when_unitTesting_jest__/tests/App.test.tsx.ejs +13 -0
- package/dist/templates/__when_unitTesting_jest__/tests/setup.ts.ejs +1 -0
- package/dist/templates/__when_unitTesting_jest__/tests/styleMock.ts.ejs +1 -0
- package/dist/templates/__when_unitTesting_rtl__/tests/App.test.tsx.ejs +13 -0
- package/dist/templates/__when_unitTesting_vitest__/tests/App.test.tsx.ejs +16 -0
- package/dist/templates/__when_unitTesting_vitest__/tests/setup.ts.ejs +1 -0
- package/dist/templates/__when_visualTesting_storybook__/.storybook/main.js.ejs +11 -0
- package/dist/templates/__when_visualTesting_storybook__/.storybook/preview.js +8 -0
- package/dist/templates/__when_visualTesting_storybook__/src/components/ui/UiButton.stories.tsx.ejs +15 -0
- package/dist/templates/commitlint.config.js +3 -0
- package/dist/templates/docs/architecture.md.ejs +74 -0
- package/dist/templates/docs/best-practices.md.ejs +56 -0
- package/dist/templates/docs/examples/README.md.ejs +14 -0
- package/dist/templates/docs/examples/api.md.ejs +17 -0
- package/dist/templates/docs/examples/data-fetching.md.ejs +18 -0
- package/dist/templates/docs/examples/forms.md.ejs +18 -0
- package/dist/templates/docs/examples/state.md.ejs +17 -0
- package/dist/templates/docs/examples/styling.md.ejs +23 -0
- package/dist/templates/docs/examples/testing.md.ejs +27 -0
- package/dist/templates/docs/getting-started.md.ejs +55 -0
- package/dist/templates/docs/selected-stack.md.ejs +55 -0
- package/dist/templates/index.html.ejs +19 -0
- package/dist/templates/public/vite.svg +4 -0
- package/dist/templates/src/app/App.tsx.ejs +71 -0
- package/dist/templates/src/app/providers.tsx.ejs +93 -0
- package/dist/templates/src/assets/.gitkeep +0 -0
- package/dist/templates/src/components/StackBadge.tsx.ejs +15 -0
- package/dist/templates/src/components/layout/AppLayout.tsx.ejs +64 -0
- package/dist/templates/src/components/ui/Toast.tsx.ejs +61 -0
- package/dist/templates/src/components/ui/UiButton.tsx.ejs +168 -0
- package/dist/templates/src/config/env.ts.ejs +18 -0
- package/dist/templates/src/features/counter/CounterPanel.tsx.ejs +66 -0
- package/dist/templates/src/features/feedback/FeedbackForm.tsx.ejs +373 -0
- package/dist/templates/src/features/posts/PostsPanel.tsx.ejs +91 -0
- package/dist/templates/src/hooks/useMounted.ts.ejs +15 -0
- package/dist/templates/src/lib/cn.ts.ejs +12 -0
- package/dist/templates/src/lib/monitoring.ts.ejs +66 -0
- package/dist/templates/src/lib/validation.ts.ejs +81 -0
- package/dist/templates/src/main.tsx.ejs +22 -0
- package/dist/templates/src/routes/AboutPage.tsx.ejs +30 -0
- package/dist/templates/src/routes/HomePage.tsx.ejs +47 -0
- package/dist/templates/src/services/api.ts.ejs +84 -0
- package/dist/templates/src/store/index.ts.ejs +80 -0
- package/dist/templates/src/styles/global.css.ejs +457 -0
- package/dist/templates/src/types/index.ts.ejs +7 -0
- package/dist/templates/src/utils/format.ts.ejs +3 -0
- package/dist/types.d.ts +46 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/logger.d.ts +12 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +31 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/validate.d.ts +3 -0
- package/dist/utils/validate.d.ts.map +1 -0
- package/dist/utils/validate.js +24 -0
- package/dist/utils/validate.js.map +1 -0
- package/package.json +62 -0
- package/templates/.env.example.ejs +21 -0
- package/templates/.husky/commit-msg +2 -0
- package/templates/.husky/pre-commit +2 -0
- package/templates/README.md.ejs +169 -0
- package/templates/__js__/jsconfig.json +9 -0
- package/templates/__ts__/src/vite-env.d.ts +16 -0
- package/templates/__ts__/tsconfig.json +24 -0
- package/templates/__when_buildTool_esbuild__/scripts/esbuild.build.mjs.ejs +23 -0
- package/templates/__when_buildTool_esbuild__/scripts/esbuild.dev.mjs.ejs +48 -0
- package/templates/__when_buildTool_parcel__/.parcelrc +9 -0
- package/templates/__when_buildTool_rollup__/rollup.config.js.ejs +33 -0
- package/templates/__when_buildTool_rspack__/rspack.config.js.ejs +36 -0
- package/templates/__when_buildTool_vite__/vite.config.ts.ejs +37 -0
- package/templates/__when_buildTool_webpack__/webpack.config.js.ejs +68 -0
- package/templates/__when_e2eTesting_cypress__/cypress/e2e/home.cy.ts.ejs +6 -0
- package/templates/__when_e2eTesting_cypress__/cypress.config.ts.ejs +8 -0
- package/templates/__when_e2eTesting_playwright__/playwright.config.ts.ejs +16 -0
- package/templates/__when_e2eTesting_playwright__/tests/e2e/home.spec.ts.ejs +6 -0
- package/templates/__when_formatting_prettier__/.prettierrc +7 -0
- package/templates/__when_formatting_stylelint__/.stylelintrc.json +3 -0
- package/templates/__when_linting_biome__/biome.json +19 -0
- package/templates/__when_linting_eslint__/eslint.config.js.ejs +42 -0
- package/templates/__when_serverState_rtk-query__/src/store/postsApi.ts.ejs +19 -0
- package/templates/__when_stateManagement_context__/src/store/context.tsx.ejs +57 -0
- package/templates/__when_styling_tailwind__/postcss.config.js +6 -0
- package/templates/__when_styling_tailwind__/tailwind.config.js.ejs +23 -0
- package/templates/__when_unitTesting_jest__/jest.config.json.ejs +11 -0
- package/templates/__when_unitTesting_jest__/tests/App.test.tsx.ejs +13 -0
- package/templates/__when_unitTesting_jest__/tests/setup.ts.ejs +1 -0
- package/templates/__when_unitTesting_jest__/tests/styleMock.ts.ejs +1 -0
- package/templates/__when_unitTesting_rtl__/tests/App.test.tsx.ejs +13 -0
- package/templates/__when_unitTesting_vitest__/tests/App.test.tsx.ejs +16 -0
- package/templates/__when_unitTesting_vitest__/tests/setup.ts.ejs +1 -0
- package/templates/__when_visualTesting_storybook__/.storybook/main.js.ejs +11 -0
- package/templates/__when_visualTesting_storybook__/.storybook/preview.js +8 -0
- package/templates/__when_visualTesting_storybook__/src/components/ui/UiButton.stories.tsx.ejs +15 -0
- package/templates/commitlint.config.js +3 -0
- package/templates/docs/architecture.md.ejs +74 -0
- package/templates/docs/best-practices.md.ejs +56 -0
- package/templates/docs/examples/README.md.ejs +14 -0
- package/templates/docs/examples/api.md.ejs +17 -0
- package/templates/docs/examples/data-fetching.md.ejs +18 -0
- package/templates/docs/examples/forms.md.ejs +18 -0
- package/templates/docs/examples/state.md.ejs +17 -0
- package/templates/docs/examples/styling.md.ejs +23 -0
- package/templates/docs/examples/testing.md.ejs +27 -0
- package/templates/docs/getting-started.md.ejs +55 -0
- package/templates/docs/selected-stack.md.ejs +55 -0
- package/templates/index.html.ejs +19 -0
- package/templates/public/vite.svg +4 -0
- package/templates/src/app/App.tsx.ejs +71 -0
- package/templates/src/app/providers.tsx.ejs +93 -0
- package/templates/src/assets/.gitkeep +0 -0
- package/templates/src/components/StackBadge.tsx.ejs +15 -0
- package/templates/src/components/layout/AppLayout.tsx.ejs +64 -0
- package/templates/src/components/ui/Toast.tsx.ejs +61 -0
- package/templates/src/components/ui/UiButton.tsx.ejs +168 -0
- package/templates/src/config/env.ts.ejs +18 -0
- package/templates/src/features/counter/CounterPanel.tsx.ejs +66 -0
- package/templates/src/features/feedback/FeedbackForm.tsx.ejs +373 -0
- package/templates/src/features/posts/PostsPanel.tsx.ejs +91 -0
- package/templates/src/hooks/useMounted.ts.ejs +15 -0
- package/templates/src/lib/cn.ts.ejs +12 -0
- package/templates/src/lib/monitoring.ts.ejs +66 -0
- package/templates/src/lib/validation.ts.ejs +81 -0
- package/templates/src/main.tsx.ejs +22 -0
- package/templates/src/routes/AboutPage.tsx.ejs +30 -0
- package/templates/src/routes/HomePage.tsx.ejs +47 -0
- package/templates/src/services/api.ts.ejs +84 -0
- package/templates/src/store/index.ts.ejs +80 -0
- package/templates/src/styles/global.css.ejs +457 -0
- package/templates/src/types/index.ts.ejs +7 -0
- package/templates/src/utils/format.ts.ejs +3 -0
package/package.json
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "create-react-starter-kit",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Interactive CLI to scaffold a production-ready React app with your preferred stack",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"react",
|
|
7
|
+
"starter-kit",
|
|
8
|
+
"boilerplate",
|
|
9
|
+
"scaffold",
|
|
10
|
+
"cli",
|
|
11
|
+
"create-react-app",
|
|
12
|
+
"vite",
|
|
13
|
+
"typescript",
|
|
14
|
+
"generator"
|
|
15
|
+
],
|
|
16
|
+
"author": "",
|
|
17
|
+
"license": "MIT",
|
|
18
|
+
"type": "module",
|
|
19
|
+
"bin": {
|
|
20
|
+
"create-react-starter-kit": "./bin/create-react-starter-kit.js"
|
|
21
|
+
},
|
|
22
|
+
"files": [
|
|
23
|
+
"bin",
|
|
24
|
+
"dist",
|
|
25
|
+
"templates"
|
|
26
|
+
],
|
|
27
|
+
"scripts": {
|
|
28
|
+
"build": "tsc && node scripts/copy-templates.mjs",
|
|
29
|
+
"dev": "tsc --watch",
|
|
30
|
+
"start": "node bin/create-react-starter-kit.js",
|
|
31
|
+
"validate": "npm run build && node scripts/validate-cli.mjs",
|
|
32
|
+
"prepublishOnly": "npm run build",
|
|
33
|
+
"typecheck": "tsc --noEmit"
|
|
34
|
+
},
|
|
35
|
+
"engines": {
|
|
36
|
+
"node": ">=18"
|
|
37
|
+
},
|
|
38
|
+
"dependencies": {
|
|
39
|
+
"chalk": "^5.4.1",
|
|
40
|
+
"ejs": "^3.1.10",
|
|
41
|
+
"execa": "^9.5.2",
|
|
42
|
+
"fs-extra": "^11.3.0",
|
|
43
|
+
"inquirer": "^12.4.2",
|
|
44
|
+
"ora": "^8.2.0",
|
|
45
|
+
"validate-npm-package-name": "^6.0.0"
|
|
46
|
+
},
|
|
47
|
+
"devDependencies": {
|
|
48
|
+
"@types/ejs": "^3.1.5",
|
|
49
|
+
"@types/fs-extra": "^11.0.4",
|
|
50
|
+
"@types/node": "^22.13.10",
|
|
51
|
+
"@types/validate-npm-package-name": "^3.0.3",
|
|
52
|
+
"typescript": "^5.8.2"
|
|
53
|
+
},
|
|
54
|
+
"repository": {
|
|
55
|
+
"type": "git",
|
|
56
|
+
"url": "git+https://github.com/example/create-react-starter-kit.git"
|
|
57
|
+
},
|
|
58
|
+
"bugs": {
|
|
59
|
+
"url": "https://github.com/example/create-react-starter-kit/issues"
|
|
60
|
+
},
|
|
61
|
+
"homepage": "https://github.com/example/create-react-starter-kit#readme"
|
|
62
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# API
|
|
2
|
+
VITE_API_BASE_URL=https://jsonplaceholder.typicode.com
|
|
3
|
+
|
|
4
|
+
<% if (errorTracking === 'sentry') { -%>
|
|
5
|
+
# Sentry
|
|
6
|
+
VITE_SENTRY_DSN=
|
|
7
|
+
<% } -%>
|
|
8
|
+
<% if (errorTracking === 'bugsnag') { -%>
|
|
9
|
+
# Bugsnag
|
|
10
|
+
VITE_BUGSNAG_API_KEY=
|
|
11
|
+
<% } -%>
|
|
12
|
+
<% if (errorTracking === 'logrocket') { -%>
|
|
13
|
+
# LogRocket
|
|
14
|
+
VITE_LOGROCKET_APP_ID=
|
|
15
|
+
<% } -%>
|
|
16
|
+
<% if (errorTracking === 'datadog') { -%>
|
|
17
|
+
# Datadog RUM
|
|
18
|
+
VITE_DATADOG_APPLICATION_ID=
|
|
19
|
+
VITE_DATADOG_CLIENT_TOKEN=
|
|
20
|
+
VITE_DATADOG_SITE=datadoghq.com
|
|
21
|
+
<% } -%>
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
# <%= projectName %>
|
|
2
|
+
|
|
3
|
+
Production-ready React starter generated by **create-react-starter-kit**.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
This app ships with a curated stack chosen during scaffolding, a working demo page, and documentation so you can extend the project without re-wiring libraries by hand.
|
|
8
|
+
|
|
9
|
+
## Selected stack
|
|
10
|
+
|
|
11
|
+
| Area | Choice |
|
|
12
|
+
|------|--------|
|
|
13
|
+
| Build tool | <%= stackLabels.buildTool %> |
|
|
14
|
+
| Language | <%= stackLabels.language %> |
|
|
15
|
+
| Routing | <%= stackLabels.router %> |
|
|
16
|
+
| State | <%= stackLabels.stateManagement %> |
|
|
17
|
+
| Server state | <%= stackLabels.serverState %> |
|
|
18
|
+
| Forms | <%= stackLabels.forms %> |
|
|
19
|
+
| Validation | <%= stackLabels.validation %> |
|
|
20
|
+
| Styling | <%= stackLabels.styling %> |
|
|
21
|
+
| UI library | <%= stackLabels.uiLibrary %> |
|
|
22
|
+
| Unit tests | <%= stackLabels.unitTesting %> |
|
|
23
|
+
| E2E tests | <%= stackLabels.e2eTesting %> |
|
|
24
|
+
| Visual | <%= stackLabels.visualTesting %> |
|
|
25
|
+
| Linting | <%= stackLabels.linting %> |
|
|
26
|
+
| Formatting | <%= stackLabels.formatting %> |
|
|
27
|
+
| API layer | <%= stackLabels.apiLayer %> |
|
|
28
|
+
| Package manager | <%= stackLabels.packageManager %> |
|
|
29
|
+
| Error tracking | <%= stackLabels.errorTracking %> |
|
|
30
|
+
| Git hooks | Husky + lint-staged + commitlint |
|
|
31
|
+
| Structure | Feature-based (domain-driven) + `@/` aliases |
|
|
32
|
+
|
|
33
|
+
## Quick start
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
<% if (packageManager === 'pnpm') { -%>
|
|
37
|
+
pnpm install
|
|
38
|
+
pnpm dev
|
|
39
|
+
<% } else if (packageManager === 'yarn') { -%>
|
|
40
|
+
yarn
|
|
41
|
+
yarn dev
|
|
42
|
+
<% } else { -%>
|
|
43
|
+
npm install
|
|
44
|
+
npm run dev
|
|
45
|
+
<% } -%>
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
Open the URL printed in the terminal (typically `http://localhost:5173`).
|
|
49
|
+
|
|
50
|
+
## Environment setup
|
|
51
|
+
|
|
52
|
+
1. Copy `.env.example` to `.env`.
|
|
53
|
+
2. Fill in API and monitoring keys as needed.
|
|
54
|
+
3. Never commit secrets — `.env` is gitignored.
|
|
55
|
+
|
|
56
|
+
| Variable | Purpose |
|
|
57
|
+
|----------|---------|
|
|
58
|
+
| `VITE_API_BASE_URL` | REST API base URL |
|
|
59
|
+
<% if (errorTracking === 'sentry') { -%>
|
|
60
|
+
| `VITE_SENTRY_DSN` | Sentry DSN |
|
|
61
|
+
<% } -%>
|
|
62
|
+
<% if (errorTracking === 'bugsnag') { -%>
|
|
63
|
+
| `VITE_BUGSNAG_API_KEY` | Bugsnag API key |
|
|
64
|
+
<% } -%>
|
|
65
|
+
<% if (errorTracking === 'logrocket') { -%>
|
|
66
|
+
| `VITE_LOGROCKET_APP_ID` | LogRocket app id |
|
|
67
|
+
<% } -%>
|
|
68
|
+
<% if (errorTracking === 'datadog') { -%>
|
|
69
|
+
| `VITE_DATADOG_APPLICATION_ID` | Datadog application id |
|
|
70
|
+
| `VITE_DATADOG_CLIENT_TOKEN` | Datadog client token |
|
|
71
|
+
<% } -%>
|
|
72
|
+
|
|
73
|
+
## Folder structure
|
|
74
|
+
|
|
75
|
+
```text
|
|
76
|
+
src/
|
|
77
|
+
app/ # App shell, providers, bootstrap
|
|
78
|
+
assets/ # Images / media imported from code
|
|
79
|
+
components/ # Shared UI (layout/, ui/)
|
|
80
|
+
config/ # Env helpers / app config
|
|
81
|
+
features/ # Domain modules (scalable default)
|
|
82
|
+
hooks/ # Shared hooks
|
|
83
|
+
lib/ # Third-party wrappers / helpers
|
|
84
|
+
routes/ # Route-level pages
|
|
85
|
+
store/ # Client state
|
|
86
|
+
services/ # API clients
|
|
87
|
+
styles/ # Global styles
|
|
88
|
+
types/ # Shared types
|
|
89
|
+
utils/ # Pure helpers
|
|
90
|
+
docs/ # Architecture & usage docs
|
|
91
|
+
tests/ # Extra test helpers / e2e
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
Organization: **feature-based / domain-driven** with `@/` path aliases. See `docs/architecture.md`.
|
|
95
|
+
|
|
96
|
+
## Scripts
|
|
97
|
+
|
|
98
|
+
| Script | Description |
|
|
99
|
+
|--------|-------------|
|
|
100
|
+
| `dev` | Start development server |
|
|
101
|
+
| `build` | Production build |
|
|
102
|
+
<% if (unitTesting !== 'none') { -%>
|
|
103
|
+
| `test` | Unit tests |
|
|
104
|
+
<% } -%>
|
|
105
|
+
<% if (e2eTesting !== 'none') { -%>
|
|
106
|
+
| `test:e2e` | End-to-end tests |
|
|
107
|
+
<% } -%>
|
|
108
|
+
| `lint` | Lint the codebase |
|
|
109
|
+
| `format` | Format sources |
|
|
110
|
+
<% if (visualTesting === 'storybook') { -%>
|
|
111
|
+
| `storybook` | Component workshop |
|
|
112
|
+
<% } -%>
|
|
113
|
+
|
|
114
|
+
## Technology explanations
|
|
115
|
+
|
|
116
|
+
Each selected library includes:
|
|
117
|
+
|
|
118
|
+
- a live example on the home/demo page
|
|
119
|
+
- a short doc under `docs/examples/`
|
|
120
|
+
- when-to-use guidance and a best-practice note
|
|
121
|
+
|
|
122
|
+
Start with `docs/selected-stack.md` and `docs/getting-started.md`.
|
|
123
|
+
|
|
124
|
+
## Example usage
|
|
125
|
+
|
|
126
|
+
The demo page (`/`) shows:
|
|
127
|
+
|
|
128
|
+
- navigation + layout
|
|
129
|
+
<% if (stateManagement !== 'none') { -%>
|
|
130
|
+
- client state (<%= stackLabels.stateManagement %>)
|
|
131
|
+
<% } -%>
|
|
132
|
+
<% if (serverState !== 'none') { -%>
|
|
133
|
+
- data fetching (<%= stackLabels.serverState %>)
|
|
134
|
+
<% } -%>
|
|
135
|
+
<% if (forms !== 'none') { -%>
|
|
136
|
+
- forms (<%= stackLabels.forms %>)
|
|
137
|
+
<% } -%>
|
|
138
|
+
<% if (validation !== 'none') { -%>
|
|
139
|
+
- validation (<%= stackLabels.validation %>)
|
|
140
|
+
<% } -%>
|
|
141
|
+
- styling (<%= stackLabels.styling %>)
|
|
142
|
+
<% if (uiLibrary !== 'none') { -%>
|
|
143
|
+
- UI primitives (<%= stackLabels.uiLibrary %>)
|
|
144
|
+
<% } -%>
|
|
145
|
+
- API integration (<%= stackLabels.apiLayer %>)
|
|
146
|
+
|
|
147
|
+
## Production best practices
|
|
148
|
+
|
|
149
|
+
- Keep secrets out of the client bundle; only expose `VITE_*` (or equivalent) public vars.
|
|
150
|
+
- Prefer feature folders for domain logic; keep `components/` shared and dumb.
|
|
151
|
+
- Gate monitoring behind environment checks.
|
|
152
|
+
- Run lint + unit + e2e in CI before merge.
|
|
153
|
+
- See `docs/best-practices.md` for deeper guidance.
|
|
154
|
+
|
|
155
|
+
## Troubleshooting
|
|
156
|
+
|
|
157
|
+
| Issue | Fix |
|
|
158
|
+
|-------|-----|
|
|
159
|
+
| Port in use | Change the port in your build tool config or kill the process |
|
|
160
|
+
| Module not found | Re-run install with <%= packageManager %> |
|
|
161
|
+
| Env vars undefined | Restart the dev server after editing `.env` |
|
|
162
|
+
| Tailwind classes missing | Confirm `content` paths in `tailwind.config` |
|
|
163
|
+
| Type errors | Run `<%= packageManager === 'npm' ? 'npx' : packageManager %> tsc --noEmit` |
|
|
164
|
+
|
|
165
|
+
More help: `docs/getting-started.md`.
|
|
166
|
+
|
|
167
|
+
---
|
|
168
|
+
|
|
169
|
+
Generated with [create-react-starter-kit](https://www.npmjs.com/package/create-react-starter-kit) · <%= year %>
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/// <reference types="vite/client" />
|
|
2
|
+
|
|
3
|
+
interface ImportMetaEnv {
|
|
4
|
+
readonly VITE_API_BASE_URL?: string;
|
|
5
|
+
readonly VITE_SENTRY_DSN?: string;
|
|
6
|
+
readonly VITE_BUGSNAG_API_KEY?: string;
|
|
7
|
+
readonly VITE_LOGROCKET_APP_ID?: string;
|
|
8
|
+
readonly VITE_DATADOG_APPLICATION_ID?: string;
|
|
9
|
+
readonly VITE_DATADOG_CLIENT_TOKEN?: string;
|
|
10
|
+
readonly VITE_DATADOG_SITE?: string;
|
|
11
|
+
readonly MODE?: string;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
interface ImportMeta {
|
|
15
|
+
readonly env: ImportMetaEnv;
|
|
16
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2022",
|
|
4
|
+
"useDefineForClassFields": true,
|
|
5
|
+
"lib": ["ES2022", "DOM", "DOM.Iterable"],
|
|
6
|
+
"module": "ESNext",
|
|
7
|
+
"skipLibCheck": true,
|
|
8
|
+
"moduleResolution": "bundler",
|
|
9
|
+
"allowImportingTsExtensions": true,
|
|
10
|
+
"resolveJsonModule": true,
|
|
11
|
+
"isolatedModules": true,
|
|
12
|
+
"noEmit": true,
|
|
13
|
+
"jsx": "react-jsx",
|
|
14
|
+
"strict": true,
|
|
15
|
+
"noUnusedLocals": true,
|
|
16
|
+
"noUnusedParameters": true,
|
|
17
|
+
"noFallthroughCasesInSwitch": true,
|
|
18
|
+
"baseUrl": ".",
|
|
19
|
+
"paths": {
|
|
20
|
+
"@/*": ["src/*"]
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
"include": ["src", "tests"]
|
|
24
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import * as esbuild from 'esbuild';
|
|
3
|
+
|
|
4
|
+
await esbuild.build({
|
|
5
|
+
entryPoints: ['src/main.<%= jsxExt %>'],
|
|
6
|
+
bundle: true,
|
|
7
|
+
outfile: 'dist/main.js',
|
|
8
|
+
format: 'esm',
|
|
9
|
+
minify: true,
|
|
10
|
+
sourcemap: true,
|
|
11
|
+
alias: {
|
|
12
|
+
'@': path.resolve('src'),
|
|
13
|
+
},
|
|
14
|
+
loader: {
|
|
15
|
+
'.<%= jsxExt %>': '<%= isTypeScript ? 'tsx' : 'jsx' %>',
|
|
16
|
+
'.css': 'css',
|
|
17
|
+
},
|
|
18
|
+
define: {
|
|
19
|
+
'process.env.NODE_ENV': '"production"',
|
|
20
|
+
},
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
console.log('Built dist/main.js');
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import * as esbuild from 'esbuild';
|
|
2
|
+
import { createServer } from 'node:http';
|
|
3
|
+
import { readFileSync, existsSync } from 'node:fs';
|
|
4
|
+
import path from 'node:path';
|
|
5
|
+
|
|
6
|
+
const ctx = await esbuild.context({
|
|
7
|
+
entryPoints: ['src/main.<%= jsxExt %>'],
|
|
8
|
+
bundle: true,
|
|
9
|
+
outfile: 'dist/main.js',
|
|
10
|
+
format: 'esm',
|
|
11
|
+
sourcemap: true,
|
|
12
|
+
alias: {
|
|
13
|
+
'@': path.resolve('src'),
|
|
14
|
+
},
|
|
15
|
+
loader: {
|
|
16
|
+
'.<%= jsxExt %>': '<%= isTypeScript ? 'tsx' : 'jsx' %>',
|
|
17
|
+
'.css': 'css',
|
|
18
|
+
},
|
|
19
|
+
define: {
|
|
20
|
+
'process.env.NODE_ENV': '"development"',
|
|
21
|
+
},
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
await ctx.watch();
|
|
25
|
+
|
|
26
|
+
const server = createServer((req, res) => {
|
|
27
|
+
const url = req.url === '/' ? '/index.html' : req.url;
|
|
28
|
+
const filePath = path.join(process.cwd(), url.startsWith('/dist') ? '.' : '', url === '/index.html' ? 'index.html' : url.slice(1));
|
|
29
|
+
const resolved = url === '/index.html' ? path.join(process.cwd(), 'index.html') : path.join(process.cwd(), url.slice(1));
|
|
30
|
+
if (!existsSync(resolved)) {
|
|
31
|
+
res.writeHead(404);
|
|
32
|
+
res.end('Not found');
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
const content = readFileSync(resolved);
|
|
36
|
+
const type = resolved.endsWith('.js')
|
|
37
|
+
? 'text/javascript'
|
|
38
|
+
: resolved.endsWith('.css')
|
|
39
|
+
? 'text/css'
|
|
40
|
+
: 'text/html';
|
|
41
|
+
res.writeHead(200, { 'Content-Type': type });
|
|
42
|
+
res.end(content);
|
|
43
|
+
void filePath;
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
server.listen(5173, () => {
|
|
47
|
+
console.log('esbuild app at http://localhost:5173');
|
|
48
|
+
});
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import alias from '@rollup/plugin-alias';
|
|
3
|
+
import resolve from '@rollup/plugin-node-resolve';
|
|
4
|
+
import commonjs from '@rollup/plugin-commonjs';
|
|
5
|
+
import replace from '@rollup/plugin-replace';
|
|
6
|
+
<% if (isTypeScript) { -%>
|
|
7
|
+
import typescript from '@rollup/plugin-typescript';
|
|
8
|
+
<% } -%>
|
|
9
|
+
import postcss from 'rollup-plugin-postcss';
|
|
10
|
+
|
|
11
|
+
export default {
|
|
12
|
+
input: 'src/main.<%= jsxExt %>',
|
|
13
|
+
output: {
|
|
14
|
+
file: 'dist/main.js',
|
|
15
|
+
format: 'esm',
|
|
16
|
+
sourcemap: true,
|
|
17
|
+
},
|
|
18
|
+
plugins: [
|
|
19
|
+
alias({
|
|
20
|
+
entries: [{ find: '@', replacement: path.resolve('src') }],
|
|
21
|
+
}),
|
|
22
|
+
replace({
|
|
23
|
+
preventAssignment: true,
|
|
24
|
+
'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV || 'development'),
|
|
25
|
+
}),
|
|
26
|
+
resolve({ browser: true, extensions: ['.<%= jsxExt %>', '.<%= ext %>', '.js', '.jsx'] }),
|
|
27
|
+
commonjs(),
|
|
28
|
+
<% if (isTypeScript) { -%>
|
|
29
|
+
typescript({ tsconfig: './tsconfig.json' }),
|
|
30
|
+
<% } -%>
|
|
31
|
+
postcss({ extract: true }),
|
|
32
|
+
],
|
|
33
|
+
};
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import { defineConfig } from '@rspack/cli';
|
|
3
|
+
import { HtmlRspackPlugin } from '@rspack/core';
|
|
4
|
+
|
|
5
|
+
export default defineConfig({
|
|
6
|
+
entry: {
|
|
7
|
+
main: './src/main.<%= jsxExt %>',
|
|
8
|
+
},
|
|
9
|
+
resolve: {
|
|
10
|
+
alias: {
|
|
11
|
+
'@': path.resolve('src'),
|
|
12
|
+
},
|
|
13
|
+
},
|
|
14
|
+
builtins: {
|
|
15
|
+
react: {
|
|
16
|
+
runtime: 'automatic',
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
module: {
|
|
20
|
+
rules: [
|
|
21
|
+
{
|
|
22
|
+
test: /\.css$/,
|
|
23
|
+
type: 'css',
|
|
24
|
+
},
|
|
25
|
+
],
|
|
26
|
+
},
|
|
27
|
+
plugins: [
|
|
28
|
+
new HtmlRspackPlugin({
|
|
29
|
+
template: './index.html',
|
|
30
|
+
}),
|
|
31
|
+
],
|
|
32
|
+
devServer: {
|
|
33
|
+
port: 5173,
|
|
34
|
+
historyApiFallback: true,
|
|
35
|
+
},
|
|
36
|
+
});
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import { fileURLToPath } from 'node:url';
|
|
3
|
+
import { defineConfig } from 'vite';
|
|
4
|
+
import react from '@vitejs/plugin-react';
|
|
5
|
+
<% if (unitTesting === 'vitest') { -%>
|
|
6
|
+
import { defineConfig as defineVitestConfig, mergeConfig } from 'vitest/config';
|
|
7
|
+
<% } -%>
|
|
8
|
+
|
|
9
|
+
const rootDir = path.dirname(fileURLToPath(import.meta.url));
|
|
10
|
+
|
|
11
|
+
const viteConfig = defineConfig({
|
|
12
|
+
plugins: [react()],
|
|
13
|
+
resolve: {
|
|
14
|
+
alias: {
|
|
15
|
+
'@': path.resolve(rootDir, 'src'),
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
server: {
|
|
19
|
+
port: 5173,
|
|
20
|
+
},
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
<% if (unitTesting === 'vitest') { -%>
|
|
24
|
+
export default mergeConfig(
|
|
25
|
+
viteConfig,
|
|
26
|
+
defineVitestConfig({
|
|
27
|
+
test: {
|
|
28
|
+
globals: true,
|
|
29
|
+
environment: 'jsdom',
|
|
30
|
+
setupFiles: './tests/setup.<%= ext %>',
|
|
31
|
+
exclude: ['**/node_modules/**', '**/dist/**', '**/e2e/**', '**/*.e2e.*'],
|
|
32
|
+
},
|
|
33
|
+
}),
|
|
34
|
+
);
|
|
35
|
+
<% } else { -%>
|
|
36
|
+
export default viteConfig;
|
|
37
|
+
<% } -%>
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
<% if (isTypeScript) { -%>
|
|
2
|
+
import type { Configuration } from 'webpack';
|
|
3
|
+
import type { Configuration as DevServerConfiguration } from 'webpack-dev-server';
|
|
4
|
+
<% } -%>
|
|
5
|
+
import path from 'node:path';
|
|
6
|
+
import HtmlWebpackPlugin from 'html-webpack-plugin';
|
|
7
|
+
|
|
8
|
+
<% if (isTypeScript) { -%>
|
|
9
|
+
const config: Configuration & { devServer?: DevServerConfiguration } = {
|
|
10
|
+
<% } else { -%>
|
|
11
|
+
const config = {
|
|
12
|
+
<% } -%>
|
|
13
|
+
entry: './src/main.<%= jsxExt %>',
|
|
14
|
+
output: {
|
|
15
|
+
path: path.resolve('dist'),
|
|
16
|
+
filename: '[name].[contenthash].js',
|
|
17
|
+
clean: true,
|
|
18
|
+
publicPath: '/',
|
|
19
|
+
},
|
|
20
|
+
resolve: {
|
|
21
|
+
extensions: ['.<%= jsxExt %>', '.<%= ext %>', '.js', '.jsx', '.json'],
|
|
22
|
+
alias: {
|
|
23
|
+
'@': path.resolve('src'),
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
module: {
|
|
27
|
+
rules: [
|
|
28
|
+
{
|
|
29
|
+
test: /\.(<%= isTypeScript ? 'ts|tsx' : 'js|jsx' %>)$/,
|
|
30
|
+
exclude: /node_modules/,
|
|
31
|
+
use: {
|
|
32
|
+
loader: 'babel-loader',
|
|
33
|
+
options: {
|
|
34
|
+
presets: [
|
|
35
|
+
'@babel/preset-env',
|
|
36
|
+
['@babel/preset-react', { runtime: 'automatic' }],
|
|
37
|
+
<% if (isTypeScript) { -%>
|
|
38
|
+
'@babel/preset-typescript',
|
|
39
|
+
<% } -%>
|
|
40
|
+
],
|
|
41
|
+
},
|
|
42
|
+
},
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
test: /\.css$/,
|
|
46
|
+
use: ['style-loader', 'css-loader'<% if (styling === 'sass') { %>, 'sass-loader'<% } %>],
|
|
47
|
+
},
|
|
48
|
+
<% if (styling === 'sass') { -%>
|
|
49
|
+
{
|
|
50
|
+
test: /\.scss$/,
|
|
51
|
+
use: ['style-loader', 'css-loader', 'sass-loader'],
|
|
52
|
+
},
|
|
53
|
+
<% } -%>
|
|
54
|
+
],
|
|
55
|
+
},
|
|
56
|
+
plugins: [
|
|
57
|
+
new HtmlWebpackPlugin({
|
|
58
|
+
template: './index.html',
|
|
59
|
+
}),
|
|
60
|
+
],
|
|
61
|
+
devServer: {
|
|
62
|
+
port: 5173,
|
|
63
|
+
historyApiFallback: true,
|
|
64
|
+
hot: true,
|
|
65
|
+
},
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
export default config;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { defineConfig, devices } from '@playwright/test';
|
|
2
|
+
|
|
3
|
+
export default defineConfig({
|
|
4
|
+
testDir: './tests/e2e',
|
|
5
|
+
fullyParallel: true,
|
|
6
|
+
use: {
|
|
7
|
+
baseURL: 'http://127.0.0.1:5173',
|
|
8
|
+
trace: 'on-first-retry',
|
|
9
|
+
},
|
|
10
|
+
webServer: {
|
|
11
|
+
command: '<%= packageManager === 'npm' ? 'npm run dev' : packageManager + ' dev' %>',
|
|
12
|
+
url: 'http://127.0.0.1:5173',
|
|
13
|
+
reuseExistingServer: !process.env.CI,
|
|
14
|
+
},
|
|
15
|
+
projects: [{ name: 'chromium', use: { ...devices['Desktop Chrome'] } }],
|
|
16
|
+
});
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://biomejs.dev/schemas/1.9.4/schema.json",
|
|
3
|
+
"organizeImports": { "enabled": true },
|
|
4
|
+
"linter": {
|
|
5
|
+
"enabled": true,
|
|
6
|
+
"rules": {
|
|
7
|
+
"recommended": true
|
|
8
|
+
}
|
|
9
|
+
},
|
|
10
|
+
"formatter": {
|
|
11
|
+
"enabled": true,
|
|
12
|
+
"indentStyle": "space"
|
|
13
|
+
},
|
|
14
|
+
"javascript": {
|
|
15
|
+
"formatter": {
|
|
16
|
+
"quoteStyle": "single"
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}
|