next를 사용합니다.react 공유기가 있는 js

이 재구매 파일은 다음 설정에서 Next.js(로컬 SSR 기능 유지)을 사용하려는 시도를 기록합니다.
  • 단일 입구점(예를 들어 Create React AppHops).파일 시스템 기반 라우팅 없음

  • react-router을 유일한 루트 시스템으로
  • 이 파일은 다음과 같은 방법으로 얻을 수 있습니다.
  • GitHub repository

  • 면책 성명

  • 다음.js팀은 이런 방법을 강력히 반대한다.
  • 본 실험은 다음 시험 때 진행된다.js v9.3: 그때부터 프레임워크에 큰 변화가 생겼다.
  • 첫 번째 섹션, 기본 설정


    1 - 다음 설치.회사 명


    관련 repo commit.
    Install NextJS, pages/index.js에 단일 입구점 파일을 만듭니다.

    2 - 모든 요청을 단일 포털 지점으로 리디렉션


    관련 repo commit.
    파일 시스템 기반 라우팅을 건너뛰기 위해 custom Next.js server을 구성하여 모든 요청을 하나의 입구점으로 전달합니다.
    Next를 사용합니다.js Server.render method으로 입구점을 렌더링하고 서비스합니다.
    // server.js
    const express = require('express');
    const nextJS = require('next');
    
    async function start() {
      const dev = process.env.NODE_ENV !== 'production';
      const app = nextJS({dev});
      const server = express();
      await app.prepare();
    
      // Redirect all requests to main entrypoint pages/index.js
      server.get('/*', async (req, res, next) => {
        try {
          app.render(req, res, '/');
        } catch (e) {
          next(e);
        }
      });
    
      server.listen(3000, err => {
        if (err) throw err;
        console.log(`> Ready on http://localhost:3000`);
      });
    }
    
    start();
    
    dev 서버를 실행하면 pages/index.js곳의 입구점 페이지는 요청 URL의 응답으로 해야 합니다.👊

    3 - react 라우터 소개


    관련 repo commit.
    요청한 URL에 따라 다른 응답을 얻기 위해서는 루트 시스템이 필요합니다.
    우리는 react-router(docs about SSR 참조)을 사용하고 환경 응용 프로그램 환경(서버 또는 브라우저)에 따라 StaticRouter 또는 BrowserRouter을 사용하여 응용 프로그램을 포장할 것입니다.react-routerreact-router-dom 설치:
    npm i react-router react-router-dom -S
    
    ...pages/index.js 입구점을 업데이트하여 Link의 일부 Routereact-router-dom 구성 요소를 사용합니다(repo 참조).
    이제 애플리케이션을 적절한 라우터로 포장하는 withReactRouter HOC를 설명합니다.
    // next/with-react-router.js
    import React from 'react';
    import {BrowserRouter} from 'react-router-dom';
    const isServer = typeof window === 'undefined';
    
    export default App => {
      return class AppWithReactRouter extends React.Component {
        render() {
          if (isServer) {
            const {StaticRouter} = require('react-router');
            return (
              <StaticRouter
                location={this.props.router.asPath}
              >
                <App {...this.props} />
              </StaticRouter>
            );
          }
          return (
            <BrowserRouter>
              <App {...this.props} />
            </BrowserRouter>
          );
        }
      };
    };
    
    ...withReactRouter HOC로 어플리케이션 포장:
    // pages/_app.js
    import App, {Container} from 'next/app';
    import React from 'react';
    import withReactRouter from '../next/with-react-router';
    
    class MyApp extends App {
      render() {
        const {Component, pageProps} = this.props;
        return (
          <Container>
            <Component {...pageProps} />
          </Container>
        );
      }
    }
    
    export default withReactRouter(MyApp);
    
    dev 서버를 실행하면 실시간 루트와 서버 쪽 렌더링을 볼 수 있습니다.

    제2부분, 언어 환경 정보


    내가 가장 좋아하는 react-router 기능 중 하나는 렌더링 단계에서 adding context information을 사용하고 context 대상에 수집된 정보에 따라 서버 측의 응답을 되돌려주는 것이다.
    이렇게 하면 클라이언트 코드는 노드 서버가 되돌아오는 응답을 제어할 수 있다. 예를 들어'페이지를 찾지 못했습니다'가 아니라 HTTP 404를 되돌리거나 클라이언트가 되돌아오는 것이 아니라 진정한 HTTP 302 방향을 되돌릴 수 있다.
    이러한 작업을 수행하려면 Next를 구성해야 합니다.js에서 다음을 수행합니다.
  • 요청한 페이지를 보여줍니다. 응용 공유기
  • 에 상하문 대상을 제공합니다
  • 상하문 대상이 렌더링 과정에서 돌연변이가 발생했는지 확인
  • 상하문 대상
  • 에 따라 표시된 페이지로 돌아갈지 아니면 다른 조작을 할지 결정합니다

    4 - 라우터에 컨텍스트 객체 제공


    관련 repo commit.
    우리는 Express의 context 대상에 빈 req.local 대상을 주입하고 React Context을 통해 공유기 응용 프로그램에 사용할 수 있도록 합니다.context 객체를 Express의 req.local 객체에 주입합니다.
    // server.js
    server.get('/*', async (req, res, next) => {
      try {
    +   req.locals = {};
    +   req.locals.context = {};
        app.render(req, res, '/');
    
    다음js는 reqres의 대상을 getInitialProps static method의 아이템으로 제공합니다.req.originalUrlreq.locals.context을 가져와 정적 공유기에 처리할 것입니다.
    // next/with-react-router.js
      return class AppWithReactRouter extends React.Component {
    +   static async getInitialProps(appContext) {
    +     const {
    +       ctx: {
    +         req: {
    +           originalUrl,
    +           locals = {},
    +         },
    +       },
    +     } = appContext;
    +     return {
    +       originalUrl,
    +       context: locals.context || {},
    +     };
    +   }
    
      // Code omitted
              <StaticRouter
    -           location={this.props.router.asPath}
    +           location={this.props.originalUrl}
    +           context={this.props.context}
              >
    

    5 - 개별 구현 및 응답


    관련 repo commit.
    우리는 SSR과 서버 응답 사이에 req.locals.context 기반의 추가 서버 비헤이비어를 제공하기를 원하기 때문에, 다음에.jsServer.render은 유연성이 부족합니다.
    Next를 사용하여 Server.render에서 server.js을 다시 구현합니다.jsServer.renderToHTMLServer.sendHTML 방법.
    코드가 생략되었음을 주의하십시오.완전한 실현을 이해하려면 원본 코드를 참조하십시오.
    // server.js
      server.get('/*', async (req, res, next) => {
        try {
    +     // Code omitted
    
          req.locals = {};
          req.locals.context = {};
    -     app.render(req, res, '/');
    +     const html = await app.renderToHTML(req, res, '/', {});
    +
    +     // Handle client redirects
    +     const context = req.locals.context;
    +     if (context.url) {
    +       return res.redirect(context.url)
    +     }
    +
    +     // Handle client response statuses
    +     if (context.status) {
    +       return res.status(context.status).send();
    +     }
    +
    +     // Code omitted
    +     app.sendHTML(req, res, html);
        } catch (e) {
    
    HTML이 표시된 응답을 클라이언트에게 보내기 전에 context 객체를 검사하고 필요할 때 사용자 정의 HTTP 코드를 다시 지정하거나 되돌려줍니다.
    테스트를 진행하기 위해 pages/index.js 입구점을 make use of <Redirect> and <Status> components으로 업데이트하고 dev 서버를 시작하십시오.

    총결산


    우리는 다음 설정을 어떻게 하는지 보여 주었다.js는 react-router을 충분히 이용하여 단일 입구점 방법을 지원하고 SSR을 완전히 보존합니다.
    이를 위해, 우리는:
  • 모든 서버 요청을 단일 포털 지점으로 리디렉션

  • 적절한 react-router 라우터 패키지 어플리케이션 사용(HOC 사용)
  • req 객체를 locals.context 서버 객체에 주입
  • req.locals.contextreq.originalUrl이 포함된 HOC 패키지를 제공합니다.

  • 다음 단계로 확장합니다.js Server.render HTML
  • 보내기 전에 req.locals.context 고려
    userland 코드에서 Server.render을 다시 실현하는 것이 가장 불안한 부분이지만 Next에서 확장자 Server.render API가 필요하지 않을 수 있습니다.js.

    결과


    반응 라우터 렌더링 서버 측


    reactrouter의 <Route> 구성 요소는 받은 req.originalUrl URL을 기반으로 서버에서 정적으로 표시됩니다.

    클라이언트 코드가 HTTP 302 리디렉션 트리거


    서버 구현 프로세스가 <Redirect from="/people/" to="/users/" /> 구성 요소를 만났을 때 서버 응답은 예상 Location 헤더를 포함하는 HTTP 302 응답을 되돌려줍니다.

    클라이언트 코드에서 HTTP 404 트리거


    서버 구현 프로세스가 <Status code={404}/> 구성 요소를 만났을 때 서버 응답은 예상 상태 코드가 있는 HTTP 응답으로 되돌아옵니다.

    한층 더 고려하다


    나는 이 설정이 결코 가장 좋은 것이 아니라고 확신한다.나는 어떤 건의, 피드백, 개선과 생각도 기꺼이 고려한다.

    문제

  • 내보내지 않은 정적 페이지
  • 개발 모드에서 요구에 따라 구축할 수 없는 루트
  • getInitialProps 미실시
  • 좋은 웹페이지 즐겨찾기