深刻NUXT,看看一條命令行的背後到底發生了什麼

寫於 2017.01.13html

1、介紹

Nuxt.js - Universal Vue.js Applicationsvue

隨着react社區的next.js框架的發佈,vue社區也終於誕生了屬於本身的先後端同構框架nuxt.js。在進一步的接觸與使用中,發現nuxt.js確實極大地方便了vue項目的開發,其背後的邏輯也值得咱們玩味。關於nuxt的具體的用法請查閱官方文檔,本文就不一一贅述了。react

本文主要研究nuxt的運行原理,分析它從接收一條nuxt指令,到完成指令背後所發生的一系列事情。webpack

在開始本文以前,請讀者務必親自體驗過nuxt.js的使用,而且具有必定的vue.js相關開發經驗。web

2、NUXT指令

經過查看nuxt.js工程目錄下的package.json文件,咱們能夠看到下列幾條指令:json

"scripts": {
  "dev": "nuxt",
  "build": "nuxt build",
  "start": "nuxt start",
  "generate": "nuxt generate"
}
複製代碼

結合官網的介紹,咱們能夠知道不一樣的指令對應着不一樣的功能:後端

指令 描述
nuxt 開啓一個監聽3000端口的服務器,同時提供hot-reloading功能
nuxt build 構建整個應用,壓縮合並JS和CSS文件(用於生產環境)
nuxt start 開啓一個生產模式的服務器(必須先運行nuxt build命令)
nuxt generate 構建整個應用,併爲每個路由生成一個靜態頁面(用於靜態服務器)

以上幾條指令,也就是本文將要分析的重點:究竟這些指令的背後,nuxt都作了一些什麼樣的工做呢?api

3、執行指令

打開nuxt.js的工程目錄,進入到到bin目錄,咱們能夠看到5個文件:bash

|__ nuxt
  |__ nuxt-build
  |__ nuxt-dev
  |__ nuxt-generate
  |__ nuxt-start
複製代碼

每一個文件對應着不一樣的指令。下面咱們經過一張圖來分析每一條指令的執行過程:服務器

從上圖可知,每一條指令基本都是作了這麼幾件事情:

  1. 讀取nuxt.config.js文件的配置;
  2. 實例化Nuxt()類,並把上一步讀取到的配置覆蓋Nuxt()類的默認配置;
  3. 執行各自具體的方法函數。

對應代碼以下(節選):

var nuxtConfigFile = resolve(rootDir, 'nuxt.config.js')

var options = {}
if (fs.existsSync(nuxtConfigFile)) {
  options = require(nuxtConfigFile)
}
if (typeof options.rootDir !== 'string') {
  options.rootDir = rootDir
}

var nuxt = new Nuxt(options)
nuxt.build()
複製代碼

第一步讀取配置以及配置的內容能夠查看官網說明,下面咱們將會對第二步和第三步進行深刻探討。

4、Nuxt()

進入到nuxt/lib目錄,咱們能夠看到以下的文件目錄結構:

|__ app
  |__ build
    |__ index.js
    |__ webpack
  |__ generate.js
  |__ nuxt.js
  |__ render.js
  |__ server.js
  |__ utils.js
  |__ views

複製代碼

目錄當中的nuxt.js文件,就是咱們要實例化的Nuxt()類的所在,讓咱們來看看它都包含一些什麼內容,以及各自都有些什麼做用:

上圖中每一步均可以在具體的代碼中自行瀏覽。在用戶輸入指令並實例化了Nuxt()類之後,實例化出來的nuxt對象就會執行圖中打了綠色對勾的幾個方法:build(), render(), renderRoute(), renderAndGetWindow()以及generate()方法。

同時,Nuxt()類也提供了一個close()公有方法,用於關閉其所開啓的服務器。

5、build()方法

build()方法對應着nuxt/lib/build/index.js文件,其基本構成以下:

簡單來講,build()方法在判斷完運行條件後,會先初始化產出目錄.nuxt,而後經過不一樣目錄下的文件結構來生成一系列的配置,寫入模板文件後輸出到.nuxt目錄。接下來,則會根據不一樣的開發環境來調用不一樣的webpack配置,運行不一樣的webpack構建方案。

6、render.js文件

nuxt/lib目錄下找到render.js文件,它包含着咱們即將要分析的三個方法:render(), renderRoute(), renderAndGetWindow()

經過這張圖片,咱們能夠知道nuxt對於處理「客戶端渲染」與「服務端渲染」的邏輯實際上是很是清晰的。

首先,在render()方法在處理完一系列的路徑問題後,會調用renderRoute()方法,獲取響應所需內容並完成響應。

其中renderRoute()方法會判斷當前響應是否應執行服務端渲染。若是是,則調用vue提供的bundleRenderer()方法,把html內容渲染完畢之後再總體輸出;若是不是,則直接輸出一個<div id="__nuxt"></div>字符串,交由客戶端渲染。

最後,經過renderAndGetWindow()來檢查輸出的html是否存在問題,而後發出通知,代表html可用。

7、generate.js文件

最後咱們來分析一下generate.js文件。咱們知道nuxt generate指令會爲page目錄下的每個頁面文件單獨生成一個html靜態頁面,功能很是貼心。那麼generate.js究竟是怎麼工做的呢?

在執行nuxt generate時,它會先執行前文已經分析過的build()方法,產出編譯後的文件;而後會初始化dist目錄,調用resolveRouteParams()方法,讀取產出後的路由配置並整理。而後經過fs.writeFile()等API,把內容挨個寫入文件並輸出,最後再統計總的generate()運行時間。

8、寫在最後

Nuxt是一個新誕生的項目,官網文檔也還沒有所有完成。從一個使用者的角度來講,這是一個很是有意思的項目,VueJS的做者尤大也曾褒獎過這個項目,在VueJS的官網也專門爲其進行推薦。

如此interesting的項目實在很值得深刻研究,做者的代碼和註釋也很是清晰詳細。本文受限於我的水平,在分析理解上不免有出錯的地方,歡迎各位讀者指正!

相關文章
相關標籤/搜索