{"componentChunkName":"component---src-templates-post-js","path":"/개발/2020/10/10/start-next-js-1/","result":{"data":{"markdownRemark":{"fields":{"slug":"/개발/2020/10/10/start-next-js-1/","date":"2020-10-10"},"frontmatter":{"title":"Next.js 시작해보자 1/5 - Next.js App 생성, 페이지 추가, Navigate Between Pages, Link, code splitting, client-side navigation, and prefetching","tags":["nextjs","react framework"],"author":"jslee"},"id":"9b03b22c-0ed1-5f83-8392-239b94a4720b","html":"<p>Gatsby와 함께 핫하다는 <code class=\"language-text\">Next.js</code>를 시도해보려고 한다. Gatsby의 경우 좀더 틀에 박힌 느낌? SpringBoot 처럼 그냥 따라해의 느낌이 강했는데, Next.js는 gatsby에 비해서 좀더 유연하게 React 관련 프로젝트를 구성할수 있다고 해서 시작해보려고 한다. (지금까지 시도해보지 않고 내가 그냥 읽은 글에서 느낀점을 작성해봄!)</p>\n<h1>시작하기</h1>\n<p><a href=\"https://nextjs.org/\">https://nextjs.org/</a></p>\n<div class=\"gatsby-highlight\" data-language=\"sh\"><pre class=\"language-sh\"><code class=\"language-sh\">npx create-next-app nextjs-blog --use-npm --example &quot;https://github.com/vercel/next-learn-starter/tree/master/learn-starter&quot;\ncd nextjs-blog\nnpm run dev</code></pre></div>\n<p><figure class=\"gatsby-resp-image-figure\" style=\"margin: 0 0;\">\n    <span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 800px; \"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/5e3f0095d7799ee1953e306e1213f8f6/d77a7/Cover.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n    <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 73.5%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAPCAYAAADkmO9VAAAACXBIWXMAABYlAAAWJQFJUiTwAAABw0lEQVQ4y6VUy2rCQBT1/7/BVVddicWCtIvWlVKhhmiqolEjPqKoicZ3Hp7mTDtpYhWhHThMZrhzcx6TpPA9TqcT/jriZ1NcBEEgFrVaDblcDsViEYqiQFVVVCoVfNTrUN7LULpLFPQA1ZEXwoc2DvBhBonGiYalUgnpdBqZTEYgn88jm83itVDAU/4RL8oQ9yrwUPPx3PRxV3bxZvhRM9HwEu3D4YDFYoH5fA7HcTCZTLDebLBxbOydObaOhcA7nkn+Op+KdydTYrvdwrIsgeVyKZqLmeuVE2KF49H9RSSS/J8w4ogYkpVt21iFb+ZMeJ6Hc/ZkudvtLt6IhIeu66JarYqUZbr0j9JlY86apqHX62G9XoeSj9jv99iE3rLO9/0fhizu9/vodrsChmFA13URBg/JmuFwiE6ng2aziVarhdlsJmqm06kglZBMuZRE8JlJx+WwhokTZEhckp269pVwjzLYKH5X40PeClkTMSTdevg10MfBYHAxUdbQw0ajEcm7Ggr9YSA8wMYEPaKXcQ+5z8A408t2u43RaCR8lAoiD03TxHg8FjPNZxGZyELK556sIRgGX0REkm9d7POLe+uP8wlLToAXeDy+xQAAAABJRU5ErkJggg=='); background-size: cover; display: block;\"\n  ></span>\n  <picture>\n        <source\n          srcset=\"/static/5e3f0095d7799ee1953e306e1213f8f6/a5e6d/Cover.webp 200w,\n/static/5e3f0095d7799ee1953e306e1213f8f6/2276a/Cover.webp 400w,\n/static/5e3f0095d7799ee1953e306e1213f8f6/cf465/Cover.webp 800w,\n/static/5e3f0095d7799ee1953e306e1213f8f6/cbd37/Cover.webp 1200w,\n/static/5e3f0095d7799ee1953e306e1213f8f6/64296/Cover.webp 1600w,\n/static/5e3f0095d7799ee1953e306e1213f8f6/2bc88/Cover.webp 1770w\"\n          sizes=\"(max-width: 800px) 100vw, 800px\"\n          type=\"image/webp\"\n        />\n        <source\n          srcset=\"/static/5e3f0095d7799ee1953e306e1213f8f6/56d15/Cover.png 200w,\n/static/5e3f0095d7799ee1953e306e1213f8f6/d9f49/Cover.png 400w,\n/static/5e3f0095d7799ee1953e306e1213f8f6/78d47/Cover.png 800w,\n/static/5e3f0095d7799ee1953e306e1213f8f6/64756/Cover.png 1200w,\n/static/5e3f0095d7799ee1953e306e1213f8f6/42cbc/Cover.png 1600w,\n/static/5e3f0095d7799ee1953e306e1213f8f6/d77a7/Cover.png 1770w\"\n          sizes=\"(max-width: 800px) 100vw, 800px\"\n          type=\"image/png\"\n        />\n        <img\n          class=\"gatsby-resp-image-image\"\n          src=\"/static/5e3f0095d7799ee1953e306e1213f8f6/78d47/Cover.png\"\n          alt=\"출력 화면\"\n          title=\"출력 화면\"\n          loading=\"lazy\"\n          style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        />\n      </picture>\n  </a>\n    </span>\n    <figcaption class=\"gatsby-resp-image-figcaption\">출력 화면</figcaption>\n  </figure></p>\n<p>프로젝트 시작은 gatsby와 동일하게 <code class=\"language-text\">github</code>에 있는 프로젝트를 템플릿으로 시작이 가능하다. 위에서는 <code class=\"language-text\">next-learn-starter</code>를 이용해서 페이지를 만들도록</p>\n<h1>에러 표시</h1>\n<p><figure class=\"gatsby-resp-image-figure\" style=\"margin: 0 0;\">\n    <span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 800px; \"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/7d1f7fdf79c1b7b026e09fdf89a99ff2/3f8e8/error.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n    <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 48.50000000000001%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAKCAYAAAC0VX7mAAAACXBIWXMAABYlAAAWJQFJUiTwAAABQklEQVQoz6WSy2vCQBDG92SiiBvX+NrEjZaWni0Y/30rnlQ0KnhTEdrGR6ulUauXft2NeOtLO/BjZvhmPhgY8jYe41myHI1CXiaTsD8XtTsZDkFeVyv48zkennw8+jME2y0ujflyCbLxfWxnM+zXa+yl+cdmAxwOFxkuFguQ+1oNXreLwaCPQb+Hnueh2+mgI/FkrWi322i1WmH+CqWp+el0CiIcB6VSEbYtYNkFcMuGJeGcQwgBR+qMMSSTyR8xTRONRgNENfksQ6nAICwTjs2QyxighgHDoKCU/mqmUHOhYcZMg+cyuL3K4uZaoFjMg+fTSKVSZ6GuCA1jsRhoIg6Hx5FmsqYMJksgGtWgaTp0XZdZ+5aTHolEUK/XQcrlMqru3ZGqi0qlcsR14f6R006z2QQ5yBcJggC73Tv+G758wU/GlgSCjFoxQgAAAABJRU5ErkJggg=='); background-size: cover; display: block;\"\n  ></span>\n  <picture>\n        <source\n          srcset=\"/static/7d1f7fdf79c1b7b026e09fdf89a99ff2/a5e6d/error.webp 200w,\n/static/7d1f7fdf79c1b7b026e09fdf89a99ff2/2276a/error.webp 400w,\n/static/7d1f7fdf79c1b7b026e09fdf89a99ff2/cf465/error.webp 800w,\n/static/7d1f7fdf79c1b7b026e09fdf89a99ff2/cbd37/error.webp 1200w,\n/static/7d1f7fdf79c1b7b026e09fdf89a99ff2/64296/error.webp 1600w,\n/static/7d1f7fdf79c1b7b026e09fdf89a99ff2/4c6e1/error.webp 1976w\"\n          sizes=\"(max-width: 800px) 100vw, 800px\"\n          type=\"image/webp\"\n        />\n        <source\n          srcset=\"/static/7d1f7fdf79c1b7b026e09fdf89a99ff2/56d15/error.png 200w,\n/static/7d1f7fdf79c1b7b026e09fdf89a99ff2/d9f49/error.png 400w,\n/static/7d1f7fdf79c1b7b026e09fdf89a99ff2/78d47/error.png 800w,\n/static/7d1f7fdf79c1b7b026e09fdf89a99ff2/64756/error.png 1200w,\n/static/7d1f7fdf79c1b7b026e09fdf89a99ff2/42cbc/error.png 1600w,\n/static/7d1f7fdf79c1b7b026e09fdf89a99ff2/3f8e8/error.png 1976w\"\n          sizes=\"(max-width: 800px) 100vw, 800px\"\n          type=\"image/png\"\n        />\n        <img\n          class=\"gatsby-resp-image-image\"\n          src=\"/static/7d1f7fdf79c1b7b026e09fdf89a99ff2/78d47/error.png\"\n          alt=\"에러표시\"\n          title=\"에러표시\"\n          loading=\"lazy\"\n          style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        />\n      </picture>\n  </a>\n    </span>\n    <figcaption class=\"gatsby-resp-image-figcaption\">에러표시</figcaption>\n  </figure></p>\n<p>React는 정말 알아보기 어렵게 에러를 화면에 표시하는데 <code class=\"language-text\">next.js</code>는 에러도 이렇게 잘… 표시해준다는게 놀랍다. 잠깐 사용해봐도 React는 정말 raw의 느낌인데 next.js는 개발자들이 많이 사용하고 필요로하는 기능을 넣어놓은 느낌 약간의 자유도는 떨어져도? 이정도 자유도 떨어지는건 전혀 문제되지 않음… 오히려 감사하다.</p>\n<h1>새로운 페이지 추가하기</h1>\n<p><a href=\"https://nextjs.org/learn/basics/navigate-between-pages/pages-in-nextjs\">https://nextjs.org/learn/basics/navigate-between-pages/pages-in-nextjs</a></p>\n<p>React에서 새로운 페이지를 추가하려면 Router 를 이용해서 추가하고 새로운 페이지를 만들어 연결해야 하는 작업이 필요한데 <code class=\"language-text\">Next.js</code>에서는 디렉토리에 파일만 넣으면 알아서 페이지를 만들고 navigate 까지 해준다.</p>\n<p>예를들어 내가 <code class=\"language-text\">/pages/posts/first-post.js</code>의 파일을 추가했다면 <code class=\"language-text\">/posts/first-post</code>로 URL을 접속하면 내가 추가한 파일명 그대로 접근이 가능하다.</p>\n<h1>새로운 페이지 연겨하기</h1>\n<p><a href=\"https://nextjs.org/learn/basics/navigate-between-pages/link-component\">https://nextjs.org/learn/basics/navigate-between-pages/link-component</a></p>\n<p><code class=\"language-text\">index.js</code>에 다음과 같이 추가하면 위에 추가한 페이지로 연결이 가능하다.</p>\n<div class=\"gatsby-highlight\" data-language=\"js\"><pre class=\"language-js\"><code class=\"language-js\"><span class=\"token comment\">// index.js</span>\n<span class=\"token keyword\">import</span> Link <span class=\"token keyword\">from</span> <span class=\"token string\">\"next/link\"</span><span class=\"token punctuation\">;</span>\nRead <span class=\"token operator\">&lt;</span>Link href<span class=\"token operator\">=</span><span class=\"token string\">\"/posts/first-post\"</span><span class=\"token operator\">></span><span class=\"token operator\">&lt;</span>a<span class=\"token operator\">></span><span class=\"token keyword\">this</span> page<span class=\"token operator\">!</span><span class=\"token operator\">&lt;</span><span class=\"token operator\">/</span>a<span class=\"token operator\">></span><span class=\"token operator\">&lt;</span><span class=\"token operator\">/</span>Link<span class=\"token operator\">></span>\n\n<span class=\"token comment\">// first-post.js</span>\n<span class=\"token operator\">&lt;</span>Link href<span class=\"token operator\">=</span><span class=\"token string\">\"/\"</span><span class=\"token operator\">></span>\n  <span class=\"token operator\">&lt;</span>a<span class=\"token operator\">></span>Back to home<span class=\"token operator\">&lt;</span><span class=\"token operator\">/</span>a<span class=\"token operator\">></span>\n<span class=\"token operator\">&lt;</span><span class=\"token operator\">/</span>Link<span class=\"token operator\">></span></code></pre></div>\n<h1>Client-Side Navigation</h1>\n<p><a href=\"https://nextjs.org/learn/basics/navigate-between-pages/client-side\">https://nextjs.org/learn/basics/navigate-between-pages/client-side</a></p>\n<p>위에서 사용한 <code class=\"language-text\">Link</code>의 경우 Client-side naviation이 가능하다. client-side navigation은 browser에서 수행하는 default navigation보다 빠른 JavaScript를 사용하여 페이지 전환이 발생한다. (전체 페이지를 리로드하지 않는다.)</p>\n<p><code class=\"language-text\">Link</code> 대신에 <code class=\"language-text\">href</code>를 사용하면 전체 페이지를 리로딩한다. 컴포넌트 사이에 이동을 할때 배경색이 유지된다면 <code class=\"language-text\">Link</code> 나는 배경색이고 뭐고 전체를 기존에 정의한 값으로 리로딩하고 싶다면 <code class=\"language-text\">href</code>를 사용하면 된다.</p>\n<h2>Code Splitting and Prefetches</h2>\n<p><code class=\"language-text\">Next.js</code>는 <code class=\"language-text\">code splitting</code>을 자동으로 수행하므로 각 페이지는 해당 페이지에 필요 것만 로드한다. 즉 페이지가 렌더링될때 다른 페이지의 코드는 처음에 제공되지 않는다. 이렇게 하면 수백개의 페이지를 추가해도 홈페이지가 빠르게 로드가 된다.</p>\n<p>요청한 페이지에 대한 코드만 로딩하면 페이지는 isloated. 만약 특정 페이지가 오류가 발생하면 나머지 앱들은 정상적으로 계속 동작한다.</p>\n<p>더나아가 <code class=\"language-text\">Next.js</code>의 production build에서 <code class=\"language-text\">Link</code> 컴포넌트가 브라우저의 viewport에 나타날때마다 <code class=\"language-text\">Next.js</code>는 백그라운드에 연결된 페이지의 코드를 자동으로 <code class=\"language-text\">prefetches</code> 한다. 링크를 클릭하면 대상 페이지의 코드가 이미 백그라운드에 로드되어 페이지의 전환이 거의 즉시 이루어진다.</p>\n<h2>Summary</h2>\n<p><code class=\"language-text\">code splitting, client-side navigation, and prefetching</code>을 통해 <code class=\"language-text\">Next.js</code>는 application의 최고의 퍼포먼스를 내도록 자동으로 최적화를 해준다.</p>","excerpt":"Gatsby와 함께 핫하다는 를 시도해보려고 한다. Gatsby의 경우 좀더 틀에 박힌 느낌? SpringBoot 처럼 그냥 따라해의 느낌이 강했는데, Next.js는 gatsby에 비해서 좀더 유연하게 React…"}},"pageContext":{"pagePath":"/개발/2020/10/10/start-next-js-1/","next":{"fields":{"slug":"/개발/2020/10/10/start-next-js-2/"},"frontmatter":{"title":"Next.js 시작해보자 2/5 - Assets, Metadata, and CSS","tags":["nextjs","react framework","assets","metadata","css"]}},"prev":{"fields":{"slug":"/개발/2020/10/10/make-landing-page/"},"frontmatter":{"title":"Next.js로 Landing Page 만들어보기","tags":["nextjs","react framework"]}}}},"staticQueryHashes":["1981752614","3361508366"]}