react搭配nextjs走马观花…
因果
angular、react、vue等现代前端框架带领前端进入spa(单页面应用)时代。从此前端可以自己操控路由,页面与页面之间不再是一个个孤立的网页,而是一个完整的应用。
但是但页面应用的盛行也带来了一些问题:
①、不利于seo,所有内容都是通过后台异步获取,搜索引擎抓取内容的时候是抓不到有意义的内容的。(据说谷歌等搜索引擎已经能够通过ajax抓取有意义的内容了,但目前的百度无疑是不行的);
②、首屏加载时间过长。主要原因是我们打包出来的bundle文件过大,即使经过路由组件拆分,依旧不能达到用户的预期。
如何解决spa带来的副作用,针对react的ssr框架,我们请出今天的主角nextjs.
入门
安装依赖
1 | # c创建项目目录并安装以下依赖 |
定义命令
运行npm run dev
将会在本机的3000端口呈现nextjs渲染出来的内容
1 | // 在package.json中定义一下命令 |
在项目中增加两个文件夹:pages、static。
pages文件夹中的组件路径映射到URL对应目录上,static文件夹存放静态资源。
页面之间的导航
Link组件
我们可以通过nextjs提供的Link组件进行页面之间的跳转。
1 | // pages/index.js |
给链接添加样式
Link组件是一个抽象的高阶组件,所以给它加样式是不起作用的。
1 | <Link href="/about"> |
共享组件
共享组件存放的路径是可以自定义的,事实上,除了pages以及static文件夹,其他文件夹名称都可以自定义。
1 | /* components/MyLayout.js */ |
传递消息,创建动态页面
很多时候,我们是根据不同的信息动态地渲染不同内容的页面,如给页面传入不同的ID从而渲染不同的详情内容。
传递参数
1 | /* pages/index.js */ |
接受参数
1 | /* pages/post.js */ |
此时,在浏览器地址栏中输入: “http://localhost:3000/post?title=Hello%20Next.js" 就可以看到效果了。
路由掩码
路由掩码的作用实际上就是将真实丑陋的URL地址掩盖起来,呈现给用户一个清爽的URL。
就像上节的栗子:我们的真实URL地址是 “http://localhost:3000/post?title=Hello%20Next.js" ,但是我们希望呈递给用户的URL是 “http://localhost:3000/p/hello-nextjs" 。
Link的as属性
1 | const PostLink = (props) => ( |
整完之后,浏览器中的前进后退都是可以实现的,但是如果在 “http://localhost:3000/p/hello-nextjs" 时,直接刷新页面就会报页面404。接下来我们来看看如何通过nodejs修复这个bug。
服务器端配合
安装express
1 | # 这里我们使用express来处理 |
创建服务
1 | /* server.js */ |
更新启动命令
1 | /* package.js */ |
页面加载前获取初始数据
直接刷新页面获取值
有时候我们在页面初始化时需要先从后台服务器中获取数据。此时我们就要祭出getInitialProps
与async
了。
1 | import Layout from '../components/MyLayout.js' |
这段打印的信息只会在服务器端打印出来,浏览器控制来不会有这段信息。理当如此!
从其他页面跳转后获取初始数据
1 | /* pages/post.js */ |
通过其他页面跳转过来的是通过浏览器异步地获取数据,就像从前一样。
部署
将nextjs项目部署到服务器上需要解决两个问题:①、项目的启动要随之操作系统的启动而启动;②、将80端口代理到nextjs开启的端口上。
使用PM2来管理我们的Next.js进程
- 启动next.js进程
1 | # 自定义Express服务器 |
- 保存启动信息
1 | pm2 save |
- 创建系统启动服务
1 | # 以Ubuntu 16.04为例, 它会创建一个名为pm2-www.service的SYSTEMD服务. |
- 查看PM2管理的Next.js应用程序状态
1 | systemctl status pm2-www.service |
代理端口
- 指定Next.js应用运行的端口
1 | /* 首先配置 package.json */ |
1 | PORT=8000 yarn start |
- 使用Ngninx反向代理
1 | # 也可以不直接指定端口, 让Next.js 应用程序在Nginx反向代理后面跑. |