본문 바로가기
프론트엔드(FrontEnd)

성격 검사 페이지 구현 회고 1 - github pages에서 react 배포하기

by codeyaki 2023. 6. 14.
반응형

https://16ssss.github.io/

 

Sixteens. site

 

16ssss.github.io

해당 페이지를 만들고 배포하면서 겪었던 문제들을 회고하기 위해서 이 글을 작성하게 되었다.

 

구현하게 된 계기

현재 진행하고 있는 프로젝트에서 웹을 다룰 줄 아는 팀원이 없었다...

그나마 내가 리액트를 접해본 적이 있었기에 내가 담당하게 되었다. (백엔드에서 어느 정도 성장을 이루면 프런트엔드도 맛보리라 생각했기에 이 기회에 맛을 봐보자라고 생각했었음)

그렇게 나만 믿으라며 의기양양하게 시작하게 된 리액트... 하지만 시작부터 순조롭지 않았다.

 

gh-pages

리액트를 깃허브 페이지에 배포하기 위해서는 빌드한 파일을 레파지토리에 올리고 github pages 설정을 해주어야 한다.

이걸 직접 했었는데 빌드할때마다 반복하게 되는 것이 불편해 이를 해결해줄 라이브러리를 찾게 되었다. 

열심히 검색해본 결과 gh-pages라는 좋은 라이브러리를 발견하게 되었다.

이를 사용하면 자동으로 branch에 푸시를 해준다.

사용방법

ph-pages의 사용방법은 이러하다.

1. gh-pages 설치

npm install gh-pages

2. gh-pages 실행

gh-pages -d build

해당 코드를 실행하게 되면 빌드 파일들을 "gh-pages" 브랜치에 푸시시켜준다.

이를 npm 스크립트에 추가하여 npm run deploy로 간편하게 빌드와 푸시를 한 번에 할 수 있도록 하였다.

"scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject",
    "deploy": "react-scripts build \ngh-pages -d build"
},

마지막 줄에 deploy 부분이 새롭게 추가된 줄이다.

이제 터미널에 npm run deploy를 입력하면 자동으로 빌드 후 푸시하게 된다.

 

3. github pages 설정

이제 마지막으로 github에서 배포할 브랜치를 설정해 주면 끝난다.

배포하는 레파지토리에 들어가서 Settings -> pages에 들어가면 해당 화면이 나온다.

이와 같이 설정해주면 이제 gh-pages에 푸시가 발생하면 자동으로 배포되게 된다.


Github pages에서의 SPA

github pages를 설정하고 이제 개발을 진행해서 테스트를 해봤는데 다른 문제가 발생했다. 바로 흰 화면만 나오는 문제가 발생하였다. 왜 이러한 문제가 생기는지 알아보았다.

React는 SPA이다. SPA란 빌드 시에 하나의 페이지에 자바스크립트를 이용하여 실시간으로 변화가 생기는 부분만 계속 바꿔주는 방법이다. 덕분에 사용자는 매번 화면이 깜빡이는 느낌이 없이 앱을 사용하는 것과 같은 느낌을 받게 된다. 거기에 나는 react-router-dom을 추가하여 url에 따른 페이지를 제공하도록 만들었다.

문제는 Github Pages의 동작방식에 있었다. Github Pages는 정적 페이지를 제공하는 방식이다. 즉 html파일이 있어야 해당 url에 해당하는 페이지를 제공할 수 있다는 것이었다. 때문에 url을 이동시키면 404페이지를 볼 수밖에 없었다.

이것을 어떻게 해결할 수 있을까 고민하던 찰나 해외의 좋은 오픈소스가 있어서 해결할 수 있었다.

 

https://github.com/rafgraph/spa-github-pages

 

GitHub - rafgraph/spa-github-pages: Host single page apps with GitHub Pages

Host single page apps with GitHub Pages. Contribute to rafgraph/spa-github-pages development by creating an account on GitHub.

github.com

 

사용 방법

1. Copy over the 404.html file to your repo as is
Note that if you are setting up a Project Pages site and not using a custom domain (i.e. your site's address is username.github.io/repo-name), then you need to set pathSegmentsToKeep to 1 in the 404.html file in order to keep /repo-name in the path after the redirect. If you are using React Router you'll need to tell it to use the repo-name as the basename, for example <BrowserRouter basename="/repo-name" />.

2. Copy the redirect script in the index.html file and add it to your index.html file - Note that the redirect script must be placed before your single page app script in your index.html file.  

레파지토리에 있는 사용방법을 그대로 가져와 보았다.

차근차근 따라 해 보면 손쉽게 우리도 배포할 수 있게 된다.

1. 404.html을 만든다.

404.html 파일을 그대로 복사하여 저장소에 추가하십시오. 참고로, 사용자 정의 도메인을 사용하지 않고 프로젝트 페이지 사이트를 설정하는 경우 (즉, 사이트 주소가 username.github.io/repo-name인 경우), 404.html 파일의 pathSegmentsToKeep을 1로 설정해야 리디렉션 후 경로에 /repo-name을 유지할 수 있습니다. React Router를 사용하는 경우 repo-name을 basename으로 사용하도록 설정해야 합니다. 예를 들어 <BrowserRouter basename="/repo-name" />입니다.

React를 사용하는 기준으로 public 디렉터리에 404.html을 만들고 아래의 내용을 그대로 복붙 해주면 된다.

<!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
        // MIT License
        // https://github.com/rafgraph/spa-github-pages
        // 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. https://www.foo.tld/one/two?a=b&c=d#qwe, becomes
        // https://www.foo.tld/?/one/two&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 pathSegmentsToKeep 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/?/one/two&a=b~and~c=d#qwe
        // Otherwise, leave pathSegmentsToKeep as 0.
        var pathSegmentsToKeep = 0;

        var l = window.location;
        l.replace(
            l.protocol + '//' + l.hostname + (l.port ? ':' + l.port : '') +
            l.pathname.split('/').slice(0, 1 + pathSegmentsToKeep).join('/') + '/?/' +
            l.pathname.slice(1).split('/').slice(pathSegmentsToKeep).join('/').replace(/&/g, '~and~') +
            (l.search ? '&' + l.search.slice(1).replace(/&/g, '~and~') : '') +
            l.hash
        );

    </script>
</head>
<body>
</body>
</html>
  • 만약 자신의 깃허브 페이지가 레파지토리와 동일하지 않고 username.github.io/repo-name 형태를 가지고 있다면 위의 코드 중 pathSegmentsToKeep을 1로 설정해주어야 한다. 그래야 url이 유지되며 이동하게 된다. 안 그러면 뒤에 /repo-name부분이 제거되어 정상적인 url로 리다이렉트 되지 않는다!
  • 또한 basename을 설정해 주어야 한다.
const router = createBrowserRouter(
  [
    {
      path: '',
      element: <Example />,
    },
  ],
  { basename: process.env.PUBLIC_URL }
);

const root = ReactDOM.createRoot(document.getElementById('root'));

root.render(
  <React.StrictMode>
    <RouterProvider router={router} />
  </React.StrictMode>
);
  • 이러한 형태로 basename을 넣어주면 된다!

2. index.html에 script 코드를 추가한다.

index.html 파일에서 리디렉션 스크립트를 복사하여 index.html 파일에 추가하십시오. 참고로, 리디렉션 스크립트는 index.html 파일에서 싱글 페이지 앱 스크립트 앞에 배치되어야 합니다.
<!-- Start Single Page Apps for GitHub Pages -->
<script type="text/javascript">
  // Single Page Apps for GitHub Pages
  // MIT License
  // https://github.com/rafgraph/spa-github-pages
  // This script checks to see if a redirect is present in the query string,
  // 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[1] === '/') {
      var decoded = l.search
        .slice(1)
        .split('&')
        .map(function (s) {
          return s.replace(/~and~/g, '&');
        })
        .join('?');
      window.history.replaceState(
        null,
        null,
        l.pathname.slice(0, -1) + decoded + l.hash
      );
    }
  })(window.location);
</script>
<!-- End Single Page Apps for GitHub Pages -->

이 코드를 index.html에 넣어주기만 하면 된다

이러한 설정들을 해주면 이제 github pages에서 정상적으로 리액트를 배포할 수 있게 된다. 얏호~ ⭐️

 

 

반응형