치춘짱베리굿나이스
gh-pages로 리액트 프로젝트 배포 + 404 에러처리 본문
gh-pages
설치
$> npm install gh-pages --save-dev
$> yarn add gh-pages
npm 링크
yarn 링크
용례
서버가 필요없거나 작은 토이 프로젝트를 배포할 때 도메인을 사고 서버를 사는 건 사치에 가깝다
다행히 우리에게는 깃허브 레포지토리에서 바로 배포할 수 있는 깃허브 페이지 기능이 있다 (이거 덕을 참 많이 봤다)
순수 html이랑 css만으로 구성된 프로젝트는 깃허브 페이지로 배포하기가 상당히 쉬운데, 리액트 등으로 만든 프로젝트는 그 과정이 약간 복잡하다... 만 이 라이브러리를 사용하면 build
와 deploy
커맨드만으로 모든 걸 해결해준다
CRA
로 생성한 프로젝트만 gh-pages 라이브러리가 적용된다는 이야기도 있으니 참고하자
1. gh-pages 설치
설치하자.
2. package.json 수정
{
"homepage": "https://[내 닉네임].github.io/[레포지토리 이름]/",
"name": "[프로젝트 이름]",
"version": "0.1.0",
"private": true,
"dependencies": {
...
package.json에 homepage
키와 주소를 추가한다
배포가 이루어질 깃허브 페이지 주소를 적으면 되는데, 따로 url을 설정해주는 것이 아닌 이상 위의 구성을 따르므로 저대로 적어주면 대개 된다
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject",
"predeploy": "yarn run build", // 이거
"deploy": "gh-pages -d build" // 이거
},
그리고 scripts
요소에 predeploy
, deploy
커맨드를 추가한다
필자는 yarn을 사용했기 때문에 yarn run build
를 사용했는데, npm이라면
"predeploy": "npm run build"
"deploy": "gh-pages -d build"
yarn만 npm으로 바꿔주면 된다
3. 커맨드 입력
$> yarn run deploy
$> npm run deploy
이 커맨드를 입력하면 gh-pages 라이브러리가 프로덕션 빌드를 진행하고, 레포지토리에 gh-pages 브랜치를 생성하여 빌드 결과를 밀어넣는다
4. 페이지가 안 나오고 readme.md가 나온다면?
혹시나 페이지가 제대로 안 뜬다면 Settings - Pages 에서 브랜치를 gh-pages로 설정하자
5. 페이지 링크가 제대로 적용되지 않는다면?
<BrowserRouter basename={process.env.PUBLIC_URL}>
...
</BrowserRouter>
페이지에 들어가도 브라우저 라우터가 적용되지 않고 404가 뜬다면 라우터의 BrowserRouter
props로 basename
을 process.env.PUBLIC_URL
로 넘겨주자
페이지의 루트 링크 기준으로 라우터가 작동하게 된다
6. 라우트한 페이지에서 새로고침을 하면 404 에러가 발생한다?
<!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>
프로젝트의 루트 경로 / public 폴더에 404.html
을 생성하고 위와 같이 적어넣는다
출처: https://github.com/rafgraph/spa-github-pages/blob/gh-pages/404.html
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<meta name="React Movie App" content="React Movie App to search & favorite" />
<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 -->
또한 index.html
의 헤더 부분을 위와 같이 수정한다
출처: https://github.com/rafgraph/spa-github-pages/blob/gh-pages/index.html
let, const가 아니라 var인 게 신경쓰인다면 let으로 수정한다
404 에러가 발생했을 때 주소로부터 쿼리 데이터와 하위 페이지 이름을 쿼리스트링으로 만들어주고, index.html에서 이 값을 쿼리스트링으로 읽어들여 다시 리디렉션시켜주는 방법이다
github pages 특성상 SPA (Single Page App) 을 지원하지 않기 때문에 발생한 오류로, 해시 라우터를 사용하는 방법도 있다고 하지만 url이 길어지며 동작을 안할 가능성도 있기 때문에 404 리디렉션을 사용하였다
참고자료
[React] GitHub Pages에 React App(SPA) 호스팅 하기
'ClientSide > 라이브러리' 카테고리의 다른 글
redux + toolkit (0) | 2022.05.21 |
---|---|
react-query 1. useQuery (0) | 2022.05.20 |
React-Beautiful-Dnd (0) | 2022.05.15 |
lodash (0) | 2022.05.14 |
store (0) | 2022.05.12 |