{"id":17543933,"url":"https://github.com/altmshfkgudtjr/simple-react-template","last_synced_at":"2025-04-24T00:04:31.579Z","repository":{"id":52177652,"uuid":"296382681","full_name":"altmshfkgudtjr/Simple-React-Template","owner":"altmshfkgudtjr","description":"This is React-based code that can be quickly generated.","archived":false,"fork":false,"pushed_at":"2022-08-14T09:44:48.000Z","size":65617,"stargazers_count":4,"open_issues_count":0,"forks_count":2,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-04-24T00:04:21.061Z","etag":null,"topics":["ducks","javascript","react","redux","template"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/altmshfkgudtjr.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-09-17T16:29:38.000Z","updated_at":"2025-02-17T11:03:43.000Z","dependencies_parsed_at":"2022-08-24T04:00:52.147Z","dependency_job_id":null,"html_url":"https://github.com/altmshfkgudtjr/Simple-React-Template","commit_stats":null,"previous_names":[],"tags_count":14,"template":true,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/altmshfkgudtjr%2FSimple-React-Template","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/altmshfkgudtjr%2FSimple-React-Template/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/altmshfkgudtjr%2FSimple-React-Template/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/altmshfkgudtjr%2FSimple-React-Template/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/altmshfkgudtjr","download_url":"https://codeload.github.com/altmshfkgudtjr/Simple-React-Template/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250535098,"owners_count":21446508,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ducks","javascript","react","redux","template"],"created_at":"2024-10-21T00:43:03.654Z","updated_at":"2025-04-24T00:04:31.556Z","avatar_url":"https://github.com/altmshfkgudtjr.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Simple-React-Template\n\n[![GitHub license](https://camo.githubusercontent.com/890acbdcb87868b382af9a4b1fac507b9659d9bf/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d626c75652e737667)](https://github.com/altmshfkgudtjr/Simple-React-Template/blob/master/LICENSE) [![img](https://img.shields.io/github/v/release/altmshfkgudtjr/Simple-React-Template?color=%2312b886)](https://github.com/altmshfkgudtjr/Simple-React-Template/releases/tag/v1.0.2)[![Language grade: JavaScript](https://img.shields.io/lgtm/grade/javascript/g/altmshfkgudtjr/Simple-React-Template.svg?logo=lgtm\u0026logoWidth=18)](https://lgtm.com/projects/g/altmshfkgudtjr/Simple-React-Template/context:javascript)\n\n**This is React-based code that can be quickly generated.**\n\n빠르게 리액트 환경을 구축할 수 있는 템플릿입니다.\n\n- **CSS in JS** : styled-components를 사용하여 간편하게 컴포넌트 별로 스타일을 적용할 수 있습니다.\n\n- **Redux-toolkit** : 상태관리를 효율적으로 하기 위해서 Store 구조를 사용합니다. 또한 개발속도를 향상시키기 위해서, 각 Reducer들은 Slice로 작성되었습니다.\n\n- **Redux-thunk** : 미들웨어로 redux-thunk를 적용하였습니다.\n\n- **Build**: `yarn build`를 통해서 작성한 코드들을 production mode로 빌드할 수 있습니다. 본 템플릿에서는 다음과 같은 과정을 빌드가 진행됩니다.\n  - **Pre Build** : 작성한 모든 test파일들을 진행합니다. 이 때, 통과하지 못한 파일이 존재하면 빌드과정이 진행되지 않습니다.\n  - **Build** : Sourcemap 파일을 제외한 빌드를 진행합니다.\n\n## How to run?\n\n```shell\nyarn install // 필요 패키지를 설치합니다.\n\nyarn start // HMR(Hot Module Replacement)이 가능한 개발 서버를 실행합니다.(기본포트:3000)\nyarn test // .test.js로 끝나는 파일을 대상으로 테스트를 진행합니다.\nyarn build // 작성한 코드를 대상으로 빌드과정을 진행합니다.\n```\n\n## Directory Structure\n\n```shell\nSimple-React-Template\n│\n│  .env\n│  .gitingnore\n│  jsconfig.json\n│  package-lock.json\n│  yarn.lock\n│  package.json\n│\n├─public\n│  │  index.html\n│  │  manifest.json\n│  │  robots.txt\n│  ├─css\n│  ├─favicons\n│  ├─fonts\n│  ├─icons\n│  └─images\n│\n└─src\n    │  App.js\n    │  index.js\n    │  serviceWorker.js\n    │  setupTests.js\n    │  testUtils.js\n    │\n    ├─components\n    │  ├─home\n    │  │\n    │  └─modal\n    │      └─info\n    │  └─common\n    │          Snackbar.js\n    │\n    ├─containers\n    │      Home.js\n    │  └─modal\n    │          index.js\n    │          Info.js\n    │  └─common\n    │          Snackbar.js\n    |          Modal.js\n    │\n    ├─controllers\n    │      fetch.js\n    │\n    ├─lib\n    │  └─styles\n    │          animations.js\n    │          media.js\n    │          palette.js\n    │          styles.js\n    │          zIndex.js\n    │  └─utils\n    │  └─hooks\n    │  └─svg\n    |       └─index.js\n    │\n    ├─slices\n    │  │  index.js\n    │  │  modal.js\n    │  │  snackbar.js\n    │  │\n    │  └─__test__\n    │          modal.test.js\n    │          snackbar.test.js\n    │\n    └─pages\n           HomePage.js\n           NotFound.js\n```\n\n- **Public** : 정적 자원를 저장하는 폴더입니다. 필요한 favicons 들과 이미지들이 존재합니다.\n\n- [**package.json**](https://github.com/altmshfkgudtjr/Simple-React-Template/blob/master/package.json) : 해당 프로젝트의 이름과 버전 및 프로젝트 정보들을 수정 및 확인할 수 있습니다.\n\n      이 외에도 proxy를 설정하여 개발을 진행할 때, 개발 서버를 대상을 API를 호출할 수 있습니다.\n\n      ```json\n\n  \"proxy\": \"http://localhost:5000\"\n\n  ```\n\n  ```\n\n- [**jsconfig.json**](https://github.com/altmshfkgudtjr/Simple-React-Template/blob/master/jsconfig.json) : 해당 프로젝트에서의 컴파일러 옵션 등을 설정할 수 있습니다.\n  (현재 설정은 src를 기준으로 절대경로가 설정되었습니다. 아래 스크립트와 같이 사용할 수 있습니다.)\n\n  ```javascript\n  import Component from \"components/path/Component\";\n  // src/components/path/Component\n  ```\n\n- **.env**: 해당 프로젝트 실행에 필요한 환경변수는 해당 파일에서 추가 및 수정할 수 있습니다.\n\n- **components** : View를 담당하는 컴포넌트들을 저장하는 폴더입니다.\n\n- **containers** : View에 관련한 로직들을 담당하는 컴포넌트들을 저장하는 폴더입니다.\n\n- **controllers** : API들을 저장하는 폴더입니다.\n\n- **lib** : 프로젝트에 필요한 추가 모듈들을 저장하는 폴더입니다.\n\n      - **hooks** : 공통 hook에 대해서 모아둔 폴더입니다.\n\n  - **styles** : Component에서 사용하는 공통 스타일에 대해서 모아둔 폴더입니다.\n  - **utils** : Component에서 사용하는 공통 로직에 대해서 모아둔 폴더입니다.\n  - **svg** : 아이콘으로 사용하기 위한 svg 파일을 모아둔 폴더입니다.\n\n- **slices** : Reducer들을 저장하는 폴더입니다.\n\n- **pages** : 각 페이지를 저장하는 폴더입니다.\n\n- \\***\\* test \\*\\*** : (test와 \\_\\_ 사이의 공백은 없습니다.) 각 컴포넌트, 모듈의 테스트 코드를 저장하는 폴더입니다.\n\n# Details\n\n개발 속도를 향상시키기 위해서 필수적이라 생각하는 기능 및 파일들이 존재합니다.\n\n## IE Redirect\n\nInternet Explorer 브라우저일 경우에는 리다이렉트 페이지가 표시되도록 구현되어 있습니다. 만약 IE를 대상으로 구현하는 프로젝트일 경우 index.html 파일의 다음 코드를 지워주시길 바랍니다.\n\n```html\n// index.html\n\n\u003cscript\u003e\n  if (/MSIE \\d|Trident.*rv:/.test(navigator.userAgent)) {\n    window.location = \"microsoft-edge:\" + window.location;\n    setTimeout(function () {\n      window.location = \"https://go.microsoft.com/fwlink/?linkid=2135547\";\n    }, 0);\n  }\n\u003c/script\u003e\n```\n\n## Default Modal\n\n\u003e 기존의 [v1.2.3](https://github.com/altmshfkgudtjr/Simple-React-Template/releases/tag/v1.2.3)에서는 modal을 보여주는 과정에서 React Component를 넘기게 되어서 직렬화가 안 되는 문제가 있었습니다. 이번 패치에서는 해당 문제를 해결해 `redux-devtool`의 시간여행 기능을 안정적으로 사용할 수 있습니다.\n\n기본적으로 모달이 작동하는 파일이 포함되어 있습니다. 본 모달은 Redux를 사용하여 작동합니다.\n(해당 방식의 사용은 선택사항입니다.)\n\n모달 reducer에는 기본적으로 다음과 같은 액션이 존재합니다.\n\n- **pushModal** : 모달을 등록하는 함수입니다. 해당 액션을 통해서 여러개의 모달을 스택처럼 등록시킬 수 있으며, 순서를 유지한채로 화면에 표시됩니다. (같은 모달 컴포넌트를 2개 이상 사용할 수 없습니다.)\n- **popModal** : 등록된 모달에서 가장 나중에 등록된 모달부터 스택처럼 제거할 수 있습니다.\n- **deleteModal** : 모달별로 고유의 name을 이용하여 특정 모달만 제거할 수 있습니다.\n- **clearModal** : 현재 등록된 모든 모달을 제거할 수 있습니다.\n\n파일은 `containers/modal/Info.js` 이며, 해당 모달을 부르고 싶은 컴포넌트에서 해당 파일명을 dispatch하여 사용하게 됩니다.그 후, modal module에 존재하는 `pushModal` 액션을 사용하여 모달을 작동시킵니다. 각 모달은 반드시 `name`에 **Modal Component 명**을 넣어서 호출해야 합니다. 만약 name값이 존재하지 않다면 해당 모달은 정상적으로 작동하지 않을 것입니다. 아래는 모달을 호출하는 예시입니다.\n\n```javascript\n// containers/modal/Info.js\n\nexport const Info = ({ PreventModalOff, ModalOff, args }) =\u003e {\n  ...\n  return (\n    ...\n  );\n}\n```\n\n```javascript\n// containers/modal/index.js\n\nexport { Info } from \"containers/modal/Info\";\n```\n\n```javascript\n// components/home/Btn.js\n\nconst Btn = () =\u003e {\n  const dispatch = useDispatch();\n\n  const modalOn = () =\u003e\n    dispatch(\n      pushModal({\n        name: \"Info\",\n        args: { title: \"Simple\" },\n      })\n    );\n\n  return \u003cButton onClick={modalOn}\u003eSimple\u003c/Button\u003e;\n};\n```\n\n`containers/modal/index.js`에 등록된 모달 파일에서는 `PreventModalOff` 와 `ModalOff` 및 `args` 인자가 기본적으로 제공됩니다. `PreventModalOff` 함수는 `onMouseDown` 속성으로 모달 최상위 속성에 등록해주시길 바랍니다. `ModalOff`는 선택적 사항입니다. `args`는 모달을 호출하는 컴포넌트에서 모달에게 매개변수를 전달할 수 있습니다. 기본적으로 Background에 MouseDown 이벤트로 모달이 닫히도록 작동됩니다. 이 외에 버튼을 통해서 모달을 닫는 경우, 해당 함수를 사용해주시길 바랍니다.\n\n## Default Snackbar\n\n기본적으로 사용자에게 보다 나은 Alert 표시를 위해서 Snackbar 구조가 포함되어 있습니다. 본 스낵바는 Redux를 사용하여 작동합니다. (해당 방식의 사용은 선택사항입니다.)\n\n기본적으로 스낵바 타입은 다음과 같습니다.\n\n- **SUCCESS** : Green Color\n- **WARNING** : Red Color\n- **ERROR** : Orange Color\n- **INFO** : BlueColor\n\n스낵바를 호출하는 방식은 아래 예시를 참고하십시오.\n\n```javascript\n/* This file is Sample Component to call a snackbar. */\n\nimport React from \"react\";\nimport { useDispatch } from \"react-redux\";\nimport Button from \"components/path/Button\";\nimport { newSnackbar } from \"modules/snackbar\";\n\nconst Btn = () =\u003e {\n  const dispatch = useDispatch();\n\n  const onSnackbar = () =\u003e {\n    dispatch(\n      newSnackbar({\n        type: \"INFO\",\n        message: \"테스트 문구\",\n      })\n    );\n  };\n\n  return \u003cButton onClick={onSnackbar}\u003eSnackbar\u003c/Button\u003e;\n};\n\nexport default Btn;\n```\n\n## Default Fetch file\n\n기본적으로 비동기 통신을 위해서 [fetch API](https://developer.mozilla.org/ko/docs/Web/API/Fetch_API)가 사용됩니다. 해당 파일에서는 API를 쉽게 사용할 수 있도록 작성되었습니다.\n(본 파일 사용유무는 선택사항입니다. 사용하지 않으면 지워주시길 바랍니다.)\n\n```javascript\nconst Fetch = (url, method, sendData, callback, failed) =\u003e { ... };\n```\n\n기본적으로 해당 모듈은 다음과 같은 인자를 필요로 합니다.\n\n- **url**\u003c string \u003e : Target url입니다. 예시) `/board/1/post/3`\n- **method**\u003c string \u003e : 기본적으로 API는 REST API 메소드를 준수하여 타입을 지정하였습니다. 만약 다른 메소드를 사용할 경우, 해당 타입을 수정할 수 있습니다. `POST`, `GET`, `DELETE`, `PUT`, `PATCH` 등이 존재합니다.\n- **sendData**\u003c object \u003e : HTTP 요청을 할 때, 필요한 data입니다. 기본적으로 json/application으로 보내지며, sendData는 JSON화 되어서 통신이 진행됩니다. FormData 타입도 지원합니다.\n- **callback**\u003c function \u003e : 통신이 완료된 후에 실행될 콜백함수입니다. 선택사항입니다.\n- **failed**\u003c function \u003e : 4xx 또는 5xx 에러(대표적으로 404, 502)가 발생할 경우, 실행될 함수입니다. 선택사항입니다.\n\n**headers**값의 Accept 속성에 'application/json' 을 적용하여, Backend로부터 송신되는 API별 에러 메세지를 확인할 수 있도록 하였습니다.\n\n해당 모듈은 **Promise** 객체를 반환합니다. 아래와 같이 사용 가능합니다.\n\n```javascript\nimport Fetch from \"./fetch\";\n\nPromise.all([\n  Fetch(\"/api/first\", \"POST\", { key: \"value\" }),\n  Fetch(\"/api/second\", \"POST\", { key: \"value\" }),\n  Fetch(\"/api/third\", \"POST\", { key: \"value\" }),\n]);\n\n// or\n\nFetch(\"/api/first\", \"GET\")\n  .then((data) =\u003e {\n    console.log(data);\n  })\n  .catch((err) =\u003e {\n    console.log(err);\n  });\n\n// or\n\nFetch(\n  \"/api/first\",\n  \"POST\",\n  { key: \"value\" },\n  (data) =\u003e {\n    console.log(data);\n  },\n  (err) =\u003e {\n    console.log(err);\n  }\n);\n```\n\n## [Removed] Default Authorization (JWT)\n\n\u003e 해당 기능은 보일러 플레이트라는 목적에 맞게 코드에서 제거하였습니다. 대신 `Fetch`파일을 수정하여 얼마든지 추가 사용자 유효성 검증을 진행할 수 있습니다.\n\n기본적으로 JWT Token을 받는다의 가정하에 작성되었습니다. Token을 보내는 곳은 [fetch.js](https://github.com/altmshfkgudtjr/Simple-React-Template/blob/master/src/controllers/fetch.js) 파일에서 상단에 WebStorage에서 token을 가져오게 됩니다. 이 방식을 사용하려면 Client에서 받는 모든 스크립트 등 해킹에 사용될 수 있는 코딩에 사용되는 입력 및 출력 값에 대해서 검증하고 무효화시켜야 합니다. 만약 그럼에도 XSS 공격에 대해서 원천 차단하기 위해서는 WebStorage에는 민감한 정보를 저장하지 않는 것이 좋습니다. 대안으로 `HttpOnly` 와 `Secure` 속성을 적용시킨 Cookie를 사용하는 것이 있습니다. 만약 Cookie 방식으로 Authorization을 진행한다면 위 `fetch.js` 파일에서 WebStorage와 관련된 코드를 수정하면 됩니다.\n\n```javascript\n// fetch.js\n\nconst Fetch = (url, method, sendData, callback, failed) =\u003e {\n\tconst headers = {};\n\n    ...\n\n    /*\n\t\twrite here custom header properties.\n\t*/\n\n    ...\n}\n```\n\n# Feedback \u0026 Issue\n\n[피드백 및 이슈 제기](https://github.com/altmshfkgudtjr/Simple-React-Template/issues) 는 언제나 환영입니다. 필요한 기능이거나 불필요한 기능이라고 생각된다면, 언제든지 Issue로 남겨주시길 바랍니다.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faltmshfkgudtjr%2Fsimple-react-template","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faltmshfkgudtjr%2Fsimple-react-template","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faltmshfkgudtjr%2Fsimple-react-template/lists"}