티스토리 뷰
[React] #11 뽀모도로 타이머 + 투두리스트: 에러 수정하기 + 깃허브로 배포하기
무화과(Fig) 2023. 2. 1. 19:59
*피드백은 언제나 환영합니다🙌
에러 수정하기
배포하기 전 여러 기능들이 잘 작동되는지 확인하던 중 내일 할 일 , 추후 탭에서 내용이 같은 리스트를 삭제하려고 하면 에러가 나는 것을 확인했다.
Warning: Encountered two children with the same key, `산책하기`. Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted — the behavior is unsupported and could change in a future version.
예를들어 '산책하기'라는 항목이 2개인 경우 삭제 버튼을 눌렀을 때 삭제가 되지 않고 오히려 늘어나는 현상이 생겼는데 찾아보니 key값을 text로 지정해서 그랬었다.
index로 지정했다면 각 항목에 고유한 번호가 생기기 때문에 text가 같아도 에러가 생기지 않았을 것이다.
따라서 index를 key값으로 수정했고 에러를 없앨 수 있었다.
{
list.map((textArr, i) =>
<div key={i} className='todolistitemStyle'> // key={textArr}를 key={i}로 변경했다.
<div className='checkboxAndcontent'>
<p>{textArr}</p>
</div>
<div className='removeboxDiv'>
<FaRegTrashAlt className='removebox' onClick={()=>{
let copy2 = [...list];
copy2.splice(i, 1);
setList(copy2);
}}/>
</div>
</div>
)
}
깃허브로 배포하기
무료로 배포할 수 있는 사이트는 여러가지가 있는데 아래의 링크에 다양한 사이트가 소개되어있다.
https://www.wanted.co.kr/community/post/2858
나는 깃허브 페이지를 통해 배포하였다.
Github Pages란?
Github는 공개 레포지토리에서 무료로 호스팅을 이용할 수 있는 서비스인 Github pages를 제공한다.HTML, CSS, JavaScript로 구성된 파일을 구동하고 배포해 정적(static) 웹 사이트를 호스팅할 수 있다.
또한 Github pages를 사용하게 되면 github.io라는 도메인을 사용하게 되는데 커스텀 도메인을 사용할 수도 있다.
페이지 만드는 방법
1. 레포지토리에서 pages 설정하기
커밋한 Github 레포지토리의 setting을 클릭한 뒤 왼쪽 메뉴 중 pages를 선택한다.
그럼 아래와 같은 창이 뜬다.
이 창을 들어가면 source의 branch가 none으로 설정되어 있을텐데 클릭해서 아무 branch를 선택한 뒤 save한다. save를 하면 상단에 url이 생성되는 것을 확인 할 수 있다.
하지만 url에 접속해도 자기가 만든 페이지와 연동이 안되어있기 때문에 404 페이지가 나타난다.
(저는 배포를 마치고 글을 쓰고 있어서 사진은 초기 페이지와는 다른 모습입니다. 참고바랍니다.)
2. React 프로젝트에 gh-pages 설치하기
Github는 React 프로젝트를 쉽게 배포할 수 있도록 gh-pages 라이브러리를 제공한다.
npm install gh-pages --save-dev
3. package.json 설정
package.json에 들어가서 homepage, predeploy, deploy를 작성한다.
1) homepage 설정하기
"homepage": "https://깃허브ID.github.io/레포지토리이름/",
예시)
2) predeploy, deploy 설정하기
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject",
"predeploy": "npm run build", // ⬅ 추가
"deploy": "gh-pages -d build" // ⬅ 추가
},
예시)
4. npm run deploy 실행
npm run deploy를 실행해서 gh-pages -d build 시켜준다. 자동으로 빌드도 해주고 github 원격 저장소에 배포에 필요한 파일을 보내준다.
실행이 잘 되었다면 마지막에 Published 라고 뜬다.
5. gh-pages 배포하고 레포지토리에서 다시 설정하기
다시 설정 창으로 돌아가서 branch를 gh-pages로 설정하고 저장한다.
6. 배포 확인하기
url를 눌러 배포가 잘 되었는지 확인한다.
겪었던 문제들
1. 기존 파일 제거됨
npm run deploy를 실행했는데 기존 파일들이 제거되고 gh-pages의 파일들만 남게됐다.
계속 방법을 못찾다가 hard reset으로 파일을 복구할 수 있었다.
모든 것을 날려버리기 때문에 타노스 reset으로 불리는 hard reset..
쓰기전에 이거 썼다가 파일 다 날아가면 어떡하지 걱정했는데 다행히 그렇지 않았다.
git reset --hard commit_id
깃 공부 소홀히 하지 말자..
2. 빈 화면
기존 파일을 복구한 뒤 npm run deploy를 실행했다.
이번에는 다행히 gh-pages 브랜치가 생겨서 기존 파일이 사라지지 않고 gh-pages에 새 파일이 저장됐다. 하지만 url을 누르면 빈 화면이 떴다.
문제가 발생한 이유는 Github는 도메인/페이지 방식이 아닌 도메인/프로젝트명/페이지 방식이라 Router를 이동할 경우 도메인/페이지로 이동되어 이상한 페이지로 이동되기 때문이다.
예시) https://miraclee1226.github.io/Pomodoro/ 에서 휴식 탭 이동 시 https://miraclee1226.github.io/rest/ 이렇게 변경되는데 miraclee1226.github.io 뒤에 있던 Pomodoro가 사라져 버린다.
해결방법은 2가지가 있다.
1. HashRouter 사용
가장 빠른 방법이다. BrowserRouter 대신 HashRouter를 사용하는 것이다. 하지만 주소에 #이 붙는다는 단점이 있다.
2. BrowserRouter에 basename 추가하기
BrowserRouter에 basename props를 추가하면 프로젝트의 기본 URL을 설정해줄 수 있다.
라우터로 이동할 경우 "/"를 기준으로 이동하는 것이 아닌 "/Pomodoro/"을 기준으로 이동하는 것이다.
<BrowserRouter basename={process.env.PUBLIC_URL}>
<Router />
</BrowserRouter>
나는 주소에 #붙는게 싫어서 2번째 방법을 이용해 문제를 해결했다.
3. 새로고침시 404 페이지 뜸
배포까지 끝내고 친구에게 자랑할겸😙 url을 보냈는데 친구가 url에 접속하고 새로고침을 누르자 404페이지가 떴다고 알려줬다. 끝났다고 신나서 뻗었는데 404페이지 떴다는 말 듣고 다시 컴퓨터 앉았다. 제길ㅋ
-새로고침 시 404 페이지가 뜨는 이유
gh-pages는 단순히 호스팅만 한다면 새로고침시 404 page가 뜬다.
이유는 SPA를 지원하지 않기때문이다.
*SPA(Single Page Application)란?
기존 웹 서비스는 요청시마다 서버로부터 리소스들과 데이터를 해석하고 화면에 렌더링하는 방식이다.
그러나 SPA형태는 브라우저 최초에 한번 페이지 전체를 로드하고, 이후부터는 특정 부분만 Ajax를 통해 데이터를 바인딩하는 방식이다. 따라서 Router를 사용하는 React의 경우 SPA로 동작하는 경우 웹 서버는 파일을 검색하지 못하고 404 메세지를 사용자에게 반환한다.
문제는 아래의 상황에서 발생한다.
1. 새로고침 버튼을 눌렀을 때
2. 방문페이지 이외의 페이지에 직접 엑세스 할 때 ex) /help 나 /help/online 과 같이 웹 서버가 인덱스 파일을 우회회서 찾았을 때
문제를 해결하기 위해서는 404.html을 만들어서 해당 url을 쿼리로 만들어 리다이렉션을 해줘야한다.
*쿼리란?
웹 서버에 특정한 정보를 보여달라는 웹 클라이언트 요청(주로 문자열을 기반으로 한 요청이다)에 의한 처리
*리다이렉트란?
리다이렉트란 말 그대로 re(다시) + 지시하다(direct) 다시 지시하는 것을 말한다.예를 들어 브라우저가 https://codingtoddlerr.tistory.com/70 URL을 웹 서버에 요청했다고 하자 그러면 서버는 HTTP 응답 메시지를 통해 "https://codingtoddlerr.tistory.com/68 로 다시 요청해봐!~" 라고 브라우저에게 다른 URL(길, 방향) 을 지시할 수 있는 것을 리다이렉트라 한다.
구체적인 해결 방법은 다음과 같다.
1. public 폴더에 404.html을 추가한다.
(아래 소스는 MIT license 의 오픈 소스입니다. 프로젝트 포함시 라이센스를 명시해주세요.)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Single Page Apps for GitHub Pages</title>
<script type="text/javascript">
// Single Page Apps for GitHub Pages
// https://github.com/rafrex/spa-github-pages
// Copyright (c) 2016 Rafael Pedicini, licensed under the MIT License
// ---------------------------------------------- ------------------------
// This script takes the current url and converts the path and query
// string into just a query string, and then redirects the browser
// to the new url with only a query string and hash fragment,
// e.g. http://www.foo.tld/one/two?a=b& c=d#qwe, becomes
// http://www.foo.tld/?p=/one/two& q=a=b~and~c=d#qwe
// Note: this 404.html file must be at least 512 bytes for it to work
// with Internet Explorer (it is currently > 512 bytes)
// If you're creating a Project Pages site and NOT using a custom domain,
// then set segmentCount to 1 (enterprise users may need to set it to > 1).
// This way the code will only replace the route part of the path, and not
// the real directory in which the app resides, for example:
// https://username.github.io/repo-name/one/two? a=b&c=d#qwe becomes
// https://username.github.io/repo-name/? p=/one/two&q=a=b~and~c=d#qwe
// Otherwise, leave segmentCount as 0.
var segmentCount = 1;
var l = window.location;
l.replace(
l.protocol + '//' + l.hostname + (l.port ? ':' + l.port : '') +
l.pathname.split('/').slice(0, 1 + segmentCount).join('/') + '/?p=/' +
l.pathname.slice(1).split('/').slice (segmentCount).join('/').replace(/&/g, '~and~') +
(l.search ? '&q=' + l.search.slice(1) .replace(/&/g, '~and~') : '') +
l.hash
);
</script>
</head>
<body>
</body>
</html>
2. index.html 수정하기
404.html 을 통해서 쿼리로 변경된 URL 을 index.html 에서 받게된다.
이 때 index.html 에서 해당 쿼리를 해석하여 올바른 URL 로 변경하도록 스크립트를 추가해야한다.
(아래 소스는 MIT license 의 오픈 소스입니다. 프로젝트 포함시 라이센스를 명시해주세요.)
<head>
...
<!-- Start Single Page Apps for GitHub Pages -->
<script type="text/javascript">
// Single Page Apps for GitHub Pages
// https://github.com/rafrex/spa-github-pages
// Copyright (c) 2016 Rafael Pedicini, licensed under the MIT License
// ----------------------------------------------------------------------
// This script checks to see if a redirect is present in the query string
// and converts it back into the correct url and adds it to the
// browser's history using window.history.replaceState(...),
// which won't cause the browser to attempt to load the new url.
// When the single page app is loaded further down in this file,
// the correct url will be waiting in the browser's history for
// the single page app to route accordingly.
(function (l) {
if (l.search) {
var q = {};
l.search.slice(1).split('&').forEach(function (v) {
var a = v.split('=');
q[a[0]] = a.slice(1).join('=').replace(/~and~/g, '&');
});
if (q.p !== undefined) {
window.history.replaceState(null, null,
l.pathname.slice(0, -1) + (q.p || '') +
(q.q ? ('?' + q.q) : '') +
l.hash
);
}
}
}(window.location))
</script>
<!-- End Single Page Apps for GitHub Pages -->
</head>
'Toy Project > Time to focus' 카테고리의 다른 글
- Total
- Today
- Yesterday
- innerhtml
- CSS
- Target
- map
- rest parameter
- 제어 컴포넌트
- html
- 배열
- tanstackquery
- 리액트
- 스프린트프론트엔드6기
- hydrationboundary
- 중급 프로젝트
- 비동기
- 비제어 컴포넌트
- 취업까지달린다
- currentTarget
- 코드잇스프린트
- Git
- 동기
- js
- 프론트엔드
- javascript
- react
- 코드잇 스프린트
- 유사배열객체
- 객체
- Next.js
- GitHub
- arguments
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |