一、什么是 SSR
?
-
SSR
就是服务器渲染
,什么是服务器渲染
?由服务器
组装好DOM
元素,生成HTML
字符串给到浏览器,也就是在浏览器里面是可以看到整个页面的DOM
源码的。 -
SSR
解决的问题:SEO
:搜索引擎的优先爬取级别是页面的HTML
结构,当我们使用SSR
的时候,服务端已经生成了与业务相关联的HTML
,这样的信息对于SEO
是很友好的。内容呈现
:客户端无需等待所有的JS
文件加载完成即可看见渲染的业务相关视图(压力来到了服务端这边,这也是需要做权衡的地方,需要区分哪些由服务端渲染,哪些可以交给客户端)。 -
SSR
相关的弊端:代码兼容
:对于开发人员来讲,需要去兼容代码在不同环境的运行Vue SSR
所需要的服务端环境是Node
,有一些客户端的对象,比如dom
、windows
之类的则无法使用。服务器负载
:相对于前后端分离模式下服务器只需要提供静态资源来说,SSR
需要的服务器负载更大,所以在项目中使用SSR
模式要慎重,比如一整套图表页面,相对于服务端渲染,可能用户不会在乎初始加载的前几秒,可以交由客户端使用类似于骨架屏,或者懒加载之类的提升用户体验。 -
Vue
与Vue SSR
与原生HTML
页面源码区别对比,在网页上右键查看源码:Vue SSR
与原生HTML
是可以看到源码标签的Vue
默认是看不到源码标签的,因为它是 JS 组装的。
二、什么是 Nuxt.js ?
-
目前做
SSR
的方式有几种,大概列举一下:1、前端编写
原生静态页面
,给到服务器,通过服务器框架进行组合数据,例如php
的Web 开发
。2、使用 prerender-spa-plugin 插件,作者是
Vue
核心团队的成员,这种实现方式并不叫SSR
,而是预渲染
。不过效果上是一样的,甚至某种程度上来说可能要比SSR
更好。相比官方提供的SSR 繁琐配置
,prerender
配置更简单快捷。3、
Vue
官方提供的轮子在Node
端做SSR
, 相对于prerender
插件来说,SSR
上手真的超级复杂,有兴趣可以自行查看 Vue SSR 指南。这种方法可以做到真实数据实时渲染,完全可供SEO
小蜘蛛尽情的爬来爬去,完全前后端同构,路由配置共享,不再影响服务器404
请求,但是配置比较麻烦、处理流程比较复杂 (比对预渲染插件,复杂太多)约束较多,对服务器会造成较大的压力,服务器成本太高了。4、Nuxt.js 是使用
Webpack
和Node.js
进行封装的基于Vue
的SSR
框架,不需要自己搭建一套SSR
程序,而是通过其约定好的文件结构和API
就可以实现一个首屏渲染的Web
应用。我这里选择使用 Nuxt.js 来做
SSR
。
三、通过 Nuxt.js 创建项目
-
Nuxt.js 官方安装流程,项目需要依赖
Node
环境,我这里用的包管理工具是NPM
,Nuxt.js
版本是2.14.5
。 -
创建项目,确保安装了
npx
(npx
在NPM
版本5.2.0
默认安装了):$ npx create-nuxt-app <项目名> $ npm create nuxt-app <项目名> $ yarn create nuxt-app <项目名>
或者用
yarn
:$ yarn create nuxt-app <项目名>
我这里用
npx
创建一个测试项目,例如:$ npx create-nuxt-app nuxt-test
// 进入到文件夹,执行创建项目命令 dengzemiaodeMacBook-Pro:test dengzemiao$ npx create-nuxt-app nuxt-test create-nuxt-app v3.5.2 ✨ Generating Nuxt.js project in nuxt-test // 项目初始配置,自己看着选,用什么选什么 不懂就选 None,后面也可以装的。 ? Project name: nuxt-test ? Programming language: JavaScript ? Package manager: Npm ? UI framework: None ? Nuxt.js modules: Axios - Promise based HTTP client ? Linting tools: (Press <space> to select, <a> to toggle all, <i> to invert sele ction) ? Testing framework: None ? Rendering mode: Universal (SSR / SSG) ? Deployment target: Server (Node.js hosting) ? Development tools: jsconfig.json (Recommended for VS Code if you're not using typescript) ? What is your GitHub username? dengzemiao ? Version control system: None .....等待一段时间,就会提示创建项目成功 🎉 Successfully created project nuxt-test // 如果是开发中,运行 npm run dev 就可以,开发者模式 To get started: cd nuxt-test npm run dev // 如果是需要发布到线上了,需要先 build 在 start 才能正式发布 To build & start for production: cd nuxt-test npm run build npm run start
四、Nuxt.js 本地运行
-
这篇文章只讲
创建项目
到发布服务器,以及服务器怎么部署才能通过服务器访问
,其他项目细节配置放在其他文章中去写。 -
创建完成项目之后,可以先运行项目一下,用上面
To get started
或To build & start for production
中的方式运行起来项目,只是前者是development
模式,后者是production
模式。dengzemiaodeMacBook-Pro:test dengzemiao$ cd nuxt-test dengzemiaodeMacBook-Pro:nuxt-test dengzemiao$ npm run dev > nuxt-test@1.0.0 dev /Users/dengzemiao/Desktop/Project/web/test/nuxt-test > nuxt ╭───────────────────────────────────────╮ │ │ │ Nuxt @ v2.14.12 │ │ │ │ ▸ Environment: development │ │ ▸ Rendering: server-side │ │ ▸ Target: server │ │ │ │ Listening: http://localhost:3000/ │ │ │ ╰───────────────────────────────────────╯
然后通过上面的
http://localhost:3000/
打开浏览器进行访问,但是这个是开发环境。 -
在
pages
里面的.vue
文件都会被自动转成路由,文件夹也是一样。 -
例如:项目
pages
文件夹里面有个index.vue
文件,它会被编译成index.html
,在路由中也就是/index
,可以尝试修改index.vue
里面的内容,或者新建一个.vue
文件进行测试内容。 -
例如:我在
pages
里面创建一个测试文件dzm.vue
,运行起来项目,访问的路径就是http://localhost:3000/dzm
<template> <div> dzm 测试页面 {{ env }} </div> </template> <script> export default { data () { return { // 当前启动的环境 development: 开发环境 production: 生产环境 env: process.env.NODE_ENV } } } </script>
五、Nuxt.js 直接 ip
访问项目(生产和开发都适用)
-
运行开发环境
$ npm run dev
╭───────────────────────────────────────╮ │ │ │ Nuxt @ v2.14.12 │ │ │ │ ▸ Environment: development │ │ ▸ Rendering: server-side │ │ ▸ Target: server │ │ │ │ Listening: http://localhost:3000/ │ │ │ ╰───────────────────────────────────────╯
-
运行生产环境
$ npm run build
+$ npm run start
╭──────────────────────────────────────────╮ │ │ │ Nuxt @ v2.14.12 │ │ │ │ ▸ Environment: production │ │ ▸ Rendering: server-side │ │ ▸ Target: server │ │ │ │ Memory usage: 29.1 MB (RSS: 73.1 MB) │ │ │ │ Listening: http://localhost:3000/ │ │ │ ╰──────────────────────────────────────────╯
-
通过上面的两个运行的结果,得到的地址都是
http://localhost:3000/
,这个是固定本地localhost:3000
才可以进访问,需要改成支持本地ip
也能访问,也就是你拿到本机电脑的ip
加上端口也能进行访问到,例如:http://10.0.93.169:3000
-
找到
nuxt.config.js
,添加下面代码:export default { head: {...}, css: [...], // 配置服务器(主要是这个配置) server: { // port: 8000, // default: 3000 host: '0.0.0.0', // default: localhost (推荐) // host: '0', // 等于 host: '0.0.0.0' 这样配置,在mac上这么配置没问题,但是在window上这么配置有报错。 timing: false },
再次运行项目,生产或测试都行,访问地址就会变成本机的
ip
地址加端口:╭─────────────────────────────────────────╮ │ │ │ Nuxt @ v2.14.12 │ │ │ │ ▸ Environment: development │ │ ▸ Rendering: server-side │ │ ▸ Target: server │ │ │ │ Memory usage: 29.4 MB (RSS: 74 MB) │ │ │ │ Listening: http://10.0.93.169:3000 │ │ │ ╰─────────────────────────────────────────╯
本地运行项目就到这里结束了,下面需要将项目发布到服务器运行起来。
四、Nuxt.js 上传服务器(Nginx + Node + PM2)
-
下面的这些操作如果需要测试,可以放在本地机器上进行搭建,把本地电脑当服务器使使。
-
服务器
安装Nginx + Node + PM2
。 -
Nuxt.js
是依赖Node
,所以服务器
需要安装Node
,装了Node
就会自带NPM
,然后通过NPM
安装PM2
:$ npm install -g pm2 // 可以通过 -h 查询使用方式 $ pm2 -h
PM2
是Node
的进程管理工具。为啥用这个
?举个例子
:运行项目之后,命令行窗口是不能关闭的,如果关闭了就无法访问这个项目地址了,所以需要支持关闭命令行窗口,运行的项目依然能够访问,也就是后台挂起进程,PM2
就可以做到这个事情。 -
安装好上面环境,在
Nginx
根目录里面通过Git
拉下来Nuxt.js
源码,可以新开文件夹存放也是可以的,随你自己$ git clone xxxxx.git // 如果存在代码就拉一下代码 保持最新 $ git pull
这里说一下,在网上搜一下会搜到很多只需要导入几个文件就可以运行项目的文章,但是这种方式有时候会出现
编译函数找不到
、资源文件找不到
之类的问题,所以如果不是特别熟悉Nuxt.js
的话,直接将整个项目拉下来使用,不需要去单独导入某些文件,这样也完美的避开一些细节上的坑,网上的文章一般都是推荐导入下面几个文件:.nuxt static nuxt.config.js package.json package-lock.json
-
将代码拉到服务器后,需要先走一遍
npm
安装,安装一下依赖包$ npm install
-
然后编译项目
$ npm run build
-
PM2
运行项目,后台挂起,你的项目名称
,可以随意填个,但是推荐跟项目package.json
文件里面的name
字段值一样,这样好区分。。// 之前是通过 $ npm run dev 或者 $ npm run start,但是命令行窗口不能关闭 // 启动开发环境后台挂起,列举了常用的几种方式,任意选一种 $ pm2 start npm -- run dev $ pm2 start npm --name "你的项目名称" -- run dev $ pm2 start ./node_modules/nuxt/bin/nuxt.js .... // 启动生产环境后台挂起,列举了常用的几种方式,任意选一种 $ pm2 start npm -- run start $ pm2 start npm --name "你的项目名称" -- run start .... // 例如:服务器启动开发环境,开发环境只需要一行命令 $ pm2 start ./node_modules/nuxt/bin/nuxt.js // 例如:服务器启动生产环境,生产环境需要先 build 在 start $ npm run build $ pm2 start npm --name "nuxt-test" -- run start // window 电脑注意:上面命令在 MAC 跟 服务器都可以生效,但是在 window 上如果做测试, // 有部分命令无法生效,我用window 用的少,所以也没去深入折腾,这里给一下建议: // window 电脑本地测试PM2挂开发环境,生产环境目前上面几种启动方式都无法挂载成功,直接上服务器挂就行了,本地只是用于测试,开发环境也不影响测试。 // 只能通过这行命令启动开发环境,生产环境的命令挂起无效,暂时没解决 $ pm2 start ./node_modules/nuxt/bin/nuxt.js
-
然后可以通过
$ pm2 list
查看是否挂起成功,这样显示了就是挂起成功了┌─────┬──────────────┬─────────────┬─────────┬─────────┬──────────┬────────┬──────┬───────────┬──────────┬──────────┬──────────┬──────────┐ │ id │ name │ namespace │ version │ mode │ pid │ uptime │ ↺ │ status │ cpu │ mem │ user │ watching │ ├─────┼──────────────┼─────────────┼─────────┼─────────┼──────────┼────────┼──────┼───────────┼──────────┼──────────┼──────────┼──────────┤ │ 0 │ nuxt-test │ default │ N/A │ fork │ 1190 │ 0s │ 0 │ online │ 0% │ 7.8mb │ den… │ disabled │ └─────┴──────────────┴─────────────┴─────────┴─────────┴──────────┴────────┴──────┴───────────┴──────────┴──────────┴──────────┴──────────┘
现在就可以通过你这台电脑或者服务器的
ip
地址加端口号进行访问了,例如:http://10.0.90.164:3000/
。 -
如果需要停掉后台挂起,执行删除命令即可,
id
就是$ pm2 list
列表中的id
值:// 删除单个挂起进程 $ pm2 delete id // 删除全面挂起进程 $ pm2 delete all 例如: $ pm2 delete 0
-
如果项目修改调整了,上传了新的东西,只需要拉下代码编译后,重启
PM2
对应环境进程即可:开发环境 - 初始化:
$ git pull
+$ npm install
+$ pm2 start npm --name "你的项目名称" -- run dev
生产环境 - 初始化:
$ git pull
+$ npm install
+$ npm run build
+$ pm2 start npm --name "你的项目名称" -- run start
注意:
$ pm2 start ....
命令,每次启动都会在$ pm2 list
列表中新增一个管理进程,所以只需要初始化创建了就行了,后面如果不是通过$ pm2 delete id
手动删除了,就不需要每次$ pm2 start ....
,只需要重启即可:开发环境 - 后续版本更新:
$ git pull
+$ npm install
+$ pm2 restart id
生产环境 - 后续版本更新:
$ git pull
+$ npm install
+$ npm run build
+$ pm2 restart id
-
额外说一句:如果
PM2
启动项目之后,不知道访问那个地址,那可以先$ pm2 delete id
删除进程,执行自带的运行方式$ npm run dev
或$ npm run start
,需要哪个环境就运行哪个命令,运行之后可以拿到访问地址,拿到之后关掉,在通过PM2
运行访问同意一个地址,注意端口号别变化了,如果端口被占用,会分配一个新的端口:╭──────────────────────────────────────────╮ │ │ │ Nuxt @ v2.14.12 │ │ │ │ ▸ Environment: production │ │ ▸ Rendering: server-side │ │ ▸ Target: server │ │ │ │ Memory usage: 29.4 MB (RSS: 74.6 MB) │ │ │ │ Listening: http://10.0.90.164:3000/ │ │ │ ╰──────────────────────────────────────────╯
-
最终通过
PM2
启动挂起之后,现在需要配置一下Nginx
,之前启动是Node
服务,访问是没问题的,但是现在需要通过Nginx
反代理到Node
,也就是通过Nginx
去访问到Node
的资源地址。 -
找到
Nginx
的nginx.conf
文件,在里面添加一个新的服务,以及一个反代理服务http { # 新建一个 nuxt server 服务 upstream nuxt { # 这里就是上面配置的 Node ip + 端口号,之前默认是 localhost:3000 server 0.0.0.0:3000; keepalive 64; } server { listen 8083; #服务器端口 server_name www.nuxt.com; #这里对应你服务器的域名 location / { proxy_pass http://nuxt; #这里对应上面 upstream 中新建的服务名 index index.html index.htm; } } }
-
配置好这个之后,通过
$ nginx
启动Nginx
或者$ nginx -s reload
刷新Nginx
配置文件生效。 -
配置好之后,启动
Node
,启动Nginx
,这样就可以直接通过Node
的ip + :3000端口
直接访问,也可以通过Nginx
的ip或域名 + :8083端口
访问了,对外当然是走Nginx
了,配置一下域名。 -
到这就完事了,其他就是项目内部的细节配置跟使用了,会写到另外的文章里面去!
-
附带 PM2 配置文件的使用,作用就是将生产或开发环境设置到配置文件里面,只需要执行配置文件即可达到效果,当然也可以不用走配置文件,走上面命令行区分生产或开发环境也一样,看自己喜好。