写于 2017.01.13html
随着react
社区的next.js
框架的发布,vue
社区也终于诞生了属于本身的先后端同构框架nuxt.js
。在进一步的接触与使用中,发现nuxt.js
确实极大地方便了vue
项目的开发,其背后的逻辑也值得咱们玩味。关于nuxt
的具体的用法请查阅官方文档,本文就不一一赘述了。react
本文主要研究nuxt
的运行原理,分析它从接收一条nuxt
指令,到完成指令背后所发生的一系列事情。webpack
在开始本文以前,请读者务必亲自体验过nuxt.js
的使用,而且具有必定的vue.js
相关开发经验。web
经过查看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
打开nuxt.js
的工程目录,进入到到bin
目录,咱们能够看到5个文件:bash
|__ nuxt
|__ nuxt-build
|__ nuxt-dev
|__ nuxt-generate
|__ nuxt-start
复制代码
每一个文件对应着不一样的指令。下面咱们经过一张图来分析每一条指令的执行过程:服务器
从上图可知,每一条指令基本都是作了这么几件事情:
nuxt.config.js
文件的配置;Nuxt()
类,并把上一步读取到的配置覆盖Nuxt()
类的默认配置;对应代码以下(节选):
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()
复制代码
第一步读取配置以及配置的内容能够查看官网说明,下面咱们将会对第二步和第三步进行深刻探讨。
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()
公有方法,用于关闭其所开启的服务器。
build()
方法build()
方法对应着nuxt/lib/build/index.js
文件,其基本构成以下:
简单来讲,build()
方法在判断完运行条件后,会先初始化产出目录.nuxt
,而后经过不一样目录下的文件结构来生成一系列的配置,写入模板文件后输出到.nuxt
目录。接下来,则会根据不一样的开发环境来调用不一样的webpack配置,运行不一样的webpack构建方案。
render.js
文件在nuxt/lib
目录下找到render.js
文件,它包含着咱们即将要分析的三个方法:render()
, renderRoute()
, renderAndGetWindow()
。
经过这张图片,咱们能够知道nuxt
对于处理“客户端渲染”与“服务端渲染”的逻辑实际上是很是清晰的。
首先,在render()
方法在处理完一系列的路径问题后,会调用renderRoute()
方法,获取响应所需内容并完成响应。
其中renderRoute()
方法会判断当前响应是否应执行服务端渲染。若是是,则调用vue
提供的bundleRenderer()
方法,把html内容渲染完毕之后再总体输出;若是不是,则直接输出一个<div id="__nuxt"></div>
字符串,交由客户端渲染。
最后,经过renderAndGetWindow()
来检查输出的html是否存在问题,而后发出通知,代表html可用。
generate.js
文件最后咱们来分析一下generate.js
文件。咱们知道nuxt generate
指令会为page
目录下的每个页面文件单独生成一个html静态页面,功能很是贴心。那么generate.js
究竟是怎么工做的呢?
在执行nuxt generate
时,它会先执行前文已经分析过的build()
方法,产出编译后的文件;而后会初始化dist
目录,调用resolveRouteParams()
方法,读取产出后的路由配置并整理。而后经过fs.writeFile()
等API,把内容挨个写入文件并输出,最后再统计总的generate()
运行时间。
Nuxt
是一个新诞生的项目,官网文档也还没有所有完成。从一个使用者的角度来讲,这是一个很是有意思的项目,VueJS
的做者尤大也曾褒奖过这个项目,在VueJS的官网也专门为其进行推荐。
如此interesting的项目实在很值得深刻研究,做者的代码和注释也很是清晰详细。本文受限于我的水平,在分析理解上不免有出错的地方,欢迎各位读者指正!