diff --git a/.eslintrc.cjs b/.eslintrc.cjs index 19bf5eb..4510f68 100644 --- a/.eslintrc.cjs +++ b/.eslintrc.cjs @@ -18,4 +18,9 @@ module.exports = { ], 'no-console': 'off', }, + settings: { + 'import/resolver': { + typescript: {}, + }, + }, }; diff --git a/package-lock.json b/package-lock.json index f7627e4..0195ce6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -19,6 +19,7 @@ }, "devDependencies": { "@svgr/rollup": "^8.1.0", + "@types/node": "^20.10.5", "@types/react": "^18.2.37", "@types/react-dom": "^18.2.15", "@types/styled-components": "^5.1.32", @@ -28,6 +29,7 @@ "eslint": "^8.53.0", "eslint-config-airbnb-base": "^15.0.0", "eslint-config-prettier": "^9.0.0", + "eslint-import-resolver-typescript": "^3.6.1", "eslint-plugin-import": "^2.29.0", "eslint-plugin-react-hooks": "^4.6.0", "eslint-plugin-react-refresh": "^0.4.4", @@ -5431,9 +5433,9 @@ "dev": true }, "node_modules/@types/node": { - "version": "20.10.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.10.0.tgz", - "integrity": "sha512-D0WfRmU9TQ8I9PFx9Yc+EBHw+vSpIub4IDvQivcp26PtPrdMGAq5SDcpXEo/epqa/DXotVpekHiLNTg3iaKXBQ==", + "version": "20.10.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.10.5.tgz", + "integrity": "sha512-nNPsNE65wjMxEKI93yOP+NPGGBJz/PoN3kZsVLee0XMiJolxSekEVD8wRwBUBqkwc7UWop0edW50yrCQW4CyRw==", "dependencies": { "undici-types": "~5.26.4" } @@ -8186,6 +8188,19 @@ "once": "^1.4.0" } }, + "node_modules/enhanced-resolve": { + "version": "5.15.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz", + "integrity": "sha512-LXYT42KJ7lpIKECr2mAXIaMldcNCh/7E0KBKOu4KSfkHmP+mZmSs+8V5gBAqisWBy0OO4W5Oyys0GO1Y8KtdKg==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, "node_modules/entities": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", @@ -8827,6 +8842,31 @@ "ms": "^2.1.1" } }, + "node_modules/eslint-import-resolver-typescript": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-3.6.1.tgz", + "integrity": "sha512-xgdptdoi5W3niYeuQxKmzVDTATvLYqhpwmykwsh7f6HIOStGWEIL9iqZgQDF9u9OEzrRwR8no5q2VT+bjAujTg==", + "dev": true, + "dependencies": { + "debug": "^4.3.4", + "enhanced-resolve": "^5.12.0", + "eslint-module-utils": "^2.7.4", + "fast-glob": "^3.3.1", + "get-tsconfig": "^4.5.0", + "is-core-module": "^2.11.0", + "is-glob": "^4.0.3" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/unts/projects/eslint-import-resolver-ts" + }, + "peerDependencies": { + "eslint": "*", + "eslint-plugin-import": "*" + } + }, "node_modules/eslint-module-utils": { "version": "2.8.0", "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.8.0.tgz", @@ -9907,6 +9947,18 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/get-tsconfig": { + "version": "4.7.2", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.7.2.tgz", + "integrity": "sha512-wuMsz4leaj5hbGgg4IvDU0bqJagpftG5l5cXIAvo8uZrqn0NJqwtfupTN00VnkQJPcIRrxYrm1Ue24btpCha2A==", + "dev": true, + "dependencies": { + "resolve-pkg-maps": "^1.0.0" + }, + "funding": { + "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" + } + }, "node_modules/gifsicle": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/gifsicle/-/gifsicle-5.2.0.tgz", @@ -15397,6 +15449,15 @@ "node": ">=4" } }, + "node_modules/resolve-pkg-maps": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", + "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", + "dev": true, + "funding": { + "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" + } + }, "node_modules/responselike": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", @@ -16424,6 +16485,15 @@ "node": ">= 10" } }, + "node_modules/tapable": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", + "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/tar-stream": { "version": "1.6.2", "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.6.2.tgz", diff --git a/package.json b/package.json index a4488a5..af69022 100644 --- a/package.json +++ b/package.json @@ -23,6 +23,7 @@ }, "devDependencies": { "@svgr/rollup": "^8.1.0", + "@types/node": "^20.10.5", "@types/react": "^18.2.37", "@types/react-dom": "^18.2.15", "@types/styled-components": "^5.1.32", @@ -32,6 +33,7 @@ "eslint": "^8.53.0", "eslint-config-airbnb-base": "^15.0.0", "eslint-config-prettier": "^9.0.0", + "eslint-import-resolver-typescript": "^3.6.1", "eslint-plugin-import": "^2.29.0", "eslint-plugin-react-hooks": "^4.6.0", "eslint-plugin-react-refresh": "^0.4.4", diff --git a/src/App.tsx b/src/App.tsx index 0939cbb..126a3d7 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,15 +1,15 @@ import { useEffect, useState, lazy, Suspense } from 'react'; import { RouterProvider, createBrowserRouter } from 'react-router-dom'; -import { auth } from './firebase.ts'; -import LoadingSpinner from './components/loading-spinner.tsx'; -import * as S from './styles/global.ts'; +import { auth } from '@/firebase.ts'; +import LoadingSpinner from '@compo/loading-spinner.tsx'; +import * as S from '@style/global.ts'; -const ProtectedRoute = lazy(() => import('./components/protected-route.tsx')); -const Home = lazy(() => import('./routes/home.tsx')); -const Profile = lazy(() => import('./routes/profile.tsx')); -const SearchResult = lazy(() => import('./routes/search-result.tsx')); -const Auth = lazy(() => import('./routes/auth.tsx')); -const Layout = lazy(() => import('./components/layout.tsx')); +const ProtectedRoute = lazy(() => import('@compo/protected-route.tsx')); +const Home = lazy(() => import('@page/home.tsx')); +const Profile = lazy(() => import('@page/profile.tsx')); +const SearchResult = lazy(() => import('@page/search-result.tsx')); +const Auth = lazy(() => import('@page/auth.tsx')); +const Layout = lazy(() => import('@compo/layout.tsx')); const router = createBrowserRouter([ { diff --git a/src/atoms.tsx b/src/atoms.tsx index d34eab9..ef7c70e 100644 --- a/src/atoms.tsx +++ b/src/atoms.tsx @@ -1,8 +1,11 @@ import { atom } from 'recoil'; +export const signInUserAtom = atom({ + key: 'signInUser', + default: null, +}); + export const searchKeywordAtom = atom({ key: 'searchKeyword', default: '', }); - -export const tmp = ''; diff --git a/src/components/sign-in.tsx b/src/components/auth/sign-in.tsx similarity index 89% rename from src/components/sign-in.tsx rename to src/components/auth/sign-in.tsx index e3cb620..b87427c 100644 --- a/src/components/sign-in.tsx +++ b/src/components/auth/sign-in.tsx @@ -2,12 +2,12 @@ import React, { useState } from 'react'; import { useNavigate } from 'react-router-dom'; import { FirebaseError } from 'firebase/app'; import { signInWithEmailAndPassword } from 'firebase/auth'; -import { auth } from '../firebase.ts'; -import useEscClose from '../utils/use-esc-close.tsx'; -import * as S from '../styles/auth.ts'; -import * as P from '../styles/popup.ts'; -import ImageComputer from '../assets/images/logo-small.png'; -import { ReactComponent as LoadingSpinner } from '../assets/images/loading-spinner-mini.svg'; +import ImageComputer from '@img/logo-small.png'; +import { ReactComponent as LoadingSpinner } from '@img/loading-spinner-mini.svg'; +import { auth } from '@/firebase.ts'; +import useEscClose from '@util/use-esc-close.tsx'; +import * as S from '@style/auth.ts'; +import * as P from '@style/popup.ts'; interface ISignInProps { onClose: () => void; diff --git a/src/components/sign-up.tsx b/src/components/auth/sign-up.tsx similarity index 91% rename from src/components/sign-up.tsx rename to src/components/auth/sign-up.tsx index 34110a4..64a9310 100644 --- a/src/components/sign-up.tsx +++ b/src/components/auth/sign-up.tsx @@ -3,12 +3,12 @@ import { useNavigate } from 'react-router-dom'; import { FirebaseError } from 'firebase/app'; import { createUserWithEmailAndPassword, updateProfile } from 'firebase/auth'; import { doc, setDoc } from 'firebase/firestore'; -import { auth, db } from '../firebase.ts'; -import useEscClose from '../utils/use-esc-close.tsx'; -import * as S from '../styles/auth.ts'; -import * as P from '../styles/popup.ts'; -import ImageComputer from '../assets/images/logo-small.png'; -import { ReactComponent as LoadingSpinner } from '../assets/images/loading-spinner-mini.svg'; +import { auth, db } from '@/firebase.ts'; +import useEscClose from '@util/use-esc-close.tsx'; +import * as S from '@style/auth.ts'; +import * as P from '@style/popup.ts'; +import ImageComputer from '@img/logo-small.png'; +import { ReactComponent as LoadingSpinner } from '@img/loading-spinner-mini.svg'; interface ISignUpProps { onClose: () => void; diff --git a/src/components/social-sign-in.tsx b/src/components/auth/social-sign-in.tsx similarity index 94% rename from src/components/social-sign-in.tsx rename to src/components/auth/social-sign-in.tsx index e3ca06c..2208493 100644 --- a/src/components/social-sign-in.tsx +++ b/src/components/auth/social-sign-in.tsx @@ -3,8 +3,8 @@ import { useNavigate } from 'react-router-dom'; import { FirebaseError } from 'firebase/app'; import { AuthProvider, signInWithPopup } from 'firebase/auth'; import { doc, setDoc } from 'firebase/firestore'; -import { auth, db } from '../firebase.ts'; -import * as S from '../styles/auth.ts'; +import { auth, db } from '@/firebase.ts'; +import * as S from '@style/auth.ts'; interface ISocialButton { provider: AuthProvider; diff --git a/src/components/edit-tweet-form.tsx b/src/components/home/edit-tweet-form.tsx similarity index 88% rename from src/components/edit-tweet-form.tsx rename to src/components/home/edit-tweet-form.tsx index 4543d98..1a5d6b8 100644 --- a/src/components/edit-tweet-form.tsx +++ b/src/components/home/edit-tweet-form.tsx @@ -6,13 +6,13 @@ import { ref, uploadBytes, } from 'firebase/storage'; -import { auth, db, storage } from '../firebase.ts'; -import ITweet from '../interfaces/ITweet.ts'; -import CompressImage from '../utils/compress-image.tsx'; -import useEscClose from '../utils/use-esc-close.tsx'; -import * as S from '../styles/tweet-form.ts'; -import { ReactComponent as IconPhoto } from '../assets/images/i-photo.svg'; -import { ReactComponent as LoadingSpinner } from '../assets/images/loading-spinner-mini.svg'; +import { auth, db, storage } from '@/firebase.ts'; +import ITweet from '@type/ITweet.ts'; +import CompressImage from '@util/compress-image.tsx'; +import useEscClose from '@util/use-esc-close.tsx'; +import * as S from '@style/tweet-form.ts'; +import { ReactComponent as IconPhoto } from '@img/i-photo.svg'; +import { ReactComponent as LoadingSpinner } from '@img/loading-spinner-mini.svg'; interface IEditTweetForm extends Pick { onClose: () => void; diff --git a/src/components/post-tweet-form.tsx b/src/components/home/post-tweet-form.tsx similarity index 89% rename from src/components/post-tweet-form.tsx rename to src/components/home/post-tweet-form.tsx index feed222..f5a3c0a 100644 --- a/src/components/post-tweet-form.tsx +++ b/src/components/home/post-tweet-form.tsx @@ -1,11 +1,11 @@ import React, { useState } from 'react'; import { addDoc, collection, updateDoc } from 'firebase/firestore'; import { getDownloadURL, ref, uploadBytes } from 'firebase/storage'; -import { auth, db, storage } from '../firebase.ts'; -import CompressImage from '../utils/compress-image.tsx'; -import * as S from '../styles/tweet-form.ts'; -import { ReactComponent as IconPhoto } from '../assets/images/i-photo.svg'; -import { ReactComponent as LoadingSpinner } from '../assets/images/loading-spinner-mini.svg'; +import { auth, db, storage } from '@/firebase.ts'; +import CompressImage from '@util/compress-image.tsx'; +import * as S from '@style/tweet-form.ts'; +import { ReactComponent as IconPhoto } from '@img/i-photo.svg'; +import { ReactComponent as LoadingSpinner } from '@img/loading-spinner-mini.svg'; export default function PostTweetForm() { const [isLoading, setLoading] = useState(false); diff --git a/src/components/timeline.tsx b/src/components/home/timeline.tsx similarity index 88% rename from src/components/timeline.tsx rename to src/components/home/timeline.tsx index 8db2636..767a4b9 100644 --- a/src/components/timeline.tsx +++ b/src/components/home/timeline.tsx @@ -7,10 +7,10 @@ import { orderBy, query, } from 'firebase/firestore'; -import { db } from '../firebase.ts'; -import Tweet from './tweet.tsx'; -import * as S from '../styles/timeline.ts'; -import ITweet from '../interfaces/ITweet.ts'; +import { db } from '@/firebase.ts'; +import Tweet from '@compo/home/tweet.tsx'; +import * as S from '@style/timeline.ts'; +import ITweet from '@type/ITweet.ts'; export default function Timeline() { const [tweets, setTweets] = useState([]); diff --git a/src/components/tweet.tsx b/src/components/home/tweet.tsx similarity index 87% rename from src/components/tweet.tsx rename to src/components/home/tweet.tsx index 730d928..cc264e7 100644 --- a/src/components/tweet.tsx +++ b/src/components/home/tweet.tsx @@ -1,14 +1,14 @@ import { useEffect, useState } from 'react'; import { deleteDoc, doc, getDoc } from 'firebase/firestore'; import { deleteObject, ref } from 'firebase/storage'; -import { auth, db, storage } from '../firebase.ts'; -import ITweet from '../interfaces/ITweet.ts'; -import FormatDate from '../utils/format-date.tsx'; -import EditTweetForm from './edit-tweet-form.tsx'; -import * as S from '../styles/tweet.ts'; -import * as P from '../styles/popup.ts'; -import { ReactComponent as IconUser } from '../assets/images/i-user.svg'; -import { ReactComponent as IconEdit } from '../assets/images/i-edit.svg'; +import { auth, db, storage } from '@/firebase.ts'; +import ITweet from '@type/ITweet.ts'; +import FormatDate from '@util/format-date.tsx'; +import EditTweetForm from '@compo/home/edit-tweet-form.tsx'; +import * as S from '@style/tweet.ts'; +import * as P from '@style/popup.ts'; +import { ReactComponent as IconUser } from '@img/i-user.svg'; +import { ReactComponent as IconEdit } from '@img/i-edit.svg'; export default function Tweet({ id, diff --git a/src/components/layout.tsx b/src/components/layout.tsx index f162be4..58919c3 100644 --- a/src/components/layout.tsx +++ b/src/components/layout.tsx @@ -1,7 +1,7 @@ import { Outlet } from 'react-router-dom'; -import Wrapper from '../styles/layout.ts'; -import Menu from './menu.tsx'; -import Search from './search.tsx'; +import Wrapper from '@style/layout.ts'; +import Menu from '@compo/menu.tsx'; +import Search from '@compo/search.tsx'; export default function Layout() { return ( diff --git a/src/components/loading-spinner.tsx b/src/components/loading-spinner.tsx index 1ed6dd3..fc5ed60 100644 --- a/src/components/loading-spinner.tsx +++ b/src/components/loading-spinner.tsx @@ -1,5 +1,5 @@ -import Wrapper from '../styles/loading-spinner.ts'; -import { ReactComponent as Spinner } from '../assets/images/loading-spinner.svg'; +import Wrapper from '@style/loading-spinner.ts'; +import { ReactComponent as Spinner } from '@img/loading-spinner.svg'; export default function LoadingSpinner() { return ( diff --git a/src/components/menu.tsx b/src/components/menu.tsx index 6f25caa..56d9edd 100644 --- a/src/components/menu.tsx +++ b/src/components/menu.tsx @@ -1,14 +1,14 @@ import { Link, useNavigate } from 'react-router-dom'; import { useEffect, useState } from 'react'; -import { auth } from '../firebase.ts'; -import WindowTop from './window-top.tsx'; -import * as W from '../styles/window.ts'; -import * as S from '../styles/menu.ts'; -import * as P from '../styles/popup.ts'; -import ImageComputer from '../assets/images/logo-small.png'; -import { ReactComponent as IconUser } from '../assets/images/i-user.svg'; -import { ReactComponent as IconHome } from '../assets/images/i-home.svg'; -import { ReactComponent as IconLogout } from '../assets/images/i-arrowleft.svg'; +import { auth } from '@/firebase.ts'; +import WindowTop from '@compo/window-top.tsx'; +import * as W from '@style/window.ts'; +import * as S from '@style/menu.ts'; +import * as P from '@style/popup.ts'; +import ImageComputer from '@img/logo-small.png'; +import { ReactComponent as IconUser } from '@img/i-user.svg'; +import { ReactComponent as IconHome } from '@img/i-home.svg'; +import { ReactComponent as IconLogout } from '@img/i-arrowleft.svg'; export default function Menu() { const navigate = useNavigate(); diff --git a/src/components/edit-profile-form.tsx b/src/components/profile/edit-profile-form.tsx similarity index 89% rename from src/components/edit-profile-form.tsx rename to src/components/profile/edit-profile-form.tsx index 2927871..cae0c56 100644 --- a/src/components/edit-profile-form.tsx +++ b/src/components/profile/edit-profile-form.tsx @@ -7,13 +7,13 @@ import { ref, uploadBytes, } from 'firebase/storage'; -import { auth, db, storage } from '../firebase.ts'; -import IUser from '../interfaces/IUser.ts'; -import CompressImage from '../utils/compress-image.tsx'; -import useEscClose from '../utils/use-esc-close.tsx'; -import * as S from '../styles/profile-form.ts'; -import { ReactComponent as IconUser } from '../assets/images/i-user.svg'; -import { ReactComponent as LoadingSpinner } from '../assets/images/loading-spinner-mini.svg'; +import { auth, db, storage } from '@/firebase.ts'; +import IUser from '@type/IUser.ts'; +import CompressImage from '@util/compress-image.tsx'; +import useEscClose from '@util/use-esc-close.tsx'; +import * as S from '@style/profile-form.ts'; +import { ReactComponent as IconUser } from '@img/i-user.svg'; +import { ReactComponent as LoadingSpinner } from '@img/loading-spinner-mini.svg'; interface IEditProfileForm extends Pick { onClose: () => void; diff --git a/src/components/user-profile.tsx b/src/components/profile/user-profile.tsx similarity index 85% rename from src/components/user-profile.tsx rename to src/components/profile/user-profile.tsx index ce75028..6fe9d68 100644 --- a/src/components/user-profile.tsx +++ b/src/components/profile/user-profile.tsx @@ -1,10 +1,10 @@ import { useEffect, useState } from 'react'; import { doc, getDoc } from 'firebase/firestore'; -import { auth, db } from '../firebase.ts'; -import * as S from '../styles/profile.ts'; -import * as P from '../styles/popup.ts'; -import { ReactComponent as IconUser } from '../assets/images/i-user.svg'; -import EditProfileForm from './edit-profile-form.tsx'; +import { auth, db } from '@/firebase.ts'; +import EditProfileForm from '@compo/profile/edit-profile-form.tsx'; +import * as S from '@style/profile.ts'; +import * as P from '@style/popup.ts'; +import { ReactComponent as IconUser } from '@img/i-user.svg'; export default function UserProfile() { const user = auth.currentUser; diff --git a/src/components/user-timeline.tsx b/src/components/profile/user-timeline.tsx similarity index 89% rename from src/components/user-timeline.tsx rename to src/components/profile/user-timeline.tsx index 25444e1..8187648 100644 --- a/src/components/user-timeline.tsx +++ b/src/components/profile/user-timeline.tsx @@ -8,10 +8,10 @@ import { query, where, } from 'firebase/firestore'; -import { auth, db } from '../firebase.ts'; -import ITweet from '../interfaces/ITweet.ts'; -import Tweet from './tweet.tsx'; -import * as S from '../styles/timeline.ts'; +import { auth, db } from '@/firebase.ts'; +import ITweet from '@type/ITweet.ts'; +import Tweet from '@compo/home/tweet.tsx'; +import * as S from '@style/timeline.ts'; export default function UserTimeline() { const user = auth.currentUser; diff --git a/src/components/protected-route.tsx b/src/components/protected-route.tsx index 6a3a27e..35f704c 100644 --- a/src/components/protected-route.tsx +++ b/src/components/protected-route.tsx @@ -1,6 +1,6 @@ import React from 'react'; import { Navigate } from 'react-router-dom'; -import { auth } from '../firebase.ts'; +import { auth } from '@/firebase.ts'; export default function ProtectedRoute({ children, diff --git a/src/components/search-timeline.tsx b/src/components/search-result/search-timeline.tsx similarity index 85% rename from src/components/search-timeline.tsx rename to src/components/search-result/search-timeline.tsx index d88f4d4..168c916 100644 --- a/src/components/search-timeline.tsx +++ b/src/components/search-result/search-timeline.tsx @@ -8,11 +8,11 @@ import { where, } from 'firebase/firestore'; import { useRecoilValue } from 'recoil'; -import { db } from '../firebase.ts'; -import { searchKeywordAtom } from '../atoms.tsx'; -import Tweet from './tweet.tsx'; -import * as S from '../styles/timeline.ts'; -import ITweet from '../interfaces/ITweet.ts'; +import { db } from '@/firebase.ts'; +import { searchKeywordAtom } from '@/atoms.tsx'; +import Tweet from '@compo/home/tweet.tsx'; +import ITweet from '@type/ITweet.ts'; +import * as S from '@style/timeline.ts'; export default function SearchTimeline() { const [tweets, setTweets] = useState([]); diff --git a/src/components/search.tsx b/src/components/search.tsx index b68f610..6537968 100644 --- a/src/components/search.tsx +++ b/src/components/search.tsx @@ -1,11 +1,11 @@ import React, { useEffect, useState } from 'react'; import { useRecoilState } from 'recoil'; import { useNavigate } from 'react-router-dom'; -import { searchKeywordAtom } from '../atoms.tsx'; -import WindowTop from './window-top.tsx'; -import * as W from '../styles/window.ts'; -import * as S from '../styles/search.ts'; -import { ReactComponent as IconSearch } from '../assets/images/i-search.svg'; +import { searchKeywordAtom } from '@/atoms.tsx'; +import WindowTop from '@compo/window-top.tsx'; +import * as W from '@style/window.ts'; +import * as S from '@style/search.ts'; +import { ReactComponent as IconSearch } from '@img/i-search.svg'; export default function Search() { const navigate = useNavigate(); diff --git a/src/components/window-top.tsx b/src/components/window-top.tsx index d791a5b..66da77b 100644 --- a/src/components/window-top.tsx +++ b/src/components/window-top.tsx @@ -1,7 +1,7 @@ -import * as W from '../styles/window.ts'; -import { ReactComponent as IconWindow1 } from '../assets/images/i-window1.svg'; -import { ReactComponent as IconWindow2 } from '../assets/images/i-window2.svg'; -import { ReactComponent as IconWindow3 } from '../assets/images/i-window3.svg'; +import * as W from '@style/window.ts'; +import { ReactComponent as IconWindow1 } from '@img/i-window1.svg'; +import { ReactComponent as IconWindow2 } from '@img/i-window2.svg'; +import { ReactComponent as IconWindow3 } from '@img/i-window3.svg'; export default function WindowTop() { return ( diff --git a/src/main.tsx b/src/main.tsx index 7c2ad49..a935f0a 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -1,7 +1,7 @@ import React from 'react'; import ReactDOM from 'react-dom/client'; import { RecoilRoot } from 'recoil'; -import App from './App.tsx'; +import App from '@/App.tsx'; ReactDOM.createRoot(document.getElementById('root')!).render( diff --git a/src/routes/auth.tsx b/src/routes/auth.tsx index 03afd94..1afae65 100644 --- a/src/routes/auth.tsx +++ b/src/routes/auth.tsx @@ -1,12 +1,12 @@ import { useState } from 'react'; import { GoogleAuthProvider, GithubAuthProvider } from 'firebase/auth'; -import SignUp from '../components/sign-up.tsx'; -import SignIn from '../components/sign-in.tsx'; -import * as S from '../styles/auth.ts'; -import SocialSignIn from '../components/social-sign-in.tsx'; -import ImageComputer from '../assets/images/logo-big.png'; -import { ReactComponent as IconGoogle } from '../assets/images/i-google.svg'; -import { ReactComponent as IconGithub } from '../assets/images/i-github.svg'; +import SignUp from '@compo/auth/sign-up.tsx'; +import SignIn from '@compo/auth/sign-in.tsx'; +import SocialSignIn from '@compo/auth/social-sign-in.tsx'; +import * as S from '@style/auth.ts'; +import ImageComputer from '@img/logo-big.png'; +import { ReactComponent as IconGoogle } from '@img/i-google.svg'; +import { ReactComponent as IconGithub } from '@img/i-github.svg'; export default function Auth() { const [signUpPopup, setSignUpPopup] = useState(false); diff --git a/src/routes/home.tsx b/src/routes/home.tsx index b794528..c613230 100644 --- a/src/routes/home.tsx +++ b/src/routes/home.tsx @@ -1,7 +1,7 @@ -import WindowTop from '../components/window-top.tsx'; -import PostTweetForm from '../components/post-tweet-form.tsx'; -import Timeline from '../components/timeline.tsx'; -import * as W from '../styles/window.ts'; +import WindowTop from '@compo/window-top.tsx'; +import PostTweetForm from '@compo/home/post-tweet-form.tsx'; +import Timeline from '@compo/home/timeline.tsx'; +import * as W from '@style/window.ts'; export default function Home() { return ( diff --git a/src/routes/profile.tsx b/src/routes/profile.tsx index 21204c6..b82e147 100644 --- a/src/routes/profile.tsx +++ b/src/routes/profile.tsx @@ -1,7 +1,7 @@ -import WindowTop from '../components/window-top.tsx'; -import UserTimeline from '../components/user-timeline.tsx'; -import * as W from '../styles/window.ts'; -import UserProfile from '../components/user-profile.tsx'; +import WindowTop from '@compo/window-top.tsx'; +import UserProfile from '@compo/profile/user-profile.tsx'; +import UserTimeline from '@compo/profile/user-timeline.tsx'; +import * as W from '@style/window.ts'; export default function Profile() { return ( diff --git a/src/routes/search-result.tsx b/src/routes/search-result.tsx index 0c856b5..cea8cd1 100644 --- a/src/routes/search-result.tsx +++ b/src/routes/search-result.tsx @@ -1,6 +1,6 @@ -import SearchTimeline from '../components/search-timeline.tsx'; -import WindowTop from '../components/window-top.tsx'; -import * as W from '../styles/window.ts'; +import SearchTimeline from '@compo/search-result/search-timeline.tsx'; +import WindowTop from '@compo/window-top.tsx'; +import * as W from '@style/window.ts'; export default function SearchResult() { return ( diff --git a/src/styles/auth.ts b/src/styles/auth.ts index ab4f7ba..b1e8921 100644 --- a/src/styles/auth.ts +++ b/src/styles/auth.ts @@ -4,8 +4,8 @@ import { blackColor, primaryColor, whiteColor, -} from './global.ts'; -import { LineButton, SolidButton, Input } from './button.ts'; +} from '@style/global.ts'; +import { LineButton, SolidButton, Input } from '@style/button.ts'; export const Wrapper = styled.div` display: flex; diff --git a/src/styles/button.ts b/src/styles/button.ts index 5aee82a..1286e36 100644 --- a/src/styles/button.ts +++ b/src/styles/button.ts @@ -1,5 +1,10 @@ import { styled } from 'styled-components'; -import { blackColor, grayColor, primaryColor, whiteColor } from './global.ts'; +import { + blackColor, + grayColor, + primaryColor, + whiteColor, +} from '@style/global.ts'; const Button = styled.button` width: 100%; diff --git a/src/styles/menu.ts b/src/styles/menu.ts index ffd9779..d51b2f6 100644 --- a/src/styles/menu.ts +++ b/src/styles/menu.ts @@ -4,7 +4,7 @@ import { blackColor, primaryColor, whiteColor, -} from './global.ts'; +} from '@style/global.ts'; export const Logo = styled.div` display: flex; diff --git a/src/styles/popup.ts b/src/styles/popup.ts index 5df8a02..9a07bd0 100644 --- a/src/styles/popup.ts +++ b/src/styles/popup.ts @@ -4,8 +4,8 @@ import { blackColor, primaryColor, whiteColor, -} from './global.ts'; -import { SolidButton } from './button.ts'; +} from '@style/global.ts'; +import { SolidButton } from '@style/button.ts'; export const PopupWrapper = styled.div` z-index: 100; diff --git a/src/styles/profile-form.ts b/src/styles/profile-form.ts index 8626b6c..3a8a377 100644 --- a/src/styles/profile-form.ts +++ b/src/styles/profile-form.ts @@ -1,8 +1,8 @@ import React from 'react'; import { styled } from 'styled-components'; -import { primaryColor, whiteColor } from './global.ts'; -import { Input, SolidButton } from './button.ts'; -import { Avatar } from './profile.ts'; +import { primaryColor, whiteColor } from '@style/global.ts'; +import { Input, SolidButton } from '@style/button.ts'; +import { Avatar } from '@style/profile.ts'; export const Form = styled.form` position: relative; diff --git a/src/styles/profile.ts b/src/styles/profile.ts index 897e99d..4d140f6 100644 --- a/src/styles/profile.ts +++ b/src/styles/profile.ts @@ -1,6 +1,6 @@ import { styled } from 'styled-components'; -import { grayColor } from './global.ts'; -import { LineButton } from './button.ts'; +import { grayColor } from '@style/global.ts'; +import { LineButton } from '@style/button.ts'; export const Profile = styled.article` position: relative; diff --git a/src/styles/search.ts b/src/styles/search.ts index db3d287..868fb90 100644 --- a/src/styles/search.ts +++ b/src/styles/search.ts @@ -1,6 +1,6 @@ import { styled } from 'styled-components'; -import { Input } from './button.ts'; -import { grayColor } from './global.ts'; +import { Input } from '@style/button.ts'; +import { grayColor } from '@style/global.ts'; export const Form = styled.form` position: relative; diff --git a/src/styles/tweet-form.ts b/src/styles/tweet-form.ts index ad8bd37..1c6b69c 100644 --- a/src/styles/tweet-form.ts +++ b/src/styles/tweet-form.ts @@ -1,6 +1,11 @@ import styled from 'styled-components'; -import { blackColor, grayColor, primaryColor, whiteColor } from './global.ts'; -import { SolidButton } from './button.ts'; +import { + blackColor, + grayColor, + primaryColor, + whiteColor, +} from '@style/global.ts'; +import { SolidButton } from '@style/button.ts'; export const Form = styled.form` position: relative; diff --git a/src/styles/tweet.ts b/src/styles/tweet.ts index 06e3a98..d7491ae 100644 --- a/src/styles/tweet.ts +++ b/src/styles/tweet.ts @@ -1,5 +1,5 @@ import { styled } from 'styled-components'; -import { grayColor, primaryColor } from './global.ts'; +import { grayColor, primaryColor } from '@style/global.ts'; export const Wrapper = styled.li` position: relative; diff --git a/src/styles/window.ts b/src/styles/window.ts index 6db10bb..39db84d 100644 --- a/src/styles/window.ts +++ b/src/styles/window.ts @@ -1,5 +1,5 @@ import styled from 'styled-components'; -import { blackColor, grayColor, primaryColor } from './global.ts'; +import { blackColor, grayColor, primaryColor } from '@style/global.ts'; export const Window = styled.section` position: relative; diff --git a/tsconfig.json b/tsconfig.json index c3a8685..485383b 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -6,6 +6,18 @@ "module": "ESNext", "skipLibCheck": true, + /* Static Path */ + "baseUrl": "src", + "paths": { + "@/*": ["*"], + "@page/*": ["routes/*"], + "@compo/*": ["components/*"], + "@type/*": ["interfaces/*"], + "@util/*": ["utils/*"], + "@style/*": ["styles/*"], + "@img/*": ["assets/images/*"] + }, + /* Bundler mode */ "moduleResolution": "bundler", "allowImportingTsExtensions": true, diff --git a/vite.config.ts b/vite.config.ts index edd7717..bd678ef 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -2,6 +2,7 @@ import { defineConfig } from 'vite'; import react from '@vitejs/plugin-react-swc'; import svgr from '@svgr/rollup'; import viteImagemin from 'vite-plugin-imagemin'; +import path from 'path'; // https://vitejs.dev/config/ export default defineConfig({ @@ -36,4 +37,21 @@ export default defineConfig({ }, }), ], + resolve: { + alias: [ + { find: '@', replacement: path.resolve(__dirname, 'src') }, + { find: '@page', replacement: path.resolve(__dirname, 'src/routes') }, + { + find: '@compo', + replacement: path.resolve(__dirname, 'src/components'), + }, + { find: '@type', replacement: path.resolve(__dirname, 'src/interfaces') }, + { find: '@util', replacement: path.resolve(__dirname, 'src/utils') }, + { find: '@style', replacement: path.resolve(__dirname, 'src/styles') }, + { + find: '@img', + replacement: path.resolve(__dirname, 'src/assets/images'), + }, + ], + }, });