亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

vuecli項目實現構建SSR服務端渲染

發布時間:2020-11-02 16:05:12 來源:億速云 閱讀:193 作者:Leah 欄目:開發技術

vuecli項目實現構建SSR服務端渲染?針對這個問題,這篇文章詳細介紹了相對應的分析和解答,希望可以幫助更多想解決這個問題的小伙伴找到更簡單易行的方法。

服務端渲染(SSR)

將一個 Vue 組件在服務端渲染成 HTML 字符串并發送到瀏覽器,最后將這些靜態標記“激活”為可交互應用程序的過程就叫服務端渲染(SSR)

服務器渲染的 Vue.js 應用程序也可以被認為是"同構"或"通用",因為應用程序的大部分代碼都可以在服務器和客戶端上運行

為什么使用 服務端渲染(SSR)

  • 更好的 SEO:傳統的 spa 頁面數據都是異步加載,搜索引擎爬蟲無法抓取,服務端渲染(SSR)使搜索引擎爬蟲抓取工具可以直接查看完全渲染的頁面,解決 vue 項目的 seo 問題
  • 更快的內容到達時間 (首屏加載更快):請求頁面時,服務端將渲染好的頁面直接發送給瀏覽器進行渲染,瀏覽器只需要解析渲染 HTML,無需等待所有的 JavaScript 都完成下載并執行,才顯示服務器渲染的標記

服務端渲染(SSR)缺點

  • 開發條件所限:瀏覽器特定的代碼,只能在某些生命周期鉤子函數中使用;一些外部擴展庫可能需要特殊處理,才能在服務器渲染應用程序中運行
  • 涉及構建設置和部署的更多要求:與可以部署在任何靜態文件服務器上的完全靜態單頁面應用程序 (SPA) 不同,服務器渲染應用程序,需要處于 Node.js server 運行環境
  • 更多的服務器端負載:在 Node.js 中渲染完整的應用程序,顯然會比僅僅提供靜態文件的 server 更加大量占用 CPU 資源,因此如果你預料在高流量環境下使用,需要準備相應的服務器負載,并采用緩存策略
     

服務端渲染(SSR)vs 預渲染(Prerendering)

如果你只是想改善少數營銷頁面(例如 /, /about, /contact 等)的 SEO,那么你可能需要預渲染,無需使用 web 服務器實時動態編譯 HTML,而是使用預渲染方式,在構建時簡單地生成針對特定路由的靜態 HTML 文件,優點是設置預渲染更簡單,并可以將你的前端作為一個完全靜態的站點
如果你使用 webpack,你可以使用 prerender-spa-plugin (npm地址) 插件輕松地添加預渲染

服務端渲染(SSR)原理

構建流程:所有的文件擁有一個公共入口 app.js,進入服務端入口 entry-server.js 和客戶端入口 entry-client.js ,項目完成后通過使用 webpack 打包生成服務端 server bundle(一個供服務端 SSR 使用的 json 文件)和客戶端 client bundle(用于瀏覽器),當請求頁面時,服務端將 vue 組件組裝成 HTML 字符串發送到瀏覽器,混入到客戶端訪問的 HTML 模板中,完成頁面渲染

vuecli項目實現構建SSR服務端渲染

通過 vuecli 創建 vue 項目

vue create vue-ssr-demo

vue-server-renderer

vue-server-renderer 是 SSR 渲染的核心,提供 createRenderer 方法,這個方法的 renderToString 可以把 app 渲染成字符串。createBundleRenderer 方法可以通過預打包應用程序代碼創建 bundleRenderer 實例,來渲染 bundle 和 HTML 模板

安裝 vue-server-renderer

npm install vue-server-renderer --save

注意:

  • vue-server-renderer 和 vue 必須匹配版本
  • vue-server-renderer 依賴一些 Node.js 原生模塊,因此只能在 Node.js 中使用

 避免狀態單例

Node.js 服務器是一個長期運行的進程,當我們的代碼進入該進程時,它將進行一次取值并留存在內存中,這意味著如果創建一個單例對象,它將在每個傳入的請求之間共享,所以我們應該暴露一個可以重復執行的工廠函數,為每個請求創建一個新的根 Vue 實例,如果我們在多個請求之間使用一個共享的實例,很容易導致交叉請求狀態污染(同樣的規則也適用于 router、store 和 event bus 實例)

創建 路由 router

安裝 vue-router

npm install vue-router --save

src 目錄下創建 router 文件夾和 index.js
在 components 目錄下創建 Home.vue 和 About.vue 頁面(根據項目需求自定義創建)

router/index.js:

import Vue from "vue"
import Router from "vue-router"

import Home from "@/components/Home"
import About from "@/components/About"

Vue.use(Router)

//每次用戶請求都需要創建一個新的router實例
//創建createRouter工廠函數
export default function createRouter() {
  //創建router實例
  return new Router({
    mode: "history",
    routes: [
      {
        path: "/", 
        name: 'home',
        component: Home
      },
      {
        path: "/about", 
        name: 'about',
        component: About
      }
    ]
  })
}

修改 App.vue

修改 App.vue 頁面,進行頁面布局(根據項目需求自定義布局)

App.vue:

<template>
 <div id="app">
  <nav>
   <router-link to="/">首頁</router-link>
   <router-link to="/about">關于</router-link>
  </nav>
  <router-view></router-view>
 </div>
</template>

創建 公共入口 app.js

src 目錄下創建 公共入口 app.js ,用于創建 vue 實例

app.js:

import Vue from "vue"
import App from "./App.vue"
import createRouter from "./router"

//創建createApp工廠函數
export default function createApp() {
  const router = createRouter()
  //創建vue實例
  const app = new Vue({
    router,
    render: h => h(App),
  })
  return { app, router }
}

創建 服務端入口 entry-server.js

src 目錄下創建 服務端入口 entry-server.js ,用于渲染首屏

entry-server.js:

import createApp from "./app"

export default context => {
  return new Promise((resolve, reject) => {
    const { app, router } = createApp()
    //渲染首屏
    router.push(context.url)
    router.onReady(() => {
      resolve(app)
    }, reject)
  })
}

創建 客戶端入口 entry-client.js

src 目錄下創建 客戶端入口 entry-client.js ,用于掛載激活 app

entry-client.js:

import createApp from "./app"

const { app, router } = createApp()
router.onReady(() => {
  //掛載激活app
  app.$mount("#app")
})

創建 頁面模板 index.temp.html

public 目錄下創建 index.temp.html ,作為渲染 Vue 應用程序時,renderer 生成 HTML 頁面包裹容器,來包裹生成的 HTML 標記
<!--vue-ssr-outlet--> 注釋將是應用程序 HTML 標記注入的地方

index.temp.html:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>vue ssr</title>
</head>
<body>
  <!--vue-ssr-outlet-->
</body>
</html>

創建 Node.js 服務器

服務端渲染(SSR)需要使用 Node.js 服務器,這里使用 express 框架搭建
安裝 express

npm install express --save

根目錄下創建 server.js 文件,用于搭建 Node.js 服務器

server.js:

//nodejs服務器
const express = require("express")
const Vue = require("vue")
const fs = require("fs")

//創建express實例
const app = express()
//創建渲染器
const { createBundleRenderer } = require("vue-server-renderer")
const serverBundle = require("./dist/server/vue-ssr-server-bundle.json")
const clientManifest = require("./dist/client/vue-ssr-client-manifest.json")
const renderer = createBundleRenderer(serverBundle, {
  runInNewContext: false,
  template: fs.readFileSync("./public/index.temp.html", "utf-8"), //頁面模板
  clientManifest
})

//中間件處理靜態文件請求
app.use(express.static("./dist/client", {index: false}))

//將路由的處理交給vue
app.get("*", async (req, res) => {
  try {
    const context = {
      url: req.url,
      title: ""
    }
    const html = await renderer.renderToString(context)
    res.send(html)
  }catch {
    res.status(500).send("服務器內部錯誤!")
  }
})

app.listen(9999, () => {
  console.log("服務器渲染成功!")
})

webpack 打包配置

根目錄下創建 vue 配置文件 vue.config.js 進行 webpack 配置,該配置會覆蓋 vue-cli 中 webpack 的默認配置

vue.config.js:

const VueSSRServerPlugin = require("vue-server-renderer/server-plugin")
const VueSSRClientPlugin = require("vue-server-renderer/client-plugin")

//環境變量,決定入口是客戶端還是服務端
const TARGRT_NODE = process.env.WEBPACK_TARGET === "node"
const target = TARGRT_NODE &#63; "server" : "client"

module.exports = {
  css: {
    extract: false
  },
  outputDir: "./dist/" + target,
  configureWebpack: () => ({
    //將 entry 指向應用程序的 server entry 文件
    entry: `./src/entry-${target}.js`,
    //對 bundle renderer 提供 source map 支持
    devtool: "source-map",
    //這允許 webpack 以 Node 適用方式(Node-appropriate fashion)處理動態導入(dynamic import)
    //并且還會在編譯 Vue 組件時,告知 `vue-loader` 輸送面向服務器代碼(server-oriented code)
    target: TARGRT_NODE &#63; "node" : "web",
    node: TARGRT_NODE &#63; undefined : false,
    output: {
      //此處告知 server bundle 使用 Node 風格導出模塊(Node-style exports)
      libraryTarget: TARGRT_NODE &#63; "commonjs2" : undefined
    },
    optimization: { splitChunks: TARGRT_NODE &#63; false : undefined },
    //將服務器的整個輸出構建為單個 JOSN 文件的插件
    //服務端默認文件名為 vue-ssr-server-bundle.json
    plugins: [TARGRT_NODE &#63; new VueSSRServerPlugin() : new VueSSRClientPlugin()]
  })
}

打包腳本配置

cross-env 插件:運行跨平臺設置和使用環境變量的腳本
安裝 cross-env 插件

npm install cross-env --save

package.json 文件中定義項目運行打包腳本

package.json:

{
	......
	"scripts": {
		"server": "node server",
	  "build:client": "vue-cli-service build",
	  "build:server": "cross-env WEBPACK_TARGET=node vue-cli-service build --mode server",
	  "build": "npm run build:server && npm run build:client"
	},
	......
}

終端執行命令打包項目:

npm run build

打包完成后,終端執行命令啟動 Node.js 服務器

npm run server

服務器啟動后,瀏覽器打開 localhost:9999 即可訪問 SSR 項目
查看網頁源代碼發現根元素上添加了一個特殊的屬性:data-server-rendered,該屬性讓客戶端 Vue 知道這部分 HTML 是由 Vue 在服務端渲染的,并且應該以激活模式進行掛載

<div id="app" data-server-rendered="true">......</div>

vuecli項目實現構建SSR服務端渲染

項目目錄:

vuecli項目實現構建SSR服務端渲染

打包后 dist 目錄:

vuecli項目實現構建SSR服務端渲染

關于vuecli項目實現構建SSR服務端渲染問題的解答就分享到這里了,希望以上內容可以對大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關注億速云行業資訊頻道了解更多相關知識。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

仁化县| 岳阳市| 绥宁县| 萨嘎县| 凤台县| 富顺县| 东莞市| 德兴市| 将乐县| 乌鲁木齐县| 秦安县| 全州县| 大石桥市| 大安市| 安远县| 河北省| 博白县| 九龙城区| 新昌县| 南华县| 大同县| 铜山县| 林州市| 东方市| 永靖县| 双柏县| 双流县| 寻乌县| 苍山县| 江阴市| 页游| 大埔区| 若羌县| 东乌珠穆沁旗| 栖霞市| 新沂市| 内江市| 永春县| 荆州市| 饶阳县| 盐源县|