手机版

详细解释如何使用Next.js构建服务器端渲染应用程序

时间:2021-08-31 来源:互联网 编辑:宝哥软件园 浏览:

next.js简介

最近在学习React.js,React官方推荐使用next.js框架作为构建服务器端渲染的网站,今天就来学习一下next.js的使用。

next.js作为一个轻量级的应用框架,主要用于构建静态网站和后端渲染网站。

框架特征

使用后端渲染自动进行代码拆分,从而获得更快的网页加载速度。简单的前端路由实现使用webpack构建,支持Hot Module Replacement与主流Node服务器(如express)接口,可以自定义babel和webpack的配置和使用方法。

创建一个项目并初始化

Mkdir服务器-渲染-网站光盘服务器-渲染-网站NPM初始化-y安装next.js

使用npm或纱线安装,因为是创建react应用程序,所以React和react-dom是同时安装的

国家预防机制:

npm安装-保存反应反应-dom nextyarn:

Yarn add react下一步添加项目根目录下的文件夹页面(必须命名为pages,这是next的强制约定,否则找不到页面),然后在package.json文件中添加脚本启动项目:

脚本' : {'dev' :' next'}如下

创建视图

在pages文件夹下创建index.js文件。文件内容:

常量索引=()=(div p hello next.js/p/div)导出默认索引运行

Npm run next在浏览器中打开http://localhost:3000/网页,显示如下:

这就完成了最简单的下一个网站。

前端路由

next.js前端路由的使用非常简单,所以我们首先添加一个名为about的页面,如下所示:

const About=()=(div p这是关于页面/p /div)导出默认的关于;当我们在浏览器中请求https://localhost:3000/about时,可以看到页面显示了相应的内容。(==这里需要注意的是,请求url的路径必须与页面的文件名相同,如果访问localhost:3000/About,则找不到关于页面。==)

我们可以使用传统的A标签在页面之间跳转,但是每次跳转都需要去服务器请求。为了提高页面访问速度,建议使用next.js的前端路由机制进行跳转。

Next.js使用next/link在页面之间跳转。用法如下:

从“next/Link”const Index=()=(div Link href='/about ' rel=' external nofollow ' rel=' external nofollow ' rel=' external nofollow ' rel=' external nofollow ' rel=' external nofollow ' a About Page/a/Link p hello next.js/p/div)导入链接导出默认索引,这样您就可以通过单击索引页的“AboutPage”链接跳转到“about Page”,而单击浏览器的“back”按钮也会跳转到前端路由。根据官方文件,使用前端路由跳转时不会有网络请求。实际上,会有一个关于. js文件的请求,这个请求来自页面中动态插入的脚本标记。但是,about.js只会被请求一次,然后就不会被请求访问。毕竟同一个脚本标签不会重复插入。然而,与后端路由相比,它仍然大大节省了请求数量和网络流量。前端路由和后端路由之间的请求比较如下:

前端路由:

后端路由:

链接标签支持任何react组件作为其子元素,只要子元素能够响应onClick事件,就不需要使用a标签,如下所示:

link href='/about ' rel=' external nofollow ' rel=' external nofollow ' rel=' external nofollow ' rel=' external nofollow ' div go about page/div/link link link标记不支持添加样式和类名等属性。如果要为链接添加样式,您需要添加:

link href='/about ' rel=' external nofollow ' rel=' external nofollow ' rel=' external nofollow ' rel=' external nofollow ' a class name=' about-link ' style={ { color : ' # ff 0000 ' } }转到关于页面/a/LinkLayout

所谓的布局就是就是给不同的页面添加相同的页眉、页脚、导航栏等通用的部分,同时又不需要写重复的代码。在next.js中可以通过共享某些组件实现布局。

我们先增加一个公共的页眉组件,放在根目录的成分文件夹下面(页面级的组件放页中,公共组件放成分中):

从"下一个/链接"导入链接;const Link style={右边距: 15 } const Header=()=(div Link href='/' external nofollow ' rel=' external nofollow ' rel=' external nofollow ' a style={ Link style } Home/a/Link Link Link href='/About ' rel=' external nofollow ' rel=' external nofollow ' rel=' external nofollow ' a style={ Link style } About/a/Link/div)导出默认表头;然后在指数和关于;在…各处;大约页面中引入页眉组件,这样就实现了公共的布局的标题:

从导入标题./组件/标题;常量索引=()=(表头/next.js/p/div)导出默认索引;如果要增加页脚也可以按照页眉的方法实现。

除了引入多个页眉、页脚组件,我们可以实现一个整体的布局组件,避免引入多个组件的麻烦,同样在成分中添加一个布局。射流研究…文件,内容如下:

从""导入标头“/Header”;常量布局样式={边距: 20,填充: 20,边框: '1px实线# DDD ' }常量布局=(道具)=(div style={ Layout style } Header/{ props。儿童}/div)导出默认布局这样我们只需要在页面中引入布局组件就可以达到布局的目的:

从导入布局'./组件/布局;常量索引=()=(布局next.js/p/布局)导出默认索引;页面间传值

通过全球资源定位器(统一资源定位符)参数(查询字符串)

然后中的页面间传值方式和传统网页一样也可以用全球资源定位器(统一资源定位符)参数实现,我们来做一个简单的博客应用:

首先将index.js的内容替换成如下来展示博客列表:

从"下一个/链接"导入链接;从导入布局'./组件/布局;const PostLink=(道具)=(li Link href={`/post?title=$ {道具。title } ` } a {道具。标题}/a/Link/Li);导出默认值()=(布局h1我的博客/h1 ul帖子链接标题=' Hello next。js '/PostLink title=' next。射流研究…真棒/post链接标题='用时代周报部署应用/ul/布局);通过在环的超链接中添加标题参数就可以实现传值。

现在我们再添加博客的详情页post.js:

从“下一个/路由器”导入{带路由器};从导入布局'./组件/布局;const Post=带路由器((道具)=(布局h1 {道具。路由器。查询。title }/h1 p这是博文内容/p/Layout));导出默认帖子;上面代码通过带路由器将然后的路由器作为一个支柱注入到成分中,实现对全球资源定位器(统一资源定位符)参数的访问。

运行后显示如图:

列表页

点击进入详情页:

使用查询字符串可以实现页面间的传值,但是会导致页面的全球资源定位器(统一资源定位符)不太简洁美观,尤其当要传输的值多了之后。所以next.js提供了路由屏蔽这个特性用于路由的美化。

路由伪装(路由屏蔽)

这项特性的官方名字叫路由屏蔽,没有找到官方的中文名,所以就根据字面意思暂且翻译成路由伪装。所谓的路由伪装即让浏览器地址栏显示的全球资源定位器(统一资源定位符)和页面实际访问的全球资源定位器(统一资源定位符)不一样。实现路由伪装的方法也很简单,通过环组件的如同属性告诉浏览器超链接对应显示为什么全球资源定位器(统一资源定位符)就可以了,索引。射流研究…代码修改如下:

从"下一个/链接"导入链接;从导入布局'./组件/布局;const PostLink=(道具)=(Li Link as={ `/p/$ {道具。id } ` } href={ `/post?title=$ {道具。title } ` } a {道具。标题}/a/Link/Li);导出默认值()=(布局h1我的博客/h1 ul帖子链接id=' Hello-next js ' title=' Hello next。js/post链接id=' learn-next js ' title=' next。射流研究…很牛逼/post链接id=' Deploy-next js ' title='用时代周报部署应用/ul/布局);运行结果:

浏览器的网址已经按计划修改,这让它看起来舒服多了。而且路线伪装对历史也很友好,点击Return前进依然可以正常打开详情页。但是,如果刷新详细信息页面,您将报告错误404,如图所示:

这是因为刷新页面会直接向服务器请求这个url,而服务器没有对应这个url的页面,所以会报告错误。要解决这个问题,您需要使用next.js提供的自定义服务器API.

定制服务界面

在定制服务界面之前,我们需要创建一个服务器并安装Express:

Npm install - save express在项目的根目录下创建server.js文件,包含以下内容:

const express=require(' express ');const next=require(' next ');const dev=process.env.NODE_ENV!==“生产”;const app=next({ dev });const handle=app . GetRequestHandler();app.prepare()。然后(()={ const server=express();server.get('* ',(req,res)={返回句柄(req,RES);});server.listen(3000),(err)={ if(err)throw err;console . log(' http://localhost :3000上的Ready ');});}) .catch((ex)={ console . error(ex . stack));process . exit(1);});然后将package.json中的dev脚本更改为:

脚本' : {'dev' :' server.js'}运行npm run dev后,项目可以像以前一样运行。接下来,我们需要添加一个路由来匹配伪装的url和真实的url,并添加:

.const server=express();server.get('/p/:id ',(req,RES)={ const actual page='/post ';const query params={ title : req . params . id };app.render(请求、资源、实际页面、查询参数);});这样,我们映射了伪装的url和真实的url,查询参数也映射了。重新启动项目后,您可以在不报告错误的情况下刷新详细信息页面。但是,有一个小问题。前端路由打开的页面标题与后端路由打开的页面标题不同,因为后端路由传输id,而前端路由页面显示标题。这个问题在实际项目中是可以避免的,因为在实际项目中,我们通常是通过id得到标题,然后显示出来。作为Demo,我们偷了点懒,直接用id作为后端路由页面的标题。

以前,我们的演示数据是静态的。接下来,我们实现了从远程服务获取数据并呈现出来。

远程数据采集

Next.js提供了一个获取远程数据的标准接口:getInitialProps。通过getInitialProps,我们可以获取远程数据,并将其分配给页面的道具。GetInitialProps可以在服务器端使用,也可以在前端使用。接下来,我们写一个小演示来展示它的用法。我们打算从TVMaze API获取一些关于电视节目的信息,并在我的网站上展示。首先,我们安装同构的-unfit,这是一个基于fetch的网络请求库:

NPM安装-保存同构-取消匹配,然后我们修改index.js如下:

从“下一个/链接”导入链接;从导入布局'./组件/布局';从“同构-不匹配”导入提取;const Index=(道具)=(布局h1 marvel TV Shows/h1 ul { props . Shows . map(({ show })={ return(Li键={ show . id } Link as={ `/p/$ { show . id } ` } href={ `/post?id=$ { show . id } ` } a { show . name }/a/Link/Li);})}/ul/Layout);index . getinitialprops=async function(){ const RES=wait fetch(' https://API . tvmaze.com/search/shows?q=marvel’);const data=await RES . JSON();返回{ shows: data } }导出默认索引;上面代码的逻辑应该很清楚。我们在getInitialprops中获取电视节目数据并返回,这样就可以在Index Props中获取节目数据,然后遍历并渲染成节目列表。

运行项目后,页面完美显示:

接下来,我们实现详细信息页面。首先,我们将/p/:id的路由修改为:

.server.get('/p/:id ',(req,RES)={ const actual page='/post ';const query params={ id : req . params . id };app.render(请求、资源、实际页面、查询参数);});我们以id为参数获取电视节目的详细信息,然后将post.js的内容修改如下:

从"同构-不匹配"导入提取;从导入布局'./组件/布局;const Post=(道具)=(布局h1 {道具。展示。name }/h1 p { props。展示。总结。替换(/[/]?p/g ' ')}/p img src={ props。展示。图像。中}//布局);Post.getInitialProps=异步函数(上下文){ const { id }=context . queryconst RES=wait fetch(` https://API。电视迷宫。com/shows/$ { id } `);const show=await RES . JSON();返回{ show };}导出默认帖子;重启项目(修改了server.js的内容需要重启),从列表页进入详情页,已经成功的获取到电视节目的详情并展示出来:

增加样式

到目前为止,咱们做的网页都太平淡了,所以接下来咱们给网站增加一些样式,让它变得漂亮。

对于反应应用,有多种方式可以增加样式。主要分为两种:

使用传统半铸钢钢性铸铁(铸造半钢)文件(包括邮政编码等)在射流研究…文件中插入半铸钢钢性铸铁(铸造半钢)使用传统半铸钢钢性铸铁(铸造半钢)文件在实际使用中会用到挺多的问题,所以next.js推荐使用第二种方式next.js内部默认使用样式-jsx框架向射流研究…文件中插入CSS。这种方式引入的样式在不同组件之间不会相互影响,甚至父子组件之间都不会相互影响。

样式-jsx

接下来,我们看一下如何使用样式-jsx。将index.js的内容替换如下:

从"下一个/链接"导入链接;从导入布局'./组件/布局;从"同构-不匹配"导入提取;常量索引=(道具)=(布局h1漫威电视节目/h1 ul {道具。表演。地图(({ show })={ return(Li键={ show。id } Link as={ `/p/$ { show。id } ` } href={ `/post?id=$ { show。id } ` } a类名=' show-Link ' { show。姓名}/a/Link/Li);})}/ul style jsx { ` * { margin :0;划水:0;} h1,a { font-family : ' Arial} h1 { margin-top :20 px;背景-颜色: # EF141Fcolor : # ffffont-size :50 px;线高:66 px文本转换:大写;文本对齐:居中;} ul { margin-top :20 px;padding:20px背景色: # 000;}李{列表式:无;余量:5 px 0;} a { text-decoration : none颜色: # B4B 5 B4;font-size :24 px} a :悬停{ opa city 33600.6} `}/样式/布局);索引。getinitialprops=async function(){ const RES=wait fetch(' https://API。电视迷宫。com/search/shows?q=marvel’);const data=await RES . JSON();console . log(` 0显示提取的数据计数: $ { data。length } `);返回{ shows: data } }导出默认索引;运行项目,首页变成:

增加了一点样式之后比之前好看了一点点。我们发现导航栏的样式并没有变。因为页眉是一个独立的的组件,组件之间的样式不会相互影响。如果需要为导航增加样式,需要修改Header.js:

从"下一个/链接"导入链接;const Header=()=(div Link href='/' rel=' external nofollow ' rel=' external nofollow ' aHome/a/Link Link href='/about ' rel=' external nofollow ' rel=' external nofollow ' aAbout/a/Link style jsx { ` a { color : # EF141F;font-size :26 px线高:40 px文本装饰:无;padd :0 10 extxt-transform :大写;} a :悬停{ opa city 33600.8} `} /style /div)导出默认页眉效果如下:

全局样式

当我们需要添加一些全局的样式,比如rest.css或者鼠标悬浮在a标签上时出现下划线,这时候我们只需要在样式jsx标签上增加全球的关键词就行了,我们修改布局。射流研究…如下:

从“”导入标头。/Header ';const Layout style={ margin : 20,padding: 20,border: '1px实线#DDD'}const Layout=(道具)=(div style={ Layout style } Header/{ props . children } style jsx global { ` a : hover { text-decoration 3360 underline;} `}/style/div)导出默认布局,以便当鼠标悬停在所有标签上时,会出现下划线。

部署next.js应用程序

建设

在部署之前,我们首先需要能够为生产环境构建项目,并将脚本添加到package.json:

构建“:”下一个构建“接下来,我们需要能够启动项目来服务于我们构建的内容,并向package.json添加脚本:

开始“:”下一个开始,然后依次执行:

npm run buildnpm run startbuild的完成内容将生成到。下一个文件夹。npm运行开始后,我们实际上访问。下一个文件夹。

运行多个实例

如果我们需要横向扩展来提高网站的访问速度,我们需要运行多个网站实例。首先,我们修改package.json的启动脚本:

开始' : '下一个开始-p $PORT '如果是windows系统:

启动“:”下一个start -p %PORT%”,然后运行build: npm运行build,然后打开两个命令行,找到项目根目录,然后分别运行:

端口=8000 npmstart端口=9000 npmstart运行后,打开localhost:8000和localhost:9000,可以正常访问:

虽然可以通过以上方法进行打包部署,但是有一个问题是我们的定制服务server.js没有运行,导致在刷新详情页的时候出现404的错误,所以我们需要将定制服务添加到app的逻辑中。

部署和使用定制服务

我们将启动脚本修改为:

启动' : ' node _ env=production nodeserver . js ',这样我们就可以解决定制服务的部署问题。重新启动项目后,也可以正常访问刷新后的详细信息页面。

到目前为止,我们已经学习了next.js的大部分使用方法,如果您有任何问题,可以查看next.js的官方文档或者给我留言讨论。

本文演示源代码:Github

源代码next.js官方网站:https://nextjs.org/

Next.js官方教程:https://nextjs.org/learn

下一个. js Github:https://github.com/zeit/next.js

以上就是本文的全部内容。希望对大家的学习有帮助,支持我们。

版权声明:详细解释如何使用Next.js构建服务器端渲染应用程序是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。