vue ssr+koa 2 서버 렌 더 링 예제 코드 구축

이전에 활동 투입 페이지 를 바 이 두,360 등 채널 에 투입 하고 koa 2+모델 엔진 방식 을 사용 했다.몇 가지 문 제 를 발견 하 다
  • 프레임 워 크 개발 페이지 에 비해 효율 이 낮 고 유지 보수 성 이 떨어진다
  • 호환성 문 제 는 페이지 에 매장 점 을 추가 한 후에 일부 사용자 의 데 이 터 를 얻 지 못 한 것 을 발견 했다.조사 한 결과 각 경 로 를 통 해 온 사용자 의 장치 에 아직도 대량의 저 버 전의 브 라 우 저 가 포함 되 어 있 음 을 발견 했다.
  •  서버 렌 더 링
     서버 렌 더 링 과 단일 페이지 렌 더 링 차이
    아래 두 장의 그림 을 보면 서버 렌 더 링 이 라면 브 라 우 저 에서 직접 완전한 html 구 조 를 얻 을 수 있 습 니 다.한 페이지 는 일부 script 태그 가 도입 한 js 파일 로 가상 dom 을#app용기 에 걸 었 습 니 다.
     
     
    @vue/cli 4 프로젝트 구조 구축
    다음 코드 는 가장 간단 한 인 스 턴 스 전체 코드 를 사용 하여 github 에 올 립 니 다.
    step 1 최신 비계 설치 초기 화 항목
    
    yarn global add @vue/cli
    step 2 서버 파일 추가
    웹 서비스 아래 코드 를 시작 하 는 중http://localhost:9000은 우리 가 최종 적 으로 주 소 를 방문 하 는 것 입 니 다.
    
    const Koa = require('koa')
    const path = require('path')
    
    const resolve = file => path.resolve(__dirname, file)
    const app = new Koa()
    const router = require('./router')
    const port = 9000
    app.listen(port, () => {
     console.log(`server started at localhost:${port}`)
    })
    module.exports = app
    여 기 는 서 비 스 를 시 작 했 을 뿐 입 니 다.서버 와 클 라 이언 트 를 파일 로 읽 어야 합 니 다.아래 코드 는 서버 렌 더 링 의 관건 적 인 절차 입 니 다.
    
    const fs = require('fs')
    const path = require('path')
    const send = require('koa-send')
    const Router = require('koa-router')
    const router = new Router()
    //            
    const resolve = file => path.resolve(__dirname, file)
    const { createBundleRenderer } = require('vue-server-renderer')
    const bundle = require('../dist/vue-ssr-server-bundle.json')
    const clientManifest = require('../dist/vue-ssr-client-manifest.json')
    //      BunleRender      renderer.renderToString   bundle       
    const renderer = createBundleRenderer(bundle, {
     runInNewContext: false,
     template: fs.readFileSync(resolve('../src/index.temp.html'), 'utf-8'),
     clientManifest: clientManifest
    })
    
    const handleRequest = async ctx => {
     ctx.res.setHeader('Content-Type', 'text/html')
     //   2.5.0+    ,  callback         。     callback  ,        Promise   ,   resolve          HTML。
     ctx.body = await renderer.renderToString(Object.assign({}, ctx.state.deliver, { url }))
    }
    router.get('/home',handleRequest)
    module.exports = router
    vue-server-rendercreateBundleRenderer 라 는 API 사용 방법 은 다음 과 같다.
    
    const { createBundleRenderer } = require('vue-server-renderer')
    
    const renderer = createBundleRenderer(serverBundle, {
     runInNewContext: false, //   
     template, // (  )    
     clientManifest // (  )      manifest
    })
    위의 createBundleRenderer 방법 을 통 해 render 대상 을 생산 하고 최종 적 으로 bunlde 를 문자열 로 렌 더 링 하여 최종 html 를 클 라 이언 트 에 되 돌려 줍 니 다.
    
    bundleRenderer.renderToString([context, callback]): ?Promise<string>
    step 3 entry-client.js,entry-server.js 입구 파일 추가
    src 에서 이 두 개의 입구 파일 을 제외 하고 다른 파일 은 모두 클 라 이언 트 와 서버 에서 공용 합 니 다.이 두 입구 문서 에서 각각 무엇 을 했 는 지 살 펴 보 자.
    대체 적 인 절 차 는 서버 에서 vue 인 스 턴 스 를 만 들 고 페이지 의 비동기 요청 데 이 터 를 용기 에 저장 하 는 것 입 니 다.>클 라 이언 트 가 서버 에서 보 낸 html 를 받 아 활성화 모드 로 마 운 트 하고 루트 요소\#app 에 자동 으로 추가data-server-rendered="true"특수 속성 입 니 다.
    main.js
    
    import Vue from 'vue'
    import App from './App.vue'
    ...
    export function createApp() {
     // ...
     const app = new Vue({
     router,
     store,
     render: h => h(App)
     })
     return { app, router, store }
    }
    entry-server.js
    
    import { createApp } from './main.js'
    export default context => {
     //                   ,          Promise,
     //                   ,
     //        。
     return new Promise((resolve, reject) => {
     const { app, router, store } = createApp()
     //        router    
     router.push(context.url)
    
     //    router                 
     router.onReady(() => {
      const matchedComponents = router.getMatchedComponents()
    
      //        ,   reject   ,    404
      if (!matchedComponents.length) {
      return reject({ code: 404 })
      }
      Promise.all(
      matchedComponents.map(component => {
       if (component.asyncData) {
       return component.asyncData({
        store,
        context,
        route: router.currentRoute
       })
       }
      })
      ).then(() => {
      //        (preFetch hook) resolve  ,
      //     store                   。
      //             ,
      //    `template`      renderer  ,
      //           `window.__INITIAL_STATE__`,    HTML。
      //                        
      context.state = store.state
      resolve(app)
      }).catch(reject)
     }, reject)
     })
    }
    entry-client.js
    
    import { createApp } from './main'
    const { app, router, store } = createApp()
    
    if (window.__INITIAL_STATE__) {
     store.replaceState(window.__INITIAL_STATE__)
    }
    
    router.onReady(() => {
     router.beforeResolve((to, from, next) => {
     const matched = router.getMatchedComponents(to)
     const prevMatched = router.getMatchedComponents(from)
     let diffed = false
     const activated = matched.filter((c, i) => {
      return diffed || (diffed = prevMatched[i] !== c)
     })
    
     if (!activated.length) {
      return next()
     }
    
     Promise.all(
      activated.map(component => {
      if (component.asyncData) {
       component.asyncData({
       store,
       route: to
       })
      }
      })
     )
      .then(() => {
      next()
      })
      .catch(next)
     })
     app.$mount('#app')
    })
    마지막.
    전체 코드 참조github 주소
    참고 로 이 그림 도 붙 여 주세요.
     
    vue ssr+koa 2 구축 서버 렌 더 링 에 관 한 예제 코드 에 관 한 이 글 은 여기까지 소개 되 었 습 니 다.더 많은 vue ssr koa 2 서버 렌 더 링 내용 은 우리 의 이전 글 을 검색 하거나 아래 의 관련 글 을 계속 조회 하 시기 바 랍 니 다.앞으로 많은 지원 바 랍 니 다!

    좋은 웹페이지 즐겨찾기