從0帶您打造企業級 Vue 服務器渲染 Nuxt.js (一) 入門

寫在開始前

公司團隊技術棧一直主要使用 Vue,因爲 SPA 模式開發有幾大痛點,團隊在2017年開始嘗試 SSR(服務端渲染)。 記得剛開始 Nuxt.js 尚未到1.0(坑哭了),到目前爲止團隊已經經歷了4個 Nuxt.js 項目,版本也從0.xx 一直到如今的 2.xx,我會把這期間遇到的問題和經驗總結給你們,但願在使用 Nuxt.js 少跳些坑。javascript

我能學到些什麼

  • Nuxt 入門(普及些基礎的知識,項目搭建)
  • Nuxt 性能提高(如何經過內網請求讓你的api加快請求速度)
  • Nuxt 常見的問題和解決方案
  • Nuxt 線上部署

正文

SSR 的不少概念性的問題建議移步官方文檔本文不作詳細介紹。css

1.爲何服務端渲染能解決 SEO 和首屏渲染

首先不論是Vue React Angular 等單頁面應用渲染是從服務器獲取所需Js,在客戶端將其解析生成 HTML, 這樣會帶來幾個問題。html

  • 首屏先去服務器請求完成 Js 而後再由 Js 生成 HTML 元素,這會致使網站首屏加載緩慢,不利於用戶體驗。
  • 頁面的 HTML 元素都是由後期的 Js 動態生成,搜索引擎沒法爬取(谷歌目前已經能夠爬取SPA頁面,因爲咱們在天朝,你懂得)

2.爲何採用 Nuxt.js

首先使用 SSR 開發成本對純前端來講仍是比較高的,須要瞭解 SSR 渲染原理,有基礎的 Node 知識。前端

還有一些生命週期,中間件須要本身去處理,Webpack, 這些搭建完成就會擋住大部分人。vue

Nuxt.js 提供了基礎的 Webpack 和 Node 的封裝,不須要咱們再去搭建繁瑣的 SSR 程序, 只需經過特定的文件結構和 Nuxt.js 提供的 Api 便可快速搭建一個 SSR 程序,詳細能夠異步官方文檔java

搭建一個 Nuxt.js 項目

Nuxt.js 2.0 之後提供了腳手架 create-nuxt-appnode

確保安裝了npx(npx在NPM版本5.2.0默認安裝了):webpack

$ npx create-nuxt-app <項目名>
複製代碼

或者用yarn :web

yarn create nuxt-app <項目名>
複製代碼

完成後腳手架會讓你進行一些自定義的選擇。npm

1.在集成的服務器端框架之間進行選擇:

Nuxt.js 2.0 之前腳手架默認是不把 Node 服務器暴露出來的,只提供默認渲染服務器,當初咱們用 Koa 分離出來還花費了一些時間,如今官方已經吧服務端框架直接在腳手架中讓用戶自由選擇了(感謝)。

若是是初學建議你選擇 None (Nuxt 默認服務器)框架不會暴露服務端代碼到你目錄,這樣有個缺點,之後作些自定義的事情時候不是很方便。

咱們團隊成員基本都會使用 Egg 因此果斷選擇了 Koa 來建立項目,也建議您選擇一個服務端框架進行初始化,後續本文會介紹一些針對 SSR 下內網請求加速,SSR 下使用中間層加速頁面接口請求速度。

當運行完時,它將安裝全部依賴項,如今啓動項目愉快的玩耍吧:

$ npm run dev || yarn dev
// 應用如今運行在 http://localhost:3000 上運行。
複製代碼

Nuxt.js 流程圖

下圖闡述了 Nuxt.js 應用一個完整的服務器請求到渲染(或用戶經過 切換路由渲染頁面)的流程:

Nuxt.js 目錄結構

裏面基本的目錄官方都有詳細介紹官方文檔,能夠看見咱們用了 Koa 初始化項目後會多一個 Server 目錄 這個文件裏面的 index.js 就是服務端框架的代碼,若是對 Koa 不熟或者 Node 不熟能夠先去官方充充電,入門仍是比較簡單的。

開始配置咱們的項目

因爲咱們主要採用手機頁面因此會配置自適應和一些便於開發的配置

配置nuxt.config.js

配置postcss
postcss: [
      require('postcss-import')({}),
      require('postcss-url')({}),
      require('postcss-preset-env')({
        browsers: 'last 2 versions'
      }),
      require('postcss-aspect-ratio-mini')({}),
      require('postcss-px-to-viewport')({
        viewportWidth: 375,
        viewportHeight: 667,
        unitPrecision: 3,
        viewportUnit: 'vw',
        selectorBlackList: ['.ignore', '.hairlines'],
        minPixelValue: 1,
        mediaQuery: false
      }),
      require('postcss-viewport-units')({
        filterRule: rule =>
          rule.selector.indexOf('::after') === -1 &&
          rule.selector.indexOf('::before') === -1 &&
          rule.selector.indexOf(':after') === -1 &&
          rule.selector.indexOf(':before') === -1
      })
    ]
複製代碼

之前咱們適配各類手機主要是採用rem方案

如今瀏覽器對 vw 單位支持的愈來愈好,下面也給你們介紹一下在 Nuxt.js 中採用 vw

postcss-import:主要功有是解決@import引入路徑問題。使用這個插件,可讓你很輕易的使用本地文件、node_modules或者web_modules的文件。這個插件配合postcss-url讓你引入文件變得更輕鬆。

postcss-url:該插件主要用來處理文件,好比圖片文件、字體文件等引用路徑的處理。

postcss-preset-env:用來自動處理瀏覽器前綴的一個插件。你也能夠像這樣來指定last 2 versions 或者 > 5%

postcss-aspect-ratio-mini:主要用來處理元素容器寬高比。在實際使用的時候,具備一個默認的結構

postcss-px-to-viewport:主要把px單位轉換爲vw、vh、vmin或者vmax這樣的視窗單位,也是vw適配方案的核心插件之一。在配置中須要配置相關的幾個關鍵參數:

viewportWidth: 375,// 視窗的寬度,對應的是咱們設計稿的寬度,通常是750 (若是咱們設置的寬度是300px,那麼編譯以後的寬度爲(300/750*100)=40vw,若是頻寬實際爲375px,那麼該元素的寬度爲(375*0.4)= 150px)
viewportHeight: 667,// 視窗的高度
unitPrecision: 3,// 指定`px`轉換爲視窗單位值的小數位數(不少時候沒法整除)
viewportUnit: 'vw',// 指定須要轉換成的視窗單位,建議使用vw
selectorBlackList: ['.ignore', '.hairlines'],// 指定不轉換爲視窗單位的類,能夠自定義,能夠無限添加,建議定義一至兩個通用的類名
minPixelValue: 1,// 小於或等於`1px`不轉換爲視窗單位,你也能夠設置爲你想要的值
mediaQuery: false// 容許在媒體查詢中轉換`px`
複製代碼

postcss-viewport-units:插件主要是給CSS的屬性添加 content 的屬性,配合 viewport-units-buggyfill 庫給 vw 、 vh 、 vmin 和 vmax 作適配的操做。

這是實現 vw 佈局必不可少的一個插件,由於少了這個插件,這將是一件痛苦的事情。後面你就清楚。

如今 PostCSS 主要配置以及完成了,根據我的須要作刪減。

配置環境變量來實現自動編譯不一樣環境代碼

首先去 babel plugins 配置一個插件

// 首先導入 webpack
const webpack = require('webpack')

plugins: [
  new webpack.DefinePlugin({
    // 接收環境變量並注入
    'process.env': JSON.stringify({
      NODE_EVENT: `${process.env.NODE_EVENT}`
    })
  })
],
複製代碼

而後咱們去package.json 配置 local qa pre prd 等幾個環境

"dev": "cross-env NODE_EVENT=local NODE_ENV=development nodemon server/index.js --watch server",
"qa": "cross-env NODE_EVENT=qa nuxt build",
"pre": "cross-env NODE_EVENT=pre nuxt build",
"prd": "cross-env NODE_EVENT=prd nuxt build",
複製代碼

接着去新增個config/index.js的配置文件

let starBaseUrl = ''

const NODE_EVENT = process.env.NODE_EVENT

if (NODE_EVENT == 'local') {
  // 本地開發環境
  starBaseUrl = 'http://xx.cn'
} else if (NODE_EVENT == 'qa') {
  // 測試
  starBaseUrl = 'http://xx.cn'

} else if (NODE_EVENT == 'testprod') {
  // 預生產
  starBaseUrl = 'http://xx.cn'
} else if (NODE_EVENT == 'prod') {
  // 生產
  starBaseUrl = 'http://xx.cn'
}

module.exports = {
  starBaseUrl
}
複製代碼

如今咱們在生產時候就能編譯出不一樣環境的代碼,避免收到修改致使的失誤。

盡請期待下一章

相關文章
相關標籤/搜索