-
), 밑줄(_
), 숫자 사용 가능test
, npm
, react
같은 예약어 ❌)npm create vite@latest user-app --template react-ts
-> React, TypeScript 선택
cd 폴더
npm install
npm install vite-plugin-pwa
# v3 버전 설치 방법
# Tailwind CSS v3.x 설치
npm i -D tailwindcss@3 postcss autoprefixer
npx tailwind init -p
# styled-components 설치 (TypeScript 지원 포함)
~~npm install styled-components
npm install -D @types/styled-components~~
# twin.macro 설치
npm install twin.macro
npm install vite-plugin-babel-macros
npm install -D @emotion/react @emotion/styled
public 폴더 아래 → icons 폴더 생성 → 아래 파일들 넣기
// vite.config.ts
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import { VitePWA } from 'vite-plugin-pwa';
import macrosPlugin from 'vite-plugin-babel-macros'
// <https://vite.dev/config/>
export default defineConfig({
plugins: [
react(),
VitePWA({
registerType: 'autoUpdate',
devOptions: {
enabled: true, // 개발환경에서 pwa 기능활성화
},
manifest: {
name: 'keywi',
short_name: '키위',
description: '1:1 키보드 견적 서비스, 나만의 키보드를 맞추고 뽐내보세요.',
start_url: '.',
display: 'standalone', // 네이티브앱처럼 화면 전체를 채움
background_color: '#ffffff',
theme_color: '#ffffff',
lang: 'ko',
"icons": [
{
"src": "icons/apple-touch-icon-57x57.png",
"sizes": "57x57",
"type": "image/png"
},
{
"src": "icons/apple-touch-icon-60x60.png",
"sizes": "60x60",
"type": "image/png"
},
{
"src": "icons/apple-touch-icon-72x72.png",
"sizes": "72x72",
"type": "image/png"
},
{
"src": "icons/apple-touch-icon-114x114.png",
"sizes": "114x114",
"type": "image/png"
},
{
"src": "icons/apple-touch-icon-120x120.png",
"sizes": "120x120",
"type": "image/png"
},
{
"src": "icons/apple-touch-icon-144x144.png",
"sizes": "144x144",
"type": "image/png"
},
{
"src": "icons/apple-touch-icon-152x152.png",
"sizes": "152x152",
"type": "image/png"
},
{
"src": "icons/apple-touch-icon-180x180.png",
"sizes": "180x180",
"type": "image/png"
},
{
"src": "icons/favicon-32x32.png",
"sizes": "32x32",
"type": "image/png"
},
{
"src": "icons/favicon-96x96.png",
"sizes": "96x96",
"type": "image/png"
},
{
"src": "icons/favicon-16x16.png",
"sizes": "16x16",
"type": "image/png"
},
{
"src": "icons/logo192.png",
"sizes": "192x192",
"type": "image/png"
},
{
"src": "icons/logo512.png",
"sizes": "512x512",
"type": "image/png"
}
],
},
}),
macrosPlugin(),
],
})
// tailwind.config.js 수정
/** @type {import('tailwindcss').Config} */
export default {
content: [
"./index.html",
"./src/**/*.{js,ts,jsx,tsx}",
],
theme: {
extend: {},
},
plugins: [],
}
// postcss.config.js 수정
export default {
plugins: {
'postcss-import': {},
tailwindcss: {},
autoprefixer: {},
},
}
/* index.css */
@tailwind base;
@tailwind components;
@tailwind utilities;
/* 경고 표시 뜰 때 */
✅ 해결 방법 1: VSCode Tailwind CSS 확장 프로그램 설치
✅ 해결 방법 2: settings.json 수정
- VSCode에서 Ctrl + Shift + P (⌘ + Shift + P on Mac)
- "Preferences: Open Settings (JSON)" 검색해서 선택
{
"css.lint.unknownAtRules": "ignore"
}
// App.tsx
import { useState } from 'react'
import reactLogo from './assets/react.svg'
import viteLogo from '/vite.svg'
import './App.css'
**import tw from "twin.macro";
import styled from "styled-components";**
**// Tailwind 클래스를 styled-components처럼 사용 가능
const Container = styled.div`
${tw`flex flex-col items-center justify-center h-screen bg-gray-100`}
`;
const Title = styled.h1`
${tw`text-3xl font-bold text-blue-600`}
`;**
function App() {
const [count, setCount] = useState(0)
return (
<>
<div>
<a href="<https://vite.dev>" target="_blank">
<img src={viteLogo} className="logo" alt="Vite logo" />
</a>
<a href="<https://react.dev>" target="_blank">
<img src={reactLogo} className="logo react" alt="React logo" />
</a>
</div>
<h1>Vite + React</h1>
**<Title>Welcome to My PWA</Title>**
<div className="card">
<button onClick={() => setCount((count) => count + 1)}>
count is {count}
</button>
<p>
Edit <code>src/App.tsx</code> and save to test HMR
</p>
</div>
<p className="read-the-docs">
Click on the Vite and React logos to learn more
</p>
</>
)
}
export default App