Giter Site home page Giter Site logo

portfolio's Introduction

๐Ÿ“œ Personal Portfolio


Notion ์ด๋ ฅ์„œ์™€ ํ”Œ๋žซํผ์—์„œ ์ œ๊ณต๋˜๋Š” ์ด๋ ฅ์„œ ์–‘์‹์˜ ๋ถˆํŽธํ•จ์„ ๊ฐœ์„ ํ•˜๊ณ ์ž ๊ธฐํš/์ œ์ž‘ํ•˜๊ฒŒ ๋œ ๊ฐœ์ธ ์ด๋ ฅ์„œ ํ”„๋กœ์ ํŠธ์ž…๋‹ˆ๋‹ค.



๐Ÿš€ Getting Started

๋ฐฐํฌ ๋งํฌ

๋ฐฐํฌ ๋งํฌ์—๋Š” ๊ฐœ์ธ ์ •๋ณด๊ฐ€ ๋‹ด๊ฒจ์ ธ ์žˆ์–ด ๋”ฐ๋กœ ๋ช…์‹œํ•˜๊ณ  ์žˆ์ง€ ์•Š์Šต๋‹ˆ๋‹ค.


๐Ÿ“ฑ ํ”„๋กœ์ ํŠธ ์•„ํ‚คํ…์ฒ˜

์•„ํ‚คํ…์ฒ˜


โœ… ๊ตฌํ˜„ ์ƒ์„ธ ๋‚ด์šฉ


1. Vite ๊ธฐ๋ฐ˜ ํ”„๋กœ์ ํŠธ

๊ธฐ์กด์— ๋ฆฌ์•กํŠธ ํ”„๋กœ์ ํŠธ๋ฅผ ๊ตฌ์„ฑํ•  ๋•Œ CRA(Create-React-App)์„ ํ™œ์šฉํ•˜๋Š” ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•ด์™”์Šต๋‹ˆ๋‹ค. CRA๋Š” Webpack์„ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•œ ๋นŒ๋“œ ์‹œ์Šคํ…œ์„ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๊ณ  ์ดˆ๊ธฐ ์„ค์ •์ด ๋˜์–ด ์žˆ์–ด ๊ฐ„ํŽธํ•˜๋‹ค๋Š” ์ ์— ์žˆ์–ด์„œ ๋งŽ์ด ์ด์šฉํ•˜์˜€์ง€๋งŒ ์ด๋ฒˆ ํ”„๋กœ์ ํŠธ์—์„œ๋Š” ๋ณด๋‹ค ๋น ๋ฅด๊ฒŒ ๋นŒ๋“œ๋ฅผ ์ฒ˜๋ฆฌํ•œ๋‹ค๋Š” Vite๋ฅผ ์‚ฌ์šฉํ•ด๋ณด๊ณ ์ž ํ–ˆ์Šต๋‹ˆ๋‹ค.

Vite๋Š” Webpack Dev Server์™€๋Š” ๋‹ค๋ฅด๊ฒŒ ๋กœ์ปฌ ๊ฐœ๋ฐœ ์‹œ ๋ฒˆ๋“ค๋ง์„ ํ•˜์ง€ ์•Š๊ณ  ESM ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•˜์—ฌ ๋กœ์ปฌ ์„œ๋ฒ„ ๊ตฌ๋™ ์†๋„์—์„œ ์žฅ์ ์„ ๊ฐ€์ง€๊ณ  ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฒˆ ํ”„๋กœ์ ํŠธ์˜ ๊ทœ๋ชจ๊ฐ€ ํฌ์ง€ ์•Š์•„ ์‹ค์ œ ํฐ ์ฐจ์ด๋ฅผ ๋Š๋ผ์ง€ ๋ชปํ–ˆ์ง€๋งŒ Webpack ์™ธ์˜ ์ƒˆ๋กœ์šด ๋นŒ๋“œ ํˆด์„ ์‚ฌ์šฉํ•ด๋ณผ ์ˆ˜ ์žˆ์–ด์„œ ์ข‹์€ ๊ฒฝํ—˜์ด์—ˆ์Šต๋‹ˆ๋‹ค.


2. AWS S3, AWS Lambda, Amazon API Gateway ์‚ฌ์šฉ

์ด๋ ฅ์„œ์— ํ•„์š”ํ•œ ์ •๋ณด(์ž๊ธฐ์†Œ๊ฐœ, ํ”„๋กœ์ ํŠธ, ๊ฐœ์ธ์ •๋ณด ๋“ฑ)๋“ค์€ ํ˜„์žฌ ๋งˆํฌ๋‹ค์šด ํŒŒ์ผ๋กœ ์ž‘์„ฑ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ๊ธฐ์กด์—๋Š” Express๋กœ ์„œ๋ฒ„๋ฅผ ๊ตฌ์„ฑํ•˜์—ฌ ๋กœ์ปฌ ํŒŒ์ผ์—์„œ ๋งˆํฌ๋‹ค์šด ํŒŒ์ผ๋“ค์„ ์ฐพ์•„ ์‘๋‹ต ๊ฐ’์œผ๋กœ ๋ณด๋‚ด์ฃผ๋Š” ์„œ๋ฒ„๋ฅผ ๊ตฌ์ถ•ํ–ˆ์—ˆ๊ณ , ์ด๋ฅผ ๋ฐฐํฌํ•˜์—ฌ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” AWS EC2๋“ฑ์„ ํ™œ์šฉํ•œ ๋ฐฐํฌ๊ฐ€ ํ•„์š”ํ–ˆ์Šต๋‹ˆ๋‹ค.

ํ•˜์ง€๋งŒ ํ˜„์žฌ ์‚ฌ์šฉ๋˜๊ณ  ์žˆ๋Š” HTTP Method๋Š” get์„ ์‚ฌ์šฉํ•˜์—ฌ ํ•ด๋‹น ๋งˆํฌ๋‹ค์šด ํŒŒ์ผ์„ json ํ˜•ํƒœ๋กœ ์ฝ์–ด์˜ค๋Š” ๊ฒƒ์ด์—ˆ์œผ๋ฏ€๋กœ AWS EC2๋ฅผ ํ†ตํ•œ ๋ฐฐํฌ๋Š” ๋Ÿฌ๋‹ ์ปค๋ธŒ์™€ ๋น„์šฉ ์ธก๋ฉด์—์„œ ํšจ์œจ์ ์ด์ง€ ์•Š๋‹ค๊ณ  ์ƒ๊ฐํ–ˆ์Šต๋‹ˆ๋‹ค. AWS Lambda๋Š” ์„œ๋ฒ„๋ฆฌ์Šค ์ปดํ“จํŒ… ์„œ๋น„์Šค๋กœ ์„œ๋ฒ„๋ฅผ ๊ด€๋ฆฌํ•˜์ง€ ์•Š์•„๋„ ๋˜๊ณ , ํ˜„์žฌ ์‚ฌ์ดํŠธ๋ฅผ ๋ฐฉ๋ฌธํ•˜๋Š” ์‚ฌ์šฉ์ž๊ฐ€ ๋งŽ์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ๋น„์šฉ์ ์ธ ์ธก๋ฉด์—์„œ๋„ EC2๋ณด๋‹ค ์ ํ•ฉํ•˜๋‹ค๊ณ  ์ƒ๊ฐํ–ˆ์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ S3๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋กœ์ปฌ์— ํŒŒ์ผ์„ ๋”ฐ๋กœ ์ €์žฅํ•˜์ง€ ์•Š์•„๋„ ๋˜์–ด ๊ธฐ์กด์˜ Express ์„œ๋ฒ„์˜ ๊ตฌ์„ฑ์—์„œ ๋ณ€๊ฒฝํ•˜๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

๐Ÿค” ํŠธ๋Ÿฌ๋ธ” ์ŠˆํŒ…

๋ฌธ์ œ ์‚ฌํ•ญ 1. AWS Lambda ํ•จ์ˆ˜์—์„œ ์ด๋ฒคํŠธ ๊ฐ์ฒด๊ฐ€ ๋นˆ ๊ฐ’์œผ๋กœ ์ถœ๋ ฅ

์š”์ฒญ URL์˜ ์ฟผ๋ฆฌ ํŒŒ๋ผ๋ฏธํ„ฐ ๊ฐ’์„ ๊ฐ€์ ธ์˜ค๊ธฐ ์œ„ํ•ด์„œ๋Š” ๋žŒ๋‹ค ํ•จ์ˆ˜์˜ handler ํ•จ์ˆ˜์—์„œ event ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ๊ณ„์†ํ•ด์„œ event ๊ฐ์ฒด๋Š” ๋นˆ ๊ฐ’์œผ๋กœ ์ถœ๋ ฅ๋˜๊ณ  ์žˆ์—ˆ๊ณ  ์ด ๋ฌธ์ œ๋Š” API Gateway์—์„œ Lambda ํ”„๋ก์‹œ ํ†ตํ•ฉ์„ ํ™œ์„ฑํ™”ํ•˜์ง€ ์•Š์•„์„œ ์ƒ๊ธด ๋ฌธ์ œ์˜€์Šต๋‹ˆ๋‹ค.

API Gateway๊ฐ€ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ํฌํ•จํ•œ ์ด๋ฒคํŠธ ์„ธ๋ถ€ ์ •๋ณด๋ฅผ Lambda์— ์ „๋‹ฌํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ์ด ์˜ต์…˜์ด ํ™œ์„ฑํ™”๋˜์–ด์•ผ ํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด๋Š” ํด๋ผ์ด์–ธํŠธ๊ฐ€ ๋ฐฑ์—”๋“œ์—์„œ ๋‹จ์ผ Lambda ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ฉ๋‹ˆ๋‹ค.

๋ฌธ์ œ ์‚ฌํ•ญ 2. S3.GetObjectCommand์˜ ์ธ์Šคํ„ด์Šค์—์„œ Body ๊ฐ์ฒด๋ฅผ ๋ฐฐ์—ด์— ์ €์žฅํ•  ์ˆ˜ ์—†๋Š” ์˜ค๋ฅ˜

export const handler = async (event) => {
  // (...)

  for (const key of contentsKey) {
    const commandGetObject = new GetObjectCommand({
      Bucket: BUCKET,
      Key: `data/${dirname}/${key}`,
    });

    const { Body } = await s3Client.send(commandGetObject);

    if (!Body) {
      return {
        statusCode: 500,
        body: JSON.stringify({ error: "๊ฐ€์ ธ์˜ฌ ํŒŒ์ผ์ด ์กด์žฌํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค." }),
      };
    }

    const content = await Body.toString();

    contentsData.push(content); // ERROR
  }
};

Lambda์˜ handler ํ•จ์ˆ˜์—์„œ๋Š” S3 ๋ฒ„ํ‚ท ๊ฐ์ฒด์—์„œ ๊ฐ€์ ธ์˜จ ํŒŒ์ผ์„ contentsData ๋ฐฐ์—ด์— ๋„ฃ์–ด์ฃผ๋Š” ๋กœ์ง์ด ์กด์žฌํ•ฉ๋‹ˆ๋‹ค.

Body?: Readable | ReadableStream | Blob;

ํ•˜์ง€๋งŒ Body์˜ ์œ ํ˜•์€ Readable | ReadableStream | Blob(cf. type) ์œผ๋กœ ๋ฐฐ์—ด์— ์ €์žฅํ•  ์ˆ˜ ์—†์—ˆ์Šต๋‹ˆ๋‹ค. ReadableStream ํƒ€์ž…์€ ๋น„๋™๊ธฐ ์ŠคํŠธ๋ฆผ ๋ฐ์ดํ„ฐ๋ฅผ ๋‚˜ํƒ€๋‚˜๋Š” ๊ฐ์ฒด๋กœ ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ์™€ ํ•จ๊ป˜ ํŠน์ • API๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ๋ณ„๋„์˜ streamToString ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ค์–ด ReadableStream ํƒ€์ž…์„ String ํƒ€์ž„์œผ๋กœ ๋ณ€๊ฒฝํ•˜์—ฌ ๋ฐฐ์—ด์— ์ €์žฅํ•˜์˜€์Šต๋‹ˆ๋‹ค. (cf. AWS sdk Github Issue)


3. React์˜ useReducer Hooks์„ ํ™œ์šฉํ•˜์—ฌ ์„œ๋ฒ„ ์ƒํƒœ ๊ด€๋ฆฌ

function mdFileReducer(state, action) {
switch (action.type) {
case "REQUEST_FILE":
return { ...state, isLoading: true };
case "LOADING":
return { ...state, file: action.file, isLoading: false };
}
}
export default function useData(dirname) {
const [{ file, isLoading }, dispatch] = useReducer(mdFileReducer, {
file: null,
isLoading: false,
});
useEffect(() => {
dispatch({ type: "REQUEST_FILE" });
dataController.getFiles(dirname).then((file) =>
dispatch({
type: "LOADING",
file: file.data.length === 1 ? file.data[0] : file.data.reverse(),
})
);
}, [dirname]);
return { file, isLoading };
}

useData() ์ปค์Šคํ…€ ํ›…์€ API๋ฅผ ์š”์ฒญํ•˜๊ณ  ์‘๋‹ต ๊ฐ’์œผ๋กœ ๋ฐ›์€ ํŒŒ์ผ ์ •๋ณด์™€ ํŒจ์นญ ๋กœ๋”ฉ ์ƒํƒœ๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ์ด ๋•Œ React Hook ์ค‘ ํ•˜๋‚˜์ธ useReducer๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ด๋Ÿฌํ•œ ์„œ๋ฒ„์˜ ์ƒํƒœ ์—…๋ฐ์ดํŠธ ๋กœ์ง์„ ๋ถ„๋ฆฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

const [{ file, isLoading }, dispatch] = useReducer(mdFileReducer, {
file: null,
isLoading: false,
});

useState๋ฅผ ์‚ฌ์šฉํ•ด๋„ ์ƒํƒœ๋ฅผ ์—…๋ฐ์ดํŠธ ํ•  ์ˆ˜ ์žˆ์ง€๋งŒ useReducer๋ฅผ ์‚ฌ์šฉํ•จ์œผ๋กœ์จ ์ƒํƒœ ์—…๋ฐ์ดํŠธ ๋กœ์ง์„ ์ปดํฌ๋„ŒํŠธ ์™ธ๋ถ€๋กœ ๋ถ„๋ฆฌํ•  ์ˆ˜ ์žˆ์—ˆ๊ณ , ์žฌ์‚ฌ์šฉ์„ฑ์„ ์ฆ๊ฐ€์‹œํ‚ฌ ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.


๐Ÿค ์ปค๋ฐ‹ ์ปจ๋ฒค์…˜

ํƒœ๊ทธ ์„ค๋ช… (ํ•œ๊ตญ์–ด๋กœ๋งŒ ์ž‘์„ฑํ•˜๊ธฐ)
โœจ FEAT: ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ ์ถ”๊ฐ€ (๋ณ€์ˆ˜๋ช… ๋ณ€๊ฒฝ ํฌํ•จ)
๐Ÿ› FIX: ๋ฒ„๊ทธ ํ•ด๊ฒฐ
๐Ÿ’„ DESIGN: CSS ๋“ฑ ์‚ฌ์šฉ์ž UI ๋””์ž์ธ ๋ณ€๊ฒฝ
๐ŸŽจ STYLE: ์ฝ”๋“œ ํฌ๋งท ๋ณ€๊ฒฝ, ์„ธ๋ฏธ ์ฝœ๋ก  ๋ˆ„๋ฝ, ์ฝ”๋“œ ์ˆ˜์ •์ด ์—†๋Š” ๊ฒฝ์šฐ
โ™ป๏ธ REFACTOR: ํ”„๋กœ๋•์…˜ ์ฝ”๋“œ ๋ฆฌํŒฉํ† ๋ง
๐Ÿ’ฌ COMMENT: ํ•„์š”ํ•œ ์ฃผ์„ ์ถ”๊ฐ€ ๋ฐ ๋ณ€๊ฒฝ
๐Ÿ“ DOCS: ๋ฌธ์„œ๋ฅผ ์ˆ˜์ •ํ•œ ๊ฒฝ์šฐ
โš™๏ธ CHORE: ๋นŒ๋“œ ํ…Œ์Šคํฌ ์—…๋ฐ์ดํŠธ, ํŒจํ‚ค์ง€ ๋งค๋‹ˆ์ € ์„ค์ •(ํ”„๋กœ๋•์…˜ ์ฝ”๋“œ ๋ณ€๊ฒฝ X)
๐Ÿ”„๏ธ RENAME: ํŒŒ์ผ ํ˜น์€ ํด๋”๋ช…์„ ์ˆ˜์ •ํ•˜๊ฑฐ๋‚˜ ์˜ฎ๊ธฐ๋Š” ์ž‘์—…
๐Ÿšš REMOVE: ํŒŒ์ผ์„ ์‚ญ์ œํ•˜๋Š” ์ž‘์—…๋งŒ ์ˆ˜ํ–‰ํ•œ ๊ฒฝ์šฐ
๐ŸŽ‰ INIT: ์ดˆ๊ธฐ ์ปค๋ฐ‹์„ ์ง„ํ–‰ํ•œ ๊ฒฝ์šฐ

โš™๏ธ ๊ธฐ์ˆ  ์Šคํƒ

portfolio's People

Contributors

mihyunlee avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.