基于vue的服务端渲染框架Nuxt介绍与实践
Nuxt是什么
Nuxt.js 是一个基于 Vue.js 的通用应用框架,通过对客户端/服务端基础架构的抽象组织。
2016年10月发布,运行环境基于vue+webpack+babel,
预置了使用vue开发服务端渲染应用所需的基础配置,
并且集成了vue-router、vuex、vue-meta等vue生太圈常用的组件和框架,
使用webpack、vue-loader、babel-loader来处理自动化构建工作。
Nuxt用来做什么
vue框架由于是单页面SPA应用,故存在SEO、首屏渲染、路由切换时渲染慢,用户体验略差等问题。
所以基于vue的服务端渲染方案应运而生。
框架特性
基于vue.js,学习成本低
内置代码分层
服务端渲染
本地开发热更新
SEO及mete头标签管理
nuxt官网
开发过程及配置
1.安装
配置好node环境和npm以后,通过vue init nuxt/express **脚手架工具生成默认文件。
npm i && npm run dev后打开localhost:3000可看到官方提供的示例。
2 目录介绍
目前所用为1.4版本,所生成的目录如下:
- pages:页面组件,Nuxt会根据结构生成对应的路由
- componets:公共组件
- layouts:宿主页面模板组件,可以让不同的页面使用不同的布局
- assets: 用于webpack打包的静态资源
- middleware:中间件,首屏加载和路由跳转前均会执行对应中间件,可以全局配置,也可以部分组件配置
- plugins:插件,SPA中常用的三方组件(如axios、utils),或者引入自己编写的三方库
- store:内置了vuex,在store目录下增加index.js,返回一个Vue.Store实例即可
3 配置
nuxt.config示例
nuxt以约束文件和nuxt.config.js的方式管理程序和组件之间的关系
nuxt.config.js对应用的扩展主要如下:
- build:webpack配置,可以对默认的webpack配置进行扩展
- cahe:配置组件缓存
- css:全局css样式
- dev or env:自定义环境变量,对应webpack.config.js中的变量
- head:vue-mete配置,在nuxt.config.js中会应用于全局,在组件中调用则只会应用于组件
- loading:nuxt内置的进度条组件,可自定义或引用三方组件
- performance: nodejs服务器性能配置
plugins: 划重点,经常用,并且很重要。
plugins会在Nuxt.js 应用实例生成之前加载,如 axios、filter。
支持数组或者对象,ssr属性默认为ture。
但是有部分组件依赖window或者docuemnt对象,须设置为false,即不打包到服务端
脚本中,例如loadsh,依赖window对象,需如下配置plugins: [ {src: '~plugins/lodash.js', ssr: false} ],
常用API
1.asyncData
页面组件加载前调用,可获取当前上下文对象,异步请求的数据会返回给当前组件的data。
注意:此时vue实例还未生成,拿不到this。
2.middleware
中间件,每次路由切换时调用,例如做登录判断
export default function ({ store, redirect }) { // If the user is not authenticated if (!store.state.authenticated) { return redirect('/login') } }
3.head
修改title和Meta标签
4.vendor
nuxt.config.js的vendor属性,可避免重复打包
开发中常见问题
1.资源引用
全局资源文件在nuxt.config.js中配置
module.exports = { head: { script: [ { src: ' https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js' } ], link: [ { rel: 'stylesheet', href: 'https://fonts.googleapis.com/css? family=Roboto' } ] } }
局部配置 ``` <script> export default { head: { script: [ { src:'https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js' } ], link: [ { rel: 'stylesheet', href: 'https://fonts.googleapis.com/css?family=Roboto' } ] } } </script> ```
2.webpack配置扩展
module.exports = { build: { extend (config, { isDev, isClient }) { // ... } } }
3.window/Document未定义
只兼容客户端的组件被打包进了服务端脚本中,单独抽出后,放后plugins中,配置时设置ssr为false。组件内引用时,通过process.BROWSER_BUILD判断导入
if (process.BROWSER_BUILD) { require('external_library') }
4.UI组件选择
目前支持服务端渲染的UI组件不是很多,已尝试过的有PC端element-ui,移动端vux,
详细配置见vux-plugins
和同目录下的vux-components.js
使用element-ui
vender:[ 'element-ui' ], babel:{ "plugins": [["component", [ { "libraryName": "element-ui", "styleLibraryName": "theme-default" }, 'transform-async-to-generator', 'transform-runtime' ]]], comments: true }, plugins: [ { src: '~plugins/element-ui', ssr: true } ], css: [ ] ~plugins/element-ui.js import Vue from 'vue' import { Button } from 'element-ui' Vue.component(Button.name, Button)
5.rem引入
将rem.js放入pluins中,在nuxt.config中配置ssr为false即可
6.部署
pm2提供了比较好的一套方案。默认服务器有node pm2 git 环境
进入项目目录后执行pm2 deploy production
ecosystem.config.js配置如下
deploy: { production: { user: '仓库用户名', host: '仓库地址', ref: 'origin/master 分支名称', repo: 'https://***.git 项目git地址', path: '/var/www/production 打包后代码目录', 'post-setup': 'git pull origin develop && ls -la', 'post-deploy': 'npm install && npm run build && pm2 reload ecosystem.config.js --env production' }, }
项目代码 代码地址,有疑问可以提issue。