Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

전남대 FE_이은진 6주차 과제 #16

Open
wants to merge 12 commits into
base: eunjin210
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 59 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
module.exports = {
env: {
browser: true,
es2021: true,
node: true,
},
extends: [
'plugin:@typescript-eslint/recommended',
'airbnb/hooks',
'airbnb-typescript',
'prettier',
'plugin:storybook/recommended',
],
parser: '@typescript-eslint/parser',
parserOptions: {
project: './tsconfig.json',
ecmaFeatures: {
jsx: true,
},
ecmaVersion: 'latest',
sourceType: 'module',
},
plugins: [
'react',
'@typescript-eslint',
'react-hooks',
'json-format',
'simple-import-sort',
'@emotion',
'prettier',
],
rules: {
'react/react-in-jsx-scope': 'off',
'simple-import-sort/imports': 'error',
'simple-import-sort/exports': 'error',
'@typescript-eslint/consistent-type-imports': 'warn',
'@typescript-eslint/no-unused-vars': [
'error',
{
argsIgnorePattern: '^_',
},
],
'import/extensions': ['off'],
'import/no-extraneous-dependencies': ['off'],
'react/jsx-filename-extension': [
'warn',
{
extensions: ['.tsx', '.js', '.jsx'],
},
],
'@typescript-eslint/no-use-before-define': ['off'],
},
ignorePatterns: ['**/build/**/*', '.eslintrc.js', 'craco.config.js'],
settings: {
'import/resolver': {
typescript: {},
},
},
};
25 changes: 25 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# dependencies
/node_modules
/.pnp
.pnp.js

# testing
/coverage

# production
/build

# misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local

npm-debug.log*
yarn-debug.log*
yarn-error.log*

.yaml
3 changes: 3 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
/.vscode
/node_modules

8 changes: 8 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"singleQuote": true,
"semi": true,
"tabWidth": 2,
"trailingComma": "all",
"printWidth": 100,
"arrowParens": "always"
}
36 changes: 36 additions & 0 deletions .storybook/main.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import type { StorybookConfig } from '@storybook/react-webpack5';
import TsconfigPathsPlugin from 'tsconfig-paths-webpack-plugin';
import path from 'path';

const config: StorybookConfig = {
stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|mjs|ts|tsx)'],
addons: [
'@storybook/addon-links',
'@storybook/addon-essentials',
'@storybook/preset-create-react-app',
'@storybook/addon-onboarding',
'@storybook/addon-interactions',
],
webpackFinal: async (config) => {
config.resolve?.plugins?.push(
new TsconfigPathsPlugin({
configFile: path.resolve(__dirname, '../tsconfig.json'),
}),
);

return config;
},
framework: {
name: '@storybook/react-webpack5',
options: {
builder: {
useSWC: true,
},
},
},
docs: {
autodocs: 'tag',
},
staticDirs: ['../public'],
};
export default config;
16 changes: 16 additions & 0 deletions .storybook/preview.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import type { Preview } from '@storybook/react';
import '@/styles';

const preview: Preview = {
parameters: {
actions: { argTypesRegex: '^on[A-Z].*' },
controls: {
matchers: {
color: /(background|color)$/i,
date: /Date$/i,
},
},
},
};

export default preview;
92 changes: 91 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,91 @@
# react-deploy
# react-deploy

## Step 1 📝기능 요구 사항
### 작성한 API 문서를 기반으로 팀 내에서 지금까지 만든 API를 검토하고 통일하여 변경 사항을 반영한다.

- [ ] 팀 내에서 일관된 기준을 정하여 API 명세를 결정한다.
- [ ] 때로는 클라이언트의 편의를 위해 API 명세를 결정하는 것이 좋다.
- [ ] 팀 내에 배포 될 API가 여러개 일 경우 상단 네비게이션 바에서 선택 가능하게 한다.
- [ ] 프론트엔드의 경우 배포와 사용자가 팀 내 여러 서버 중 하나를 선택하여 서비스를 이용
- [ ] 팀내 백엔드 엔지니어의 이름을 넣고, 이름을 선택하면 해당 엔지니어의 API로 API통신을 하게 한다.
- [ ] 기본 선택은 제일 첫번째 이름으로 한다.

## Step 2 📝기능 요구 사항
### 세가지 방법 중 본인이 원하는 방식으로 배포한다. (단, 가능하면 최대한 방법 1, 3번으로 진행하고 CI/CD를 구축하는 것을 권장해요)

- [ ]방법1.
- [ ]github action을 사용하여 ci/cd를 구성한다.
cloudflare의 pages에 배포한다.

- [ ]방법2.
- [ ]vercel을 사용하여 배포한다.

- [ ]방법3.
- [ ] github pages를 사용하여 배포한다.
서버 API가 의도대로 잘 동작하는지 확인하고, 문제가 있다면 해결한다.

## Step4 📝질문 답변

# 웹 개발 질문 답변

## 🧐 질문 1. SPA 페이지를 정적 배포를 하려고 할 때 Vercel을 사용하지 않고 한다면 어떻게 할 수 있을까요?


- **GitHub Pages**:
- GitHub Pages는 GitHub 저장소의 정적 파일을 호스팅할 수 있다.
- 프로젝트를 GitHub 저장소에 push하고, `gh-pages` 브랜치를 사용하여 배포할 수 있다.
- GitHub Actions를 이용해 CI/CD를 설정하면, 코드가 푸시될 때마다 자동으로 배포할 수 있다.

- **Netlify**:
- Netlify는 정적 사이트를 호스팅할 수 있는 서비스로, CI/CD 통합 기능을 제공한다.
- Git 저장소를 연결하고, 빌드 명령어를 설정하면 코드 푸시 시 자동으로 배포된다.


## 🧐 질문 2. CSRF나 XSS 공격을 막는 방법은 무엇일까요?

**CSRF(Cross-Site Request Forgery) 공격을 막기 위한 방법**:

- **CSRF 토큰 사용**:
- 각 요청에 대해 고유한 토큰을 생성하고, 이를 서버와 클라이언트가 공유하여 요청의 유효성을 검증한다.
- 서버는 요청을 처리하기 전에 토큰을 검증하여 CSRF 공격을 방지한다.

- **SameSite 쿠키 속성 설정**:
- 쿠키에 `SameSite` 속성을 설정하여 크로스사이트 요청 시 쿠키가 전송되지 않도록 한다.
- `SameSite=Strict` 또는 `SameSite=Lax`를 설정하여 CSRF 공격을 방지할 수 있다.


**XSS(Cross-Site Scripting) 공격을 막기 위한 방법**:

- **입력 값 검증 및 인코딩**:
- 사용자 입력 값을 철저히 검증하고, HTML 특수 문자를 인코딩하여 악성 스크립트가 실행되지 않도록 한다.
- 서버와 클라이언트 모두에서 입력 값을 검증하는 것이 중요하다.

- **Content Security Policy (CSP) 설정**:
- `Content-Security-Policy: script-src 'self';`를 설정하여 외부 스크립트 실행을 차단할 수 있습니다.


## 🧐 질문 3. 브라우저 렌더링 원리에 대해 설명해주세요.

브라우저 렌더링은 사용자가 웹 페이지를 요청하고, 이를 화면에 표시하는 과정이다.

- **1. HTML 파싱 및 DOM 생성**:
- 브라우저가 HTML 파일을 받아서 파싱하고, DOM트리를 생성

- **2. CSS 파싱 및 CSSOM 생성**:
- 브라우저가 CSS 파일을 받아서 파싱하고, CSSOM트리를 생성

- **3. 렌더 트리 생성**:
- DOM과 CSSOM을 결합하여 렌더 트리 생성
- 렌더 트리는 실제로 화면에 표시될 요소만 포함

- **4. 레이아웃 계산**:
- 렌더 트리를 바탕으로 각 요소의 크기와 위치를 계산
- "reflow" 또는 "layout"이라고 불림

- **5. 페인팅**:
- 레이아웃 계산 결과를 바탕으로 픽셀 단위로 화면에 요소를 그림
- 이 과정은 "painting" 또는 "rasterization"이라고 불림

- **6. 컴포지팅**:
- 브라우저는 여러 레이어를 결합하여 최종 화면을 구성
- 컴포지팅은 GPU를 사용하여 수행되는 경우가 많아 성능 최적화에 중요함
10 changes: 10 additions & 0 deletions babel.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
module.exports = {
presets: [
'@babel/preset-env',
'@babel/preset-react',
'@babel/preset-typescript'
],
plugins: [
['@babel/plugin-transform-react-jsx', { runtime: 'automatic' }]
]
};
9 changes: 9 additions & 0 deletions craco.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
const path = require('path');

module.exports = {
webpack: {
alias: {
'@': path.resolve(__dirname, 'src'),
},
},
};
15 changes: 15 additions & 0 deletions jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
module.exports = {
roots: ['<rootDir>'],
moduleNameMapper: {
'^@/(.*)$': '<rootDir>/src/$1',
'^axios$': require.resolve('axios')
},
transform: {
'^.+\\.(js|jsx|ts|tsx)$': 'babel-jest'
},
transformIgnorePatterns: [
'node_modules/(?!(axios)/)'
],
testEnvironment: 'jsdom',
setupFilesAfterEnv: ['@testing-library/jest-dom/extend-expect']
};
Loading