치춘짱베리굿나이스

gh-pages로 리액트 프로젝트 배포 + 404 에러처리 본문

ClientSide/라이브러리

gh-pages로 리액트 프로젝트 배포 + 404 에러처리

치춘 2022. 5. 15. 12:04

gh-pages

설치

$> npm install gh-pages --save-dev
$> yarn add gh-pages

npm 링크

gh-pages

 

gh-pages

Publish to a gh-pages branch on GitHub (or any other branch on any other remote). Latest version: 4.0.0, last published: 4 days ago. Start using gh-pages in your project by running `npm i gh-pages`. There are 885 other projects in the npm registry using gh

www.npmjs.com

yarn 링크

Contributors

 

https://yarnpkg.com/package/gh-pages

Fast, reliable, and secure dependency management.

yarnpkg.com

용례

서버가 필요없거나 작은 토이 프로젝트를 배포할 때 도메인을 사고 서버를 사는 건 사치에 가깝다

다행히 우리에게는 깃허브 레포지토리에서 바로 배포할 수 있는 깃허브 페이지 기능이 있다 (이거 덕을 참 많이 봤다)

순수 html이랑 css만으로 구성된 프로젝트는 깃허브 페이지로 배포하기가 상당히 쉬운데, 리액트 등으로 만든 프로젝트는 그 과정이 약간 복잡하다... 만 이 라이브러리를 사용하면 builddeploy 커맨드만으로 모든 걸 해결해준다

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로 basenameprocess.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) 호스팅 하기

 

Songlog

Javascript, Typescript, Angular, React, RxJS, etc.

iamsjy17.github.io

 

'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
Comments