zura-stack-native
Version:
A comprehensive React Native CLI project generator with production-ready setup
180 lines (141 loc) • 5.07 kB
JavaScript
const chalk = require('chalk');
const ora = require('ora');
const { execSync } = require('child_process');
const path = require('path');
class DependencyInstaller {
constructor(config) {
this.config = config;
this.spinner = null;
}
async installAll() {
try {
// Step 1: React Native CLI Management
await this.installReactNativeCLI();
// Step 2: Navigation Setup
await this.installNavigation();
// Step 3: State Management & API
await this.installStateManagement();
// Step 4: UI & Styling Setup
await this.installUIStyling();
// Step 5: Icons & Animations
await this.installIconsAnimations();
// Step 6: Testing (if selected)
if (this.config.testing) {
await this.installTesting();
}
} catch (error) {
this.stopSpinner();
throw new Error(`Dependency installation failed: ${error.message}`);
}
}
async installReactNativeCLI() {
this.startSpinner('Setting up React Native CLI...');
try {
// Uninstall global React Native CLI if exists
execSync('npm uninstall -g react-native-cli @react-native-community/cli', {
stdio: 'pipe'
});
} catch (error) {
// Ignore errors if not installed
}
this.stopSpinner();
}
async installNavigation() {
this.startSpinner('Installing navigation dependencies...');
const commands = [
'npm install @react-navigation/native@6.1.9 @react-navigation/native-stack@6.9.17 @react-navigation/bottom-tabs@6.5.11',
'npm install react-native-screens@3.27.0 react-native-safe-area-context@4.7.4'
];
for (const command of commands) {
execSync(command, {
stdio: this.config.verbose ? 'inherit' : 'pipe',
cwd: this.config.projectPath
});
}
this.stopSpinner();
}
async installStateManagement() {
this.startSpinner('Installing state management and API dependencies...');
const commands = [
'npm install zustand@5.0.6 @tanstack/react-query@5.83.0 axios@1.10.0',
'npm install @react-native-async-storage/async-storage@2.2.0'
];
for (const command of commands) {
execSync(command, {
stdio: this.config.verbose ? 'inherit' : 'pipe',
cwd: this.config.projectPath
});
}
this.stopSpinner();
}
async installUIStyling() {
this.startSpinner('Installing UI and styling dependencies...');
const commands = [
// Install react-dom first (required for Gluestack)
'npm install react-dom@19.1.0',
// Install Gluestack UI CLI and components
'npm install -g @gluestack-ui/cli',
'npx gluestack-ui@latest init',
// Install all Gluestack components
'npx gluestack-ui@latest add accordion actionsheet alert alert-dialog avatar button checkbox divider fab form-control icon image input link menu modal overlay popover pressable progress radio select slider spinner switch textarea toast tooltip',
// Uninstall prettier first
'npm uninstall prettier prettier-plugin-tailwindcss',
// Install NativeWind
'npm install nativewind@4.1.23 tailwindcss@3.4.17',
'npm install react-native-css-interop@0.1.22',
// Install responsive utilities
'npm install react-native-responsive-screen@1.4.2 react-native-responsive-fontsize@0.5.1'
];
for (const command of commands) {
try {
execSync(command, {
stdio: this.config.verbose ? 'inherit' : 'pipe',
cwd: this.config.projectPath
});
} catch (error) {
console.log(chalk.yellow(`⚠️ Command failed: ${command}`));
if (this.config.verbose) {
console.log(chalk.gray(`Error: ${error.message}`));
}
}
}
this.stopSpinner();
}
async installIconsAnimations() {
this.startSpinner('Installing icons and animation dependencies...');
const commands = [
'npm install lucide-react-native@0.525.0',
'npm install react-native-reanimated@3.18.0 react-native-svg@15.12.0'
];
for (const command of commands) {
execSync(command, {
stdio: this.config.verbose ? 'inherit' : 'pipe',
cwd: this.config.projectPath
});
}
this.stopSpinner();
}
async installTesting() {
this.startSpinner('Installing testing dependencies...');
const command = 'npm install --save-dev @testing-library/react-native@13.2.0 @testing-library/jest-native@5.4.3 jest@29.7.0 jest-environment-jsdom@29.7.0 @types/jest@29.5.14 detox@20.40.2';
execSync(command, {
stdio: this.config.verbose ? 'inherit' : 'pipe',
cwd: this.config.projectPath
});
this.stopSpinner();
}
startSpinner(text) {
if (!this.config.verbose) {
this.spinner = ora(text).start();
} else {
console.log(chalk.blue(`🔄 ${text}`));
}
}
stopSpinner() {
if (this.spinner) {
this.spinner.succeed();
this.spinner = null;
}
}
}
module.exports = { DependencyInstaller };