Welcome to our comprehensive workshop on building code into artifacts! This hands-on tutorial will take you through the entire journey from setting up your development environment to building, running, and debugging a React application.
- How to install and set up Node.js and npm
- Creating a React application from scratch
- Managing dependencies with npm
- Building and running applications
- Debugging build errors and understanding build output
- Adding styling with CSS frameworks
- Setting up linting tools and fixing code quality issues
- Best practices for modern web development
By the end of this workshop, you'll have:
- A fully functional React application
- Experience with common build tools and dependencies
- Skills to debug and fix common build issues
- Understanding of code quality tools and linting
- Confidence to start your own projects
- Prerequisites
- Step 1: Installing Node.js and npm
- Step 2: Setting Up Your First React App
- Step 3: Understanding the Project Structure
- Step 4: Running Your Application
- Step 5: Adding Dependencies
- Step 6: Introducing Build Errors (Learning Exercise)
- Step 7: Adding Styling Dependencies
- Step 8: Setting Up Linting
- Step 9: Fixing Linting Errors
- Step 10: Building for Production
- Step 11: Adding Tests with React Testing Library
- Step 12: Setting Up GitHub Actions CI/CD Pipeline
- Troubleshooting
- Next Steps
- A computer with Windows, macOS, or Linux
- Administrator/sudo access for installing software
- A text editor (we recommend Visual Studio Code)
- Basic understanding of HTML, CSS, and JavaScript
- Enthusiasm to learn! π
Node.js is a JavaScript runtime that allows you to run JavaScript outside of a browser. npm (Node Package Manager) comes bundled with Node.js and helps you manage project dependencies.
π‘ Pro Tip: Consider using Node Version Manager (nvm) to manage multiple Node.js versions:
- Windows: Install nvm-windows from https://github.com/coreybutler/nvm-windows
- macOS/Linux: Install nvm from https://github.com/nvm-sh/nvm
With nvm, you can easily switch between Node.js versions:
nvm install --lts nvm use --lts
- Go to https://nodejs.org/
- Download the LTS (Long Term Support) version - this is the most stable
- The website should automatically detect your operating system
Windows:
- Run the downloaded
.msifile - Follow the installation wizard
- Make sure to check "Add to PATH" option
macOS:
- Run the downloaded
.pkgfile - Follow the installation wizard
Linux (Ubuntu/Debian):
curl -fsSL https://deb.nodesource.com/setup_lts.x | sudo -E bash -
sudo apt-get install -y nodejsOpen your terminal/command prompt and run:
node --version
npm --versionYou should see version numbers like:
v18.17.0
9.6.7
π‘ Tip: If you see "command not found" errors, you may need to restart your terminal or add Node.js to your PATH manually.
npm install -g npm@latestReact is a popular JavaScript library for building user interfaces. We'll use Vite, which is a fast, modern build tool that provides an excellent development experience with instant hot module replacement.
npm create vite@latest {your app name}
cd {your app name}
npm installWhen prompted:
- Select "React" as the framework
- Choose "JavaScript" as the variant (or TypeScript if you prefer)
π‘ What is Vite? Vite is a build tool that provides fast development server startup and instant hot module replacement. It's much faster than traditional bundlers and has become the modern standard for React development.
The command above created a new directory with a complete React application powered by Vite. Let's see what was generated:
ls -la
# or on Windows:
dirYou should see files like:
package.json- Project configuration and dependenciespackage-lock.json- Exact dependency versionsnode_modules/- Installed dependenciespublic/- Static filessrc/- Source codeindex.html- Main HTML file (note: this is in the root, not in public/)vite.config.js- Vite configuration
Let's examine the key files in your new React project:
This file contains:
- Project metadata (name, version, description)
- Dependencies (libraries your project needs)
- Scripts (commands you can run)
Open package.json and you'll see something like:
{
"name": "my-build-workshop",
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "vite build",
"lint": "eslint . --ext js,jsx --report-unused-disable-directives --max-warnings 0",
"lint:fix": "eslint . --ext js,jsx --fix",
"preview": "vite preview"
},
"dependencies": {
"react": "^18.2.0",
"react-dom": "^18.2.0"
},
"devDependencies": {
"@vitejs/plugin-react": "^4.2.1",
"eslint": "^8.57.0",
"eslint-plugin-react": "^7.34.1",
"eslint-plugin-react-hooks": "^4.6.0",
"eslint-plugin-react-refresh": "^0.4.6",
"vite": "^5.2.0"
}
}This is your main React component. Open it to see the default React application code.
This is the HTML template where your React app will be mounted. Note that with Vite, this file is in the root directory, not in a public folder.
This file contains Vite-specific configuration for your build process.
npm run devThis command:
- Starts Vite's development server
- Opens your browser automatically (or shows you the URL to visit)
- Watches for file changes and reloads instantly with Hot Module Replacement (HMR)
You should see your React app running at http://localhost:5173 (Vite's default port)
π Congratulations! You've successfully created and run your first React application!
- Open
src/App.jsxin your text editor - Find the text that says "Vite + React" or similar
- Change it to "Welcome to the Build Tools Workshop!"
- Save the file
- Watch the browser automatically reload with your changes instantly
π Amazing! Notice how fast the changes appear - this is Vite's Hot Module Replacement in action!
Real applications need external libraries. Let's add some useful dependencies to our project.
npm install axiosnpm install momentReplace the contents of src/App.jsx with:
import React, { useState, useEffect } from 'react';
import axios from 'axios';
import moment from 'moment';
import './App.css';
function App() {
const [currentTime, setCurrentTime] = useState('');
const [joke, setJoke] = useState('Loading...');
useEffect(() => {
// Update time every second
const timer = setInterval(() => {
setCurrentTime(moment().format('MMMM Do YYYY, h:mm:ss a'));
}, 1000);
// Fetch a programming joke
fetchJoke();
return () => clearInterval(timer);
}, []);
const fetchJoke = async () => {
try {
const response = await axios.get('https://official-joke-api.appspot.com/jokes/programming/random');
setJoke(`${response.data[0].setup} - ${response.data[0].punchline}`);
} catch (error) {
setJoke('Failed to load joke. Check your internet connection!');
}
};
return (
<div className="App">
<header className="App-header">
<h1>π Build Tools Workshop</h1>
<p>Welcome to learning about build tools!</p>
<div className="info-section">
<h2>Current Time</h2>
<p>{currentTime}</p>
</div>
<div className="info-section">
<h2>Programming Joke of the Moment</h2>
<p>{joke}</p>
<button onClick={fetchJoke}>Get New Joke</button>
</div>
</header>
</div>
);
}
export default App;Save the file and check your browser. You should see:
- A live updating clock
- A programming joke that changes when you click the button
Let's intentionally introduce some errors to learn how to read and fix build output.
Replace the fetchJoke function in src/App.jsx with this broken version:
const fetchJoke = async () => {
try {
const response = await axios.get('https://official-joke-api.appspot.com/jokes/programming/random');
setJoke(`${response.data[0].setup} - ${response.data[0].punchline}`);
} catch (error) {
setJoke('Failed to load joke. Check your internet connection!');
}
// Missing closing brace - this will cause an error!Save the file and observe:
- The terminal shows compilation errors
- The browser shows an error overlay
- The error message tells you exactly what's wrong and where
The error output will look something like:
β [ERROR] Expected "}" but found end of file
src/App.jsx:32:1:
32 β }
β΅ ^
The file ends here but we expected to find a closing "}" to match the opening "{" here:
src/App.jsx:20:25:
20 β const fetchJoke = async () => {
β΅ ^
Add the missing } before the catch block:
const fetchJoke = async () => {
try {
const response = await axios.get('https://official-joke-api.appspot.com/jokes/programming/random');
setJoke(`${response.data[0].setup} - ${response.data[0].punchline}`);
} catch (error) {
setJoke('Failed to load joke. Check your internet connection!');
}
};π― Learning Point: Vite provides immediate feedback about errors in your code with clear, helpful error messages. The development server shows errors both in the terminal and in an overlay in your browser. Always read the error messages carefully - they usually tell you exactly what's wrong and where to fix it.
Let's make our app look better by adding a CSS framework.
npm install bootstrapAdd this import to the top of src/App.jsx:
import 'bootstrap/dist/css/bootstrap.min.css';Replace the contents of src/App.css with:
.App {
text-align: center;
min-height: 100vh;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
padding: 2rem;
}
.App-header {
max-width: 800px;
margin: 0 auto;
}
.info-section {
background: rgba(255, 255, 255, 0.1);
border-radius: 10px;
padding: 2rem;
margin: 2rem 0;
backdrop-filter: blur(10px);
border: 1px solid rgba(255, 255, 255, 0.2);
}
.info-section h2 {
color: #ffd700;
margin-bottom: 1rem;
}
.btn-primary {
background: #ff6b6b;
border: none;
padding: 0.75rem 1.5rem;
border-radius: 25px;
font-weight: bold;
transition: all 0.3s ease;
}
.btn-primary:hover {
background: #ff5252;
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(255, 107, 107, 0.3);
}
.time-display {
font-family: 'Courier New', monospace;
font-size: 1.2rem;
background: rgba(0, 0, 0, 0.3);
padding: 1rem;
border-radius: 5px;
display: inline-block;
}
.joke-text {
font-style: italic;
line-height: 1.6;
margin: 1rem 0;
}First, update your imports in src/App.jsx to include Bootstrap:
import React, { useState, useEffect } from 'react';
import axios from 'axios';
import moment from 'moment';
import 'bootstrap/dist/css/bootstrap.min.css';
import './App.css';Then update your App.jsx return statement:
return (
<div className="App">
<header className="App-header">
<h1 className="display-4 mb-4">π Build Tools Workshop</h1>
<p className="lead">Welcome to learning about build tools!</p>
<div className="row">
<div className="col-md-6">
<div className="info-section">
<h2>β° Current Time</h2>
<p className="time-display">{currentTime}</p>
</div>
</div>
<div className="col-md-6">
<div className="info-section">
<h2>π Programming Joke</h2>
<p className="joke-text">{joke}</p>
<button className="btn btn-primary btn-lg" onClick={fetchJoke}>
Get New Joke
</button>
</div>
</div>
</div>
</header>
</div>
);Now your app should look much more professional with Bootstrap styling!
Linting helps maintain code quality by checking for potential errors and enforcing coding standards.
Vite comes with ESLint pre-configured, but let's update to the modern flat config and add additional plugins:
npm install --save-dev @eslint/js eslint-plugin-react eslint-plugin-react-hooks globalsReplace the existing .eslintrc.cjs file with a modern eslint.config.js file (ESLint 9+ flat config format):
import js from '@eslint/js';
import globals from 'globals';
import react from 'eslint-plugin-react';
import reactHooks from 'eslint-plugin-react-hooks';
import reactRefresh from 'eslint-plugin-react-refresh';
export default [
{
ignores: ['dist'],
},
{
files: ['**/*.{js,jsx}'],
languageOptions: {
ecmaVersion: 2020,
globals: {
...globals.browser,
...globals.es2020,
},
parserOptions: {
ecmaVersion: 'latest',
ecmaFeatures: { jsx: true },
sourceType: 'module',
},
},
settings: {
react: { version: '19.1' }
},
plugins: {
react,
'react-hooks': reactHooks,
'react-refresh': reactRefresh,
},
rules: {
...js.configs.recommended.rules,
...react.configs.recommended.rules,
...react.configs['jsx-runtime'].rules,
...reactHooks.configs.recommended.rules,
'react-refresh/only-export-components': [
'warn',
{ allowConstantExport: true },
],
'no-unused-vars': 'error',
'no-console': 'warn',
'react/prop-types': 'error',
'react-hooks/rules-of-hooks': 'error',
'react-hooks/exhaustive-deps': 'warn',
'semi': ['error', 'always'],
'quotes': ['error', 'single'],
'indent': ['error', 2],
},
},
];π‘ TypeScript Configuration: If you chose TypeScript when creating your Vite project, use the TypeScript configuration below instead.
If you created your project with TypeScript, replace the above JavaScript config with this TypeScript version:
First, install the TypeScript ESLint dependencies:
npm install --save-dev @eslint/js @typescript-eslint/parser @typescript-eslint/eslint-plugin eslint-plugin-react eslint-plugin-react-hooks globalsThen create your eslint.config.js file:
import js from '@eslint/js';
import globals from 'globals';
import tseslint from '@typescript-eslint/eslint-plugin';
import tsparser from '@typescript-eslint/parser';
import react from 'eslint-plugin-react';
import reactHooks from 'eslint-plugin-react-hooks';
import reactRefresh from 'eslint-plugin-react-refresh';
export default [
{
ignores: ['dist'],
},
{
files: ['**/*.{js,jsx,ts,tsx}'],
languageOptions: {
parser: tsparser,
ecmaVersion: 2020,
globals: {
...globals.browser,
...globals.es2020,
},
parserOptions: {
ecmaVersion: 'latest',
ecmaFeatures: { jsx: true },
sourceType: 'module',
project: './tsconfig.json',
},
},
settings: {
react: { version: '19.1' }
},
plugins: {
'@typescript-eslint': tseslint,
react,
'react-hooks': reactHooks,
'react-refresh': reactRefresh,
},
rules: {
...js.configs.recommended.rules,
...tseslint.configs.recommended.rules,
...react.configs.recommended.rules,
...react.configs['jsx-runtime'].rules,
...reactHooks.configs.recommended.rules,
'react-refresh/only-export-components': [
'warn',
{ allowConstantExport: true },
],
// Disable conflicting rules for TypeScript
'no-unused-vars': 'off',
'@typescript-eslint/no-unused-vars': 'error',
'no-undef': 'off', // TypeScript handles this
// TypeScript specific rules
'@typescript-eslint/explicit-function-return-type': 'off',
'@typescript-eslint/explicit-module-boundary-types': 'off',
'@typescript-eslint/no-explicit-any': 'warn',
'@typescript-eslint/prefer-const': 'error',
// Common rules
'no-console': 'warn',
'react/prop-types': 'off', // TypeScript handles prop validation
'react-hooks/rules-of-hooks': 'error',
'react-hooks/exhaustive-deps': 'warn',
'semi': ['error', 'always'],
'quotes': ['error', 'single'],
'indent': ['error', 2],
},
},
];The linting scripts are already configured in your package.json. You can run:
npm run lint # Check for linting issues
npm run lint:fix # Auto-fix issues where possibleNow let's introduce some code that will trigger linting errors, then fix them.
Replace your src/App.jsx with this version that has several linting issues:
import React, { useState, useEffect } from 'react';
import axios from 'axios';
import moment from 'moment';
import 'bootstrap/dist/css/bootstrap.min.css';
import './App.css';
function App() {
const [currentTime, setCurrentTime] = useState('');
const [joke, setJoke] = useState('Loading...');
const unusedVariable = "This variable is never used"; // Linting error: unused variable
useEffect(() => {
const timer = setInterval(() => {
setCurrentTime(moment().format('MMMM Do YYYY, h:mm:ss a'));
}, 1000);
fetchJoke();
return () => clearInterval(timer);
}, []); // Linting warning: missing dependency
const fetchJoke = async () => {
try {
const response = await axios.get("https://official-joke-api.appspot.com/jokes/programming/random") // Missing semicolon
console.log("Fetching joke...") // Console warning + missing semicolon + wrong quotes
setJoke(`${response.data[0].setup} - ${response.data[0].punchline}`)
} catch (error) {
console.log(error) // Console warning + missing semicolon
setJoke("Failed to load joke. Check your internet connection!") // Wrong quotes + missing semicolon
}
}; // This function should be defined before useEffect
const handleJokeClick = () => {
console.log("Button clicked") // Console warning + missing semicolon + wrong quotes
fetchJoke()
} // Missing semicolon
return (
<div className="App">
<header className="App-header">
<h1 className="display-4 mb-4">π Build Tools Workshop</h1>
<p className="lead">Welcome to learning about build tools!</p>
<div className="row">
<div className="col-md-6">
<div className="info-section">
<h2>β° Current Time</h2>
<p className="time-display">{currentTime}</p>
</div>
</div>
<div className="col-md-6">
<div className="info-section">
<h2>π Programming Joke</h2>
<p className="joke-text">{joke}</p>
<button className="btn btn-primary btn-lg" onClick={handleJokeClick}>
Get New Joke
</button>
</div>
</div>
</div>
</header>
</div>
);
}
export default App;npm run lintYou'll see output like:
5:9 error 'unusedVariable' is assigned a value but never used no-unused-vars
18:5 warning React Hook useEffect has missing dependencies: 'fetchJoke' react-hooks/exhaustive-deps
22:85 error Missing semicolon semi
23:7 warning Unexpected console statement no-console
23:36 error Missing semicolon semi
23:36 error Strings must use singlequote quotes
25:7 warning Unexpected console statement no-console
25:25 error Missing semicolon semi
26:7 warning Unexpected console statement no-console
26:75 error Missing semicolon semi
26:75 error Strings must use singlequote quotes
32:7 warning Unexpected console statement no-console
32:32 error Missing semicolon semi
32:32 error Strings must use singlequote quotes
33:15 error Missing semicolon semi
34:3 error Missing semicolon semi
Here's the corrected version:
import React, { useState, useEffect, useCallback } from 'react';
import axios from 'axios';
import moment from 'moment';
import 'bootstrap/dist/css/bootstrap.min.css';
import './App.css';
function App() {
const [currentTime, setCurrentTime] = useState('');
const [joke, setJoke] = useState('Loading...');
const fetchJoke = useCallback(async () => {
try {
const response = await axios.get('https://official-joke-api.appspot.com/jokes/programming/random');
setJoke(`${response.data[0].setup} - ${response.data[0].punchline}`);
} catch (error) {
setJoke('Failed to load joke. Check your internet connection!');
}
}, []);
useEffect(() => {
const timer = setInterval(() => {
setCurrentTime(moment().format('MMMM Do YYYY, h:mm:ss a'));
}, 1000);
fetchJoke();
return () => clearInterval(timer);
}, [fetchJoke]);
const handleJokeClick = () => {
fetchJoke();
};
return (
<div className="App">
<header className="App-header">
<h1 className="display-4 mb-4">π Build Tools Workshop</h1>
<p className="lead">Welcome to learning about build tools!</p>
<div className="row">
<div className="col-md-6">
<div className="info-section">
<h2>β° Current Time</h2>
<p className="time-display">{currentTime}</p>
</div>
</div>
<div className="col-md-6">
<div className="info-section">
<h2>π Programming Joke</h2>
<p className="joke-text">{joke}</p>
<button className="btn btn-primary btn-lg" onClick={handleJokeClick}>
Get New Joke
</button>
</div>
</div>
</div>
</header>
</div>
);
}
export default App;npm run lintYou should now see no errors! π
npm run buildThis command:
- Creates optimized, minified files using Vite's build process
- Generates a
dist/directory with your built application - Prepares your app for deployment
- Uses Rollup under the hood for optimal bundling
Vite provides a built-in preview command:
npm run previewThis serves your built application locally so you can test the production build.
Visit the URL shown (usually http://localhost:4173) to see your production build!
Notice the differences:
- Development: Large file sizes, readable code, instant hot reloading
- Production: Small file sizes, minified code, optimized for performance
- Build tool: Vite uses esbuild for development and Rollup for production builds
"command not found" errors:
- Make sure Node.js is properly installed
- Restart your terminal
- Check your PATH environment variable
Port already in use:
- Vite uses port 5173 by default
- Try a different port:
npm run dev -- --port 3001 - Or kill the process using the port
Module not found errors:
- Run
npm installto ensure all dependencies are installed - Delete
node_modules/andpackage-lock.json, then runnpm install
Linting errors:
- Read the error messages carefully
- Use
npm run lint:fixto auto-fix some issues - Check the ESLint documentation for specific rules
Build fails:
- Check for syntax errors in your code
- Ensure all dependencies are properly installed
- Look at the build output for specific error messages
- Try deleting
node_modulesand runningnpm installagain
Testing is crucial for maintaining code quality and catching bugs early. Let's add tests to our application.
React Testing Library and Jest come pre-configured with Vite, but let's add some additional testing utilities:
npm install --save-dev @testing-library/jest-dom @testing-library/user-eventCreate a src/setupTests.js file:
import '@testing-library/jest-dom';Create a new file src/App.test.jsx:
import { render, screen, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { vi } from 'vitest';
import App from './App';
// Mock axios to avoid making real API calls in tests
vi.mock('axios');
import axios from 'axios';
describe('App Component', () => {
beforeEach(() => {
// Reset mocks before each test
vi.clearAllMocks();
});
test('renders workshop title', () => {
render(<App />);
const titleElement = screen.getByText(/Build Tools Workshop/i);
expect(titleElement).toBeInTheDocument();
});
test('displays current time section', () => {
render(<App />);
const timeSection = screen.getByText(/Current Time/i);
expect(timeSection).toBeInTheDocument();
});
test('displays programming joke section', () => {
render(<App />);
const jokeSection = screen.getByText(/Programming Joke/i);
expect(jokeSection).toBeInTheDocument();
});
test('clicking joke button triggers new joke fetch', async () => {
const mockJokeResponse = {
data: [{
setup: 'Why do programmers prefer dark mode?',
punchline: 'Because light attracts bugs!'
}]
};
axios.get.mockResolvedValueOnce(mockJokeResponse);
render(<App />);
const jokeButton = screen.getByText(/Get New Joke/i);
await userEvent.click(jokeButton);
await waitFor(() => {
expect(axios.get).toHaveBeenCalledWith(
'https://official-joke-api.appspot.com/jokes/programming/random'
);
});
});
test('handles joke fetch error gracefully', async () => {
axios.get.mockRejectedValueOnce(new Error('Network error'));
render(<App />);
await waitFor(() => {
const errorMessage = screen.getByText(/Failed to load joke/i);
expect(errorMessage).toBeInTheDocument();
});
});
});Add test scripts to your package.json:
{
"scripts": {
"dev": "vite",
"build": "vite build",
"lint": "eslint . --ext js,jsx --report-unused-disable-directives --max-warnings 0",
"lint:fix": "eslint . --ext js,jsx --fix",
"preview": "vite preview",
"test": "vitest",
"test:ui": "vitest --ui",
"test:coverage": "vitest --coverage"
}
}npm install --save-dev vitest @vitest/ui @vitest/coverage-v8 jsdomUpdate your vite.config.js:
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
export default defineConfig({
plugins: [react()],
test: {
globals: true,
environment: 'jsdom',
setupFiles: './src/setupTests.js',
},
})npm testYou should see your tests run and pass! π
Let's set up automated testing and deployment using GitHub Actions.
Create a .github/workflows/ci-cd.yml file in your project root:
name: CI/CD Pipeline
on:
push:
branches: [ main, develop ]
pull_request:
branches: [ main ]
jobs:
test:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [18.x, 20.x]
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Run linting
run: npm run lint
- name: Run tests
run: npm test
- name: Run build
run: npm run build
- name: Upload build artifacts
uses: actions/upload-artifact@v4
with:
name: build-files-${{ matrix.node-version }}
path: dist/
deploy:
needs: test
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main' && github.event_name == 'push'
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Use Node.js 20.x
uses: actions/setup-node@v4
with:
node-version: 20.x
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Build project
run: npm run build
- name: Deploy to GitHub Pages
uses: peaceiris/actions-gh-pages@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./distThis GitHub Actions workflow:
- Triggers: Runs on pushes to
main/developbranches and pull requests tomain - Matrix Testing: Tests against multiple Node.js versions (18.x and 20.x)
- Quality Checks: Runs linting, tests, and builds
- Deployment: Automatically deploys to GitHub Pages when changes are pushed to
main
To enable GitHub Pages deployment:
- Go to your GitHub repository settings
- Navigate to "Pages" section
- Select "GitHub Actions" as the source
- Your app will be deployed automatically when you push to main
Add these badges to the top of your README to show build status:

- Commit your changes and push to GitHub
- Go to the "Actions" tab in your repository
- Watch your pipeline run automatically
- Check that all steps pass successfully
Congratulations! You've completed the Build Tools Workshop. Here's what you can explore next:
- TypeScript: Add type safety to your JavaScript
- State Management: Explore Redux or Context API for complex state
- Performance: Learn about code splitting and optimization techniques
- Advanced Testing: Explore integration testing and end-to-end testing with Playwright or Cypress
- Deployment: Deploy your app to platforms like Netlify, Vercel, or AWS
- Webpack: Understanding module bundlers and build processes
- Docker: Containerizing your applications
- Monorepos: Managing multiple packages with tools like Lerna or Nx
You've successfully:
- β Set up a development environment with Node.js and npm
- β Created a React application from scratch using Vite
- β Added and managed dependencies
- β Debugged build errors by reading error output
- β Implemented styling with external CSS frameworks
- β Set up and used linting tools for code quality
- β Built your application for production
- β Added comprehensive tests with React Testing Library
- β Set up automated CI/CD pipelines with GitHub Actions
You're now ready to start building amazing web applications with modern build tools! Remember, the best way to learn is by building projects and experimenting with new tools and libraries.
- React Documentation
- Vite Documentation
- npm Documentation
- ESLint Rules
- React Testing Library
- GitHub Actions Documentation
Happy coding! π