@@ -5,6 +5,8 @@ import { run, createFolder, deleteFile } from './lib/utils.js';
55import { initializePWA } from './lib/pwa.js' ;
66import { setupCSSFramework } from './lib/css-frameworks.js' ;
77import { createAxiosSetup , createAppComponent , setupRouterMain , createPWAReadme } from './lib/templates.js' ;
8+ import { setupTestingFramework } from './lib/testing.js' ;
9+ import { setupDevTools } from './lib/dev-tools.js' ;
810
911( async ( ) => {
1012 // 1. Collect user inputs
@@ -26,6 +28,17 @@ import { createAxiosSetup, createAppComponent, setupRouterMain, createPWAReadme
2628 message : "Do you want to make this a Progressive Web App (PWA)?" ,
2729 default : false
2830 } ,
31+ {
32+ type : "list" ,
33+ name : "testingFramework" ,
34+ message : "Choose a testing framework:" ,
35+ choices : [
36+ { name : "None" , value : "none" } ,
37+ { name : "Vitest + React Testing Library" , value : "vitest" } ,
38+ { name : "Jest + React Testing Library" , value : "jest" } ,
39+ { name : "Cypress (E2E)" , value : "cypress" }
40+ ]
41+ } ,
2942 {
3043 type : "checkbox" ,
3144 name : "packages" ,
@@ -36,65 +49,130 @@ import { createAxiosSetup, createAppComponent, setupRouterMain, createPWAReadme
3649 { name : "React Hook Form" , value : "react-hook-form" } ,
3750 { name : "Yup" , value : "yup" } ,
3851 { name : "Formik" , value : "formik" } ,
39- { name : "Moment.js" , value : "moment" }
52+ { name : "Moment.js" , value : "moment" } ,
53+ { name : "Zustand (State Management)" , value : "zustand" } ,
54+ { name : "TanStack Query" , value : "@tanstack/react-query" } ,
55+ { name : "Framer Motion" , value : "framer-motion" } ,
56+ { name : "React Helmet (SEO)" , value : "react-helmet-async" }
57+ ]
58+ } ,
59+ {
60+ type : "checkbox" ,
61+ name : "devTools" ,
62+ message : "Select development tools:" ,
63+ choices : [
64+ { name : "ESLint + Prettier" , value : "eslint-prettier" } ,
65+ { name : "Husky (Git Hooks)" , value : "husky" } ,
66+ { name : "Commitizen (Conventional Commits)" , value : "commitizen" }
4067 ]
4168 }
4269 ] ) ;
4370
44- const { projectName, cssFramework, isPWA, packages } = answers ;
71+ const { projectName, cssFramework, isPWA, testingFramework , packages, devTools } = answers ;
4572 const projectPath = path . join ( process . cwd ( ) , projectName ) ;
4673
4774 console . log ( `\n🚀 Creating ${ projectName } ${ isPWA ? ' with PWA capabilities' : '' } ...` ) ;
4875
4976 // 2. Create Vite project
5077 run ( `npm create vite@latest ${ projectName } -- --template react` ) ;
5178
52- // 3. Create all necessary folder structure first
53- const folders = [ "components" , "pages" , "hooks" , "store" , "utils" , "assets" ] ;
54- folders . forEach ( ( folder ) => {
55- createFolder ( path . join ( projectPath , "src" , folder ) ) ;
56- } ) ;
79+ // 3. Setup CSS framework
80+ setupCSSFramework ( cssFramework , projectPath ) ;
81+
82+ // 4. Setup testing framework
83+ if ( testingFramework !== "none" ) {
84+ setupTestingFramework ( testingFramework , projectPath ) ;
85+ }
5786
58- // 4. Install packages
87+ // 5. Install PWA functionality
88+ if ( isPWA ) {
89+ initializePWA ( projectPath , projectName ) ;
90+ }
91+
92+ // 6. Install packages with legacy peer deps for compatibility
5993 const defaultPackages = [ "react-router-dom" ] ;
6094 const allPackages = [ ...defaultPackages , ...packages ] ;
6195 if ( allPackages . length > 0 ) {
62- run ( `npm install ${ allPackages . join ( " " ) } ` , projectPath ) ;
96+ run ( `npm install ${ allPackages . join ( " " ) } --legacy-peer-deps ` , projectPath ) ;
6397 }
6498
65- // 5 . Setup PWA if selected (after folder structure is created)
66- if ( isPWA ) {
67- initializePWA ( projectPath , projectName ) ;
99+ // 7 . Setup development tools
100+ if ( devTools . length > 0 ) {
101+ setupDevTools ( devTools , projectPath , testingFramework ) ;
68102 }
69103
70- // 6. Setup CSS framework
71- setupCSSFramework ( cssFramework , projectPath ) ;
104+ // 8. Create folder structure
105+ const folders = [ "components" , "pages" , "hooks" , "store" , "utils" , "assets" ] ;
106+ folders . forEach ( ( folder ) => {
107+ createFolder ( path . join ( projectPath , "src" , folder ) ) ;
108+ } ) ;
72109
73- // 7 . Setup Axios if selected
110+ // 9 . Setup Axios if selected
74111 if ( packages . includes ( "axios" ) ) {
75112 createAxiosSetup ( projectPath ) ;
76113 }
77114
78- // 8 . Clean up default boilerplate files
115+ // 10 . Clean up default boilerplate files
79116 deleteFile ( path . join ( projectPath , "src" , "App.css" ) ) ;
80117 if ( cssFramework !== "Tailwind" ) {
81118 deleteFile ( path . join ( projectPath , "src" , "index.css" ) ) ;
82119 }
83120
84- // 9 . Generate clean templates
121+ // 11 . Generate clean templates
85122 createAppComponent ( projectPath , projectName , isPWA ) ;
86123 setupRouterMain ( projectPath , cssFramework ) ;
87124
88- // 10 . Create comprehensive README
125+ // 12 . Create comprehensive README
89126 createPWAReadme ( projectPath , projectName , cssFramework , packages , isPWA ) ;
90127
91- // 11. Success message
128+ // 13. Enhanced success message
92129 console . log ( "\n✅ Setup complete!" ) ;
130+ console . log ( `\n🎉 Your ${ projectName } project is ready!` ) ;
131+ console . log ( `\n📁 Project includes:` ) ;
132+
133+ if ( testingFramework !== "none" ) {
134+ const testingName = testingFramework === "vitest" ? "Vitest" :
135+ testingFramework === "jest" ? "Jest" : "Cypress" ;
136+ console . log ( ` • ${ testingName } testing setup` ) ;
137+ }
138+
139+ if ( devTools . includes ( "eslint-prettier" ) ) {
140+ console . log ( ` • ESLint + Prettier configuration` ) ;
141+ }
142+
143+ if ( devTools . includes ( "husky" ) ) {
144+ console . log ( ` • Husky git hooks` ) ;
145+ }
146+
147+ if ( devTools . includes ( "commitizen" ) ) {
148+ console . log ( ` • Commitizen for conventional commits` ) ;
149+ }
150+
151+ if ( packages . length > 0 ) {
152+ console . log ( ` • Additional packages: ${ packages . join ( ", " ) } ` ) ;
153+ }
154+
93155 if ( isPWA ) {
94- console . log ( "📱 PWA features enabled - your app can be installed on mobile devices!" ) ;
95- console . log ( "⚠️ Important: Replace placeholder SVG icons with proper PNG icons for production" ) ;
156+ console . log ( " • PWA features enabled - your app can be installed on mobile devices!" ) ;
157+ console . log ( " ⚠️ Important: Replace placeholder SVG icons with proper PNG icons for production" ) ;
158+ }
159+
160+ console . log ( `\n🚀 Next steps:` ) ;
161+ console . log ( ` cd ${ projectName } ` ) ;
162+ console . log ( ` npm install` ) ;
163+ console . log ( ` npm run dev` ) ;
164+
165+ if ( testingFramework === "vitest" ) {
166+ console . log ( ` npm test (run tests)` ) ;
167+ } else if ( testingFramework === "jest" ) {
168+ console . log ( ` npm test (run tests)` ) ;
169+ } else if ( testingFramework === "cypress" ) {
170+ console . log ( ` npm run test:e2e (run E2E tests)` ) ;
171+ }
172+
173+ if ( devTools . includes ( "eslint-prettier" ) ) {
174+ console . log ( ` npm run lint (check code quality)` ) ;
96175 }
97- console . log ( `\nNext steps:\n cd ${ projectName } \n npm install\n npm run dev` ) ;
98176
99177 if ( isPWA ) {
100178 console . log ( `\n📱 To test PWA:\n npm run build\n npm run preview\n Open http://localhost:4173 and test install/offline features` ) ;
0 commit comments