Development Setup - gaulatti/autostrada-frontend GitHub Wiki
This guide provides step-by-step instructions for setting up the Autostrada frontend development environment, including configuration, local development, testing, and common workflows.
Before you begin, ensure you have the following installed:
- Node.js (v14.x or later)
- npm (v6.x or later), yarn, or pnpm
- Git for version control
- A code editor like Visual Studio Code (recommended)
- AWS CLI (if working with AWS services locally)
git clone https://github.com/gaulatti/autostrada.git
cd autostrada/frontend
npm install
Create a .env
file in the frontend directory with the following variables:
# API Configuration
VITE_API_FQDN=localhost
VITE_API_PORT=3000
# Authentication
VITE_COGNITO_USER_POOL_ID=your-cognito-pool-id
VITE_COGNITO_CLIENT_ID=your-cognito-client-id
VITE_USER_POOL_DOMAIN=your-cognito-domain
VITE_FQDN=localhost
# Feature Flags
VITE_ENABLE_EXPERIMENTAL_FEATURES=false
For local development, you can use the following options:
- Use a development Cognito user pool (ask a team member for credentials)
- Set up a local mock authentication server (see the "Mock Auth Server" section below)
- Connect to the development API environment
npm run dev
This will start the Vite development server, typically at http://localhost:5173.
The frontend requires a running backend service to function properly. You have several options:
- Follow the setup instructions in the
/service/README.md
to run the backend service locally - Make sure your
.env
file points to the local service:VITE_API_FQDN=localhost VITE_API_PORT=3000
To connect to the development backend:
-
Update your
.env
file with the development API endpoint:VITE_API_FQDN=api-dev.autostrada.example.com # Remove or comment out VITE_API_PORT when using FQDN
-
Obtain development environment credentials from your team lead
For local development without AWS Cognito, you can use a mock authentication server:
-
Install the mock auth server:
npm install --save-dev @autostrada/mock-auth-server
-
Start the mock server:
npx mock-auth-server
-
Update your
.env
file to use the mock auth server:VITE_USE_MOCK_AUTH=true VITE_MOCK_AUTH_URL=http://localhost:9000
-
Use the following test credentials:
- Email:
[email protected]
- Password:
Password123!
- Email:
If you're using the real Cognito user pool:
- Make sure your
.env
file contains the correct Cognito settings - Sign up for an account in the Cognito user pool (or ask for test credentials)
- You might need to confirm your email address before logging in
Understanding the project structure is crucial for effective development:
frontend/
├── app/ # Main application code
│ ├── app.css # Global CSS
│ ├── root.tsx # App root component
│ ├── routes.ts # Route definitions
│ ├── clients/ # API clients
│ ├── components/ # Reusable UI components
│ ├── hooks/ # Custom React hooks
│ ├── layouts/ # Page layout components
│ ├── pages/ # Page components
│ └── state/ # Redux state management
├── public/ # Static assets
├── src/ # Legacy code (being migrated)
├── build/ # Build output
└── locales/ # Internationalization files
-
app/root.tsx
: The entry point of the application, sets up providers -
app/routes.ts
: Route definitions for all pages -
app/clients/api.ts
: API client for communicating with the backend -
app/components/
: Reusable UI components -
app/state/
: Redux store configuration, reducers, and sagas -
app/hooks/
: Custom hooks for data fetching, authentication, etc.
-
Create a new file in the appropriate directory:
touch app/components/my-new-component.tsx
-
Use the following template for your component:
import React from 'react'; import styles from './my-new-component.module.css'; interface MyNewComponentProps { // Define props here } export const MyNewComponent: React.FC<MyNewComponentProps> = (props) => { return ( <div className={styles.container}> {/* Component content */} </div> ); };
-
Create a CSS module file if needed:
touch app/components/my-new-component.module.css
-
Create a new file in the pages directory:
touch app/pages/my-new-page.tsx
-
Add the route to
app/routes.ts
:// Add to the routes array { path: '/my-new-page', element: <PrivateLayout />, children: [ { path: '', element: <MyNewPage />, }, ], }
-
Import your page component where needed
The application uses Redux with Redux Saga for state management:
-
Define a new slice in
app/state/slices/
:// myFeature.slice.ts import { createSlice, PayloadAction } from '@reduxjs/toolkit'; interface MyFeatureState { // Define state shape } const initialState: MyFeatureState = { // Initial state }; const myFeatureSlice = createSlice({ name: 'myFeature', initialState, reducers: { // Define reducers }, }); export const { actions, reducer } = myFeatureSlice;
-
Add your reducer to the root reducer in
app/state/store.ts
-
Create sagas for side effects in
app/state/sagas/
:// myFeature.saga.ts import { takeLatest, put, call } from 'redux-saga/effects'; import { actions } from '../slices/myFeature.slice'; function* handleMyFeatureAction(action) { try { // Perform side effect yield put(actions.success(result)); } catch (error) { yield put(actions.failure(error)); } } export function* myFeatureSaga() { yield takeLatest(actions.request.type, handleMyFeatureAction); }
-
Add your saga to the root saga in
app/state/sagas/index.ts
Autostrada uses Radix UI Themes combined with Tailwind CSS. Here's how to use them:
import { Card, Flex, Text, Button } from '@radix-ui/themes';
function MyComponent() {
return (
<Card className="p-4 max-w-md mx-auto">
<Flex direction="column" gap="3">
<Text size="5" weight="bold">Card Title</Text>
<Text>Card content goes here</Text>
<Button className="bg-brand hover:bg-brand-dark">
Click Me
</Button>
</Flex>
</Card>
);
}
The project uses Jest and React Testing Library for testing:
# Run all tests
npm test
# Run tests in watch mode
npm test -- --watch
# Run tests with coverage
npm test -- --coverage
Create test files with the .test.tsx
extension next to the component:
// my-component.test.tsx
import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { MyComponent } from './my-component';
describe('MyComponent', () => {
it('should render correctly', () => {
render(<MyComponent />);
expect(screen.getByText('Expected Text')).toBeInTheDocument();
});
it('should handle click events', async () => {
const mockFn = jest.fn();
render(<MyComponent onClick={mockFn} />);
await userEvent.click(screen.getByRole('button'));
expect(mockFn).toHaveBeenCalled();
});
});
To create a production build:
npm run build
The output will be in the build/
directory.
To preview the production build locally:
npm run preview
Issue: API connection errors
- Check that the backend service is running
- Verify your
.env
configuration - Check for CORS issues in the browser console
Issue: Authentication failures
- Ensure you're using the correct Cognito credentials
- Check if your token has expired
- Verify the Cognito configuration in
.env
Issue: Build errors
- Run
npm clean-install
to refresh dependencies - Check for TypeScript errors
- Make sure all required environment variables are set
If you encounter issues not covered in this guide:
- Check the project wiki for more detailed documentation
- Ask in the
#frontend-dev
Slack channel - Consult with the frontend team lead
- Code Style: Follow the project's ESLint and Prettier configuration
-
Naming Conventions:
- Components: PascalCase (e.g.,
MyComponent
) - Files: kebab-case (e.g.,
my-component.tsx
) - CSS modules: component-name.module.css
- Components: PascalCase (e.g.,
-
State Management:
- Use local state for UI-specific state
- Use Redux for shared application state
- Use Redux Saga for side effects
-
Performance:
- Memoize expensive calculations
- Use virtualization for long lists
- Lazy load components when appropriate
-
Accessibility:
- Ensure proper ARIA attributes
- Test with keyboard navigation
- Maintain sufficient color contrast
By following this guide, you should be able to set up and work effectively with the Autostrada frontend codebase.