Skip to content

Commit

Permalink
Feat/fe s3 cd (#150)
Browse files Browse the repository at this point in the history
* eslint 설정 추가 및 stylelint 설정 추가 (#87)

* chore: eslint 설정 추가

Co-Authored-By: MYONG JAEWI <[email protected]>
Co-Authored-By: 월하 <[email protected]>

* style(src): eslint 적용

Co-Authored-By: MYONG JAEWI <[email protected]>
Co-Authored-By: 월하 <[email protected]>

* chore: stylelint 설정 추가

Co-Authored-By: MYONG JAEWI <[email protected]>
Co-Authored-By: 월하 <[email protected]>

* style(components): stylelint 적용

Co-Authored-By: MYONG JAEWI <[email protected]>
Co-Authored-By: 월하 <[email protected]>

* chore: stylelint 라이브러리, config 파일 수정

* style(components): stylelint 재적용

Co-Authored-By: MYONG JAEWI <[email protected]>
Co-Authored-By: 월하 <[email protected]>

---------

Co-authored-by: MYONG JAEWI <[email protected]>
Co-authored-by: 월하 <[email protected]>
Co-authored-by: jayming66 <[email protected]>

* chore: Jest 관련 패키지 설치 및 설정

Co-Authored-By: 헤인 <[email protected]>

* chore: React Testing Library 관련 패키지 설치

Co-Authored-By: 헤인 <[email protected]>

* chore: MSW 설치 및 설정

Co-Authored-By: 헤인 <[email protected]>

* chore: @stylelint/postcss-css-in-js 패키지 devDependencies로 변경

* chore: stylelint-config-standartd 패키지 제거

stylelint extension 사용으로 저장시 자동 Fix 기능을 이용하기 위함.
제거한 패키지로 인해 다른 eslint와 충돌, Fix 되지 않았음.

* chore: MSW 세팅

Webpack과 MSW v2 이슈로 jest.polyfills.js를 구성해줬어야함.

* chore: gitignore에 .env 파일 추가

* feat(hooks): MSW 초기 설정 테스트용 useTemplateListQuery spec 생성

* refactor(Button): 스타일 일관성 리팩토링

* refactor(Flex): 스타일 일관성 리팩토링

* refactor(Header): 스타일 일관성 리팩토링

* refactor(Input): 스타일 일관성 리팩토링

* refactor(Text): 스타일 일관성 리팩토링

* refactor(SelectList): 스타일 일관성 리팩토링

* refactor(SnippetEditor): 스타일 일관성 리팩토링

* refactor(Layout): 스타일 일관성 리팩토링

* refactor(TemplateTitleInput): 스타일 일관성 리팩토링

* feat(components): import 'type' 키워드 사용 및 type > interface 리팩토링

* refactor(SelectList): style 기본값 선언 방식 변경

* refactor(Flex): style props 객체분해할당

* fix(Button): 버튼 텍스트 중앙 정렬

* chore: stylelint 불필요한 구문 제거 및 shortHand 규칙 비활성화

* refactor(Flex): flex-flow -> flex-direction 수정

* refactor(Flex): 스타일 props 전달 방식 props.gap > {gap} 변경

* chore: eslint config 파일 json 형식으로 변경

* chore: stylelint 불필요한 설정 제거

* chore: eslint 설정에서 path alias webpack 설정 제거

* chore: jest config 옵션에 path alias 추가

* chore: jest의 setupTests에 사용하지 않는 패키지 import 제거

Co-authored-by: 헤인 <[email protected]>

* fix(SelectList): isSelected 스타일 구문 오류 수정

* refactor(Input): formNoValidate 조건 간략화

* refactor(SnippetEditor): 컴포넌트 변경사항 롤백

* refactor(SelectList): Text-color isSelected 조건 수정

* refactor(components): 컴포넌트 Props에서 불필요한 optional 제거 및 반영

* refactor(components): styled-components에서 컴포넌트의 Props 사용

* refactor(components): children 대신 PropsWithChildren 사용

* refactor(components): 컴포넌트 매개변수에서 기본값 정의 및 수정사항 반영

* feat(workflows): frontend ci 설정

* refactor(Text): Text 서브컴포넌트 assign 방식 변경

DX(코드 추천)를 위하여 변경

* fix(SelectList): Text color 값 오류 해결

* refactor(Text): Text 컴포넌트 prop color Optional 제거

* fix(Text): TextWrapper 'size' 단위 'rem' 추가

* fix(Flex): 타입 확장 (HTMLAttributes<HTMLDivElement>)

* refactor(components): import 'React' 생략

* refactor(Header): 불필요한 styled-component 삭제

* refactor(components): import 구문에 path-alias 사용

* refactor(Button): 'variant' 이름 변경 (default > contained>

* refactor(Button): Props 타입 변경, 속성 변경

* refactor(Flex): React 객체 제거

* chore: dotenv 설치 및 webpack 설정 추가

* refactor(public): index.html 에서 불필요한 script 제거

* feat(api): customFetch

* feat(api): endPoint 및 queryKey 상수화

* feat(api): customFetch 활용하여 templates 관련 요청 함수 생성

* refactor(src): 응답 json 객체 키 카멜케이스로 변경

api 요구사항에 맞게 응답 json 객체 키 카멜케이스로 변경

* refactor(utils): 불필요한 convertToCamelCase 삭제

* refactor(hooks): queryKey 상수 적용 및 api 요청 함수 적용

* test(hooks): useTemplateListQuery, useTemplateQuery, useTemplateUploadQuery 테스트

* refactor(src): UploadsTemplate => TemplateUpload 로 변경

* feat(utils): formatRelativeTime

* test(utils): formatRelativeTime

* refactor(src): formatRelativeTime 적용 및 SyntaxHighlighter에 fontSize 추가

* chore: msw setupWorker 설정

* feat(Button): size 속성에 filled 타입 추가

* feat(.storybook): storybook에 path alias 설정 추가

* refactor(Flex): props 변수명을 rests로 변경

* style(Header): import 순서 변경

* refactor(Input): Props의 타입을 InputHTMLAttributes를 extend하도록 변경

* refactor(api): header에 'Content-Type': 'application/json' 추가

* test(utils): formatRelativeTime 테스트 명세 수정

* refactor(src): TEMPLATE_API_URL templates 파일에서 export 및 config 파일 제거

* fix(pages): Text Title에 color 추가

* chore: CI에 Type Checking 추가, packge.json 스크립트 tsc 추가 및 start => dev로 변경

* refactor(src): contentSummary => thumbnailContent 로 필드명 변경

* feat(routes): basename 설정

* refactor(workflows): CI 설정 run 명령에 'run' 추가

* chore: webpack의 file-loader 제거, webpack5의 설정으로 대체

* refactor(src): 컴포넌트 import/export 방식 변경 및 반영

* refactor(src): 이미지 import/export 방식 변경 및 반영

* refactor(src): 훅, 유틸 import/export 방식 변경 및 반영

* refactor(src): 페이지 import/export 방식 변경 및 반영

* chore: eslint import 외부/내부 모듈 간 newLine 규칙 추가

* refactor(src): eslint 외부/내부 모듈 import간 newLine 규칙 반영

* refactor(src): API import/export 방식 변경 및 반영

* refactor(SelectList): styled-component 'Container'를 'Flex' 컴포넌트로 변경

* refactor(Template): Template 페이지 프레임 구조 수정

* refactor(Template): Template 페이지 폴더링

* chore: webpack의 설정을 common, dev, prod로 파일 변경

해당 과정에서 dotenv 패키지를 dotenv-webpack 패키지로 변경
브라우저 환경에서 process undefined 에러를 해결하기 위해 process 패키지 설치

* refactor(api): BASE_URL -> API_URL 변수명 변경

환경변수의 변수명에 맞춤

* refactor(routes): 환경변수 파일 분리에 따른 BASE_URL 분기처리 제거

* refactor(components): import 경로 변경 ('..' > '@/components')

* refactor(TemplateItem): utils import 방식 미반영사항 수정

* refactor(components): index.ts에 EOL 추가

* refactor(routes): basename 제거

* chore: webpack.common.js로 파일명 변경, clear 옵션 추가

* feat(src): template 수정, 삭제 요청 함수 생성

* feat(mocks): template 수정, 삭제 handlers 추가

* feat(hooks): useTemplateEditQuery

* test(hooks): useTemplateEditQuery

* feat(hooks): useTemplateDeleteQuery

* test(hooks): useTemplateDeleteQuery

* chore: publicPath 옵션을 webpack.dev.js로 변경

* chore: process 패키지 제거

process 패키지는 배포(브라우저) 환경에서 환경변수를 위한 process 모듈을 찾지 못하는 에러를 잡기 위함이었다.
다만 dotenv-webpack의 공식 문서의 방식인 ignoreStuyb : ture 옵션으로 충분히 해결 가능하다고 판단.

* refactor(src): 페이지에 'Page' suffix 추가

* refactor(src): 업로드 라우팅 주소 변경 (uploads > upload)

* feat(src): 'TemplateEditPage' 구현

* refactor(routes): basename 제거

* refactor(src): browser worker 주석 제거

* feat(workflows): 배포 파이프라인 구현

---------

Co-authored-by: 헤인 <[email protected]>
Co-authored-by: MYONG JAEWI <[email protected]>
Co-authored-by: 월하 <[email protected]>
Co-authored-by: jayming66 <[email protected]>
Co-authored-by: 월하 <[email protected]>
  • Loading branch information
6 people authored Jul 25, 2024
1 parent 894ace6 commit 71b0d0c
Show file tree
Hide file tree
Showing 90 changed files with 13,493 additions and 6,900 deletions.
52 changes: 52 additions & 0 deletions .github/workflows/front_cd.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
name: Frontend CD

on:
push:
branches:
- main
- develop

jobs:
build:
runs-on: ubuntu-latest
env:
frontend-directory: ./frontend
steps:
- uses: actions/checkout@v4

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 20

- name: Install Dependencies
run: npm install
working-directory: ${{ env.frontend-directory }}

- name: Run Build
run: npm run build
working-directory: ${{ env.frontend-directory }}

- name: Upload Artifact
uses: actions/upload-artifact@v4
with:
name: code-zap-front
path: ${{ env.frontend-directory }}/dist/**

deploy:
needs: build
runs-on: self-hosted
steps:
- name: Make Artifact Directory
run: mkdir ${{ secrets.FRONT_DIRECTORY }}

- name: Download Artifact
uses: actions/download-artifact@v4
with:
name: code-zap-front
path: ${{ secrets.FRONT_DIRECTORY }}

- name: Move To S3
run: |
aws s3 cp --recursive ${{ secrets.FRONT_DIRECTORY }} s3://techcourse-project-2024/code-zap
rm -rf ${{ secrets.FRONT_DIRECTORY }}
31 changes: 31 additions & 0 deletions .github/workflows/frontend_ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
name: Frontend CI

on:
pull_request:
branches:
- '**'

jobs:
build-with-test:
runs-on: ubuntu-latest
env:
frontend-directory: ./frontend
steps:
- uses: actions/checkout@v4

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 20

- name: Install Dependencies
run: npm install
working-directory: ${{ env.frontend-directory }}

- name: Run Type Checking
run: npm run tsc
working-directory: ${{ env.frontend-directory }}

- name: Run Tests
run: npm run test
working-directory: ${{ env.frontend-directory }}
20 changes: 0 additions & 20 deletions frontend/.eslintrc.cjs

This file was deleted.

103 changes: 103 additions & 0 deletions frontend/.eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
{
"root": true,
"env": {
"browser": true,
"es2020": true
},
"extends": [
"eslint:recommended",
"plugin:prettier/recommended",
"plugin:@typescript-eslint/recommended",
"plugin:import/recommended",
"plugin:react/recommended",
"plugin:react-hooks/recommended",
"plugin:react/jsx-runtime",
"plugin:storybook/recommended"
],
"ignorePatterns": ["dist", "*.config.ts", "*.common.js", "*.prod.js", "*.dev.js", "*.polyfills.js"],
"parser": "@typescript-eslint/parser",
"plugins": ["react-refresh", "react", "import"],
"settings": {
"import/resolver": {
"typescript": {
"alwaysTryTypes": true
},
"node": {
"extensions": [".js", ".jsx", ".ts", ".tsx"]
}
}
},
"rules": {
"prettier/prettier": "error",
"padding-line-between-statements": [
"error",
{ "blankLine": "always", "prev": "*", "next": "return" },
{ "blankLine": "always", "prev": ["const", "let", "var", "function", "block-like"], "next": "*" },
{ "blankLine": "any", "prev": ["const", "let", "var"], "next": ["const", "let", "var"] },
{ "blankLine": "always", "prev": "case", "next": "*" }
],
"prefer-template": "error",
"object-shorthand": ["error", "always"],
"prefer-arrow-callback": "error",
"func-style": ["error", "expression", { "allowArrowFunctions": true }],
"arrow-body-style": ["error", "as-needed"],
"consistent-return": "error",
"curly": ["error", "all"],
"default-case": "error",
"default-case-last": "error",
"no-fallthrough": "error",
"import/newline-after-import": ["error", { "count": 1 }],
"import/order": [
"error",
{
"groups": [
["builtin", "external"],
["internal", "parent", "sibling", "index", "type"]
],
"warnOnUnassignedImports": true,
"alphabetize": { "order": "asc" },
"newlines-between": "always",
"distinctGroup": false,
"pathGroups": [
{
"pattern": "@storybook/**",
"group": "external",
"position": "before"
},
{
"pattern": "@/**",
"group": "internal",
"position": "before"
},
{
"pattern": "./**",
"group": "sibling",
"position": "after"
}
]
}
],
"import/extensions": [
"error",
"ignorePackages",
{
"js": "never",
"jsx": "never",
"ts": "never",
"tsx": "never"
}
],
"react-refresh/only-export-components": ["error", { "allowConstantExport": false }],
"react/no-unknown-property": ["error", { "ignore": ["css"] }],
"import/no-default-export": "error"
},
"overrides": [
{
"files": ["*.tsx", "*.d.ts"],
"rules": {
"import/no-default-export": "off",
"import/prefer-default-export": "error"
}
}
]
}
4 changes: 4 additions & 0 deletions frontend/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,7 @@ node_modules
*storybook.log

dist

.env
.env.development
.env.production
11 changes: 8 additions & 3 deletions frontend/.storybook/main.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { StorybookConfig } from '@storybook/react-webpack5';
import { Configuration } from 'webpack';

import path from 'path';
const config: StorybookConfig = {
stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|mjs|ts|tsx)'],
addons: [
Expand All @@ -27,10 +27,15 @@ const config: StorybookConfig = {
},
],
});

config.resolve = {
...config.resolve,
alias: {
...config.resolve?.alias,
'@': path.resolve(__dirname, '../src'),
},
};
return config;
},

framework: {
name: '@storybook/react-webpack5',
options: {},
Expand Down
4 changes: 4 additions & 0 deletions frontend/.stylelintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"extends": ["stylelint-config-clean-order"],
"customSyntax": "postcss-styled-syntax"
}
21 changes: 21 additions & 0 deletions frontend/jest.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import type { Config } from 'jest';

const config: Config = {
preset: 'ts-jest',
testEnvironment: 'jsdom',
setupFiles: ['./jest.polyfills.js'],
testEnvironmentOptions: {
customExportConditions: [''],
},
setupFilesAfterEnv: ['./setupTests.ts'],
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json'],
transform: {
'^.+\\.tsx?$': 'ts-jest',
},
clearMocks: true,
moduleNameMapper: {
'^@/(.*)$': '<rootDir>/src/$1',
},
};

export default config;
34 changes: 34 additions & 0 deletions frontend/jest.polyfills.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
const { ReadableStream, TransformStream } = require('node:stream/web');
const { TextDecoder, TextEncoder } = require('node:util');

Object.defineProperties(globalThis, {
TextDecoder: { value: TextDecoder },
TextEncoder: { value: TextEncoder },
ReadableStream: { value: ReadableStream },
TransformStream: { value: TransformStream },
});

Object.defineProperties(globalThis, {
TextDecoder: { value: TextDecoder },
TextEncoder: { value: TextEncoder },
ReadableStream: { value: ReadableStream },
});

const { Blob, File } = require('node:buffer');
const { fetch, Headers, FormData, Request, Response } = require('undici');

Object.defineProperties(globalThis, {
fetch: { value: fetch, writable: true },
Blob: { value: Blob },
File: { value: File },
Headers: { value: Headers },
FormData: { value: FormData },
Request: { value: Request },
Response: { value: Response },
});

globalThis.setImmediate = (callback, ...args) => setTimeout(callback, 0, ...args);

globalThis.clearImmediate = (immediateId) => {
clearTimeout(immediateId);
};
Loading

0 comments on commit 71b0d0c

Please sign in to comment.