npm create vite@latest 프로젝트 -- template react-ts
cd 프로젝트
npm install
npm run dev
를 실행하면 서버가 시작된다.
아래 두 개를 설치한다.
npm install --save-dev eslint @eslint/js globals eslint-plugin-react eslint-plugin-react-hooks eslint-plugin-react-refresh eslint-plugin-jsx-a11y eslint-plugin-prettier prettier @typescript-eslint/eslint-plugin @typescript-eslint/parser
그리고 eslint.config.js 수정
import js from '@eslint/js'
import globals from 'globals'
import reactPlugin from 'eslint-plugin-react';
import reactHooks from 'eslint-plugin-react-hooks'
import reactRefresh from 'eslint-plugin-react-refresh'
import tseslint from 'typescript-eslint'
import jsxA11yPlugin from 'eslint-plugin-jsx-a11y';
import prettierPlugin from 'eslint-plugin-prettier';
export default tseslint.config(
{ ignores: ['dist'] },
{
extends: [js.configs.recommended, ...tseslint.configs.recommended],
files: ['**/*.{ts,tsx}'],
languageOptions: {
ecmaVersion: 2020,
globals: globals.browser,
},
plugins: {
prettier: prettierPlugin,
react: reactPlugin,
'react-hooks': reactHooks,
'react-refresh': reactRefresh,
'jsx-a11y': jsxA11yPlugin,
'@typescript-eslint': tseslint,
},
settings: {
react: { version: 'detect' },
},
rules: {
...reactHooks.configs.recommended.rules,
'react-refresh/only-export-components': [
'warn',
{ allowConstantExport: true },
],
'prettier/prettier': 'error',
},
},
)
.prettierignore
node_modules
node_modules/*
.DS_Store
dist
build
coverage
*.log
.eslintrc.*
eslint.config.*
.prettierrc
.prettierrc.*
package-lock.json
yarn.lock
pnpm-lock.yaml
vite.config.*
.env
*.local
**/public/static/*
**/assets/*
.prettierrc
{
"semi": false,
"singleQuote": true,
"trailingComma": "all",
"tabWidth": 2,
"printWidth": 200,
"bracketSpacing": true,
"jsxSingleQuote": false,
"arrowParens": "avoid",
"endOfLine": "lf"
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
<title>React Web App</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
import './index.css';
const rootElement = document.getElementById('root') as HTMLElement;
if (!rootElement) {
console.error('Root element with id="root" not found in index.html');
} else {
const root = ReactDOM.createRoot(rootElement);
root.render(
<React.StrictMode>
<App />
</React.StrictMode>
);
}
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@/*": ["src/*"],
"@pages/*": ["src/pages/*"]
},
"jsx": "react-jsx",
"strict": true,
"esModuleInterop": true,
"moduleResolution": "node",
"skipLibCheck": true,
"target": "ESNext",
"module": "ESNext",
"lib": ["DOM", "DOM.Iterable", "ESNext"],
"allowSyntheticDefaultImports": true,
"noEmit": true,
"allowImportingTsExtensions": true
},
"include": ["src"],
}
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import path from 'path';
export default defineConfig({
plugins: [react()],
resolve: {
alias: {
'@': path.resolve(__dirname, './src'),
'@pages': path.resolve(__dirname, './src/pages'),
},
},
});
import React from 'react';
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';
import Login from './pages/Login';
import SalesSearch from './pages/SalesSearch';
const App: React.FC = () => {
return (
<Router>
<Routes>
<Route path="/" element={<Login />} />
<Route path="/salesSearch" element={<SalesSearch />} />
{/* 추가 페이지 라우팅 설정 */}
</Routes>
</Router>
);
};
export default App;