next.js 采坑录(服务端渲染)
前言:
next.js
服务端渲染讲真,坑是真不少。
我们这里结合antd
构建简单服务端运用。咱们这里只讲最简单的构建步骤,复杂场景请看官网。咱们要是就是快。
next官网文档:http://nextjs.frontendx.cn/
1. 安装脚手架
create-next-app 是next的脚手架会为你搭建好最基本的next框架。
构建步骤
yarn global add create-next-app
create-next-app my-project
cd my-project
yarn dev
经过上述步骤就可以访问我们的页面。默认端口是3000
,但是经常被占用,所以
我们更改 package.json
:
"scripts": {
- "dev": "next",
+ "dev": "next -p 3006",
"build": "next build",
"start": "next start"
},
页面展示:
2. 加入antd
安装antd
和按需加载的babel-plugin-import
。
yarn add antd babel-plugin-import
目前时间2019年5月,此时的next@8.1.0
十分不稳定,和antd
结合出现了太多的问题,耽误了我非常多的时间。有位开发提供了一个稳定版本。next@7.0.2
,推荐大家都修改下,避免打包和导出静态资源出现各种问题。
安装next@7.0.2
yarn remove next
yarn add next@7.0.2
跟目录下建立.babelrc
{
"presets": ["next/babel"],
"plugins": [
// 可以使用装饰器decorator
["@babel/plugin-proposal-decorators", { "legacy": true }],
// 让我们可以使用根路径,避免相对路径的混乱,如import Head from '@/components/Head'
[
"module-resolver",
{
"alias": {
"@": "./"
}
}
],
// 按需加载并且可以使用less的配置
[
"import",
{
"libraryName": "antd",
"style": true
}
]
]
}
对于.babelrc
的功能,我们需要安装以下包:
yarn add @zeit/next-css @zeit/next-less less
yarn add babel-plugin-import
yarn add @babel/plugin-proposal-decorators
yarn add babel-plugin-module-resolver
根目录有个next.config.js
,专门用来修改next
以及webpack
的配置。更改如下:
const withLess = require('@zeit/next-less');
const WithCss = require('@zeit/next-css');
// fix: prevents error when .less files are required by node
if (typeof require !== 'undefined') {
require.extensions['.less'] = file => {};
}
module.exports = withLess(
WithCss({
lessLoaderOptions: {
modifyVars: {
'primary-color': '#1DA57A'
},
javascriptEnabled: true
}
})
);
其中modifyVars
是修改antd
的皮肤。
3. 编写demo
根目录pages
下本身是有index.js
,我们建两个文件夹index.less
和user.js
,Link
就可以直接路由跳转,不需要配置,还有Router
,详情看官网。
index.js
代码更换
import React, { Fragment } from 'react';
import Link from 'next/link';
import Head from '@/components/Head';
import './index.less';
import { Button} from 'antd';
const Home = () => (
<Fragment>
<Head title={'next-ssr'} />
<h1>欢迎来到next</h1>
{/* Link内需要a标签,不然爬虫识别不了,不用a可以加passHref,提高爬虫识别率 */}
<Link href="/userList" passHref>
<Button type="primary">用户列表页</Button>
</Link>
</Fragment>
);
export default Home;
新建的index.less
h1 {
color: green;
}
新建的user.js
const User = () => <h2>我是用户列表页</h2>;
export default User;
此时yarn dev
,可以看到生效了。
4. 部署
package.json
代码更改如下:
"scripts": {
"dev": "next -p 3006",
"start": "next start -p 3006",
"build": "next build",
"export": "next build && next export && serve out"
},
yarn build
就可以打包我们的项目,然后yarn start
就可以访问。
yarn build
yarn start
next
提供输出静态页面:next export
。
serve
是很好用的本地服务器,我想大家都遇到打包后的html
,路径不能直接访问把,就是因为默认是需要启动服务才能访问的,serve
完美解决了我们的问题。
yarn global add serve
yarn export
发布到自己服务器上:
github
提供了一个免费的服务器GitHub Pages
,这里可以展示自己的静态页面,如写个博客。
1. 怎么建github项目和关联远程,我这里就不说了,大家百度一下。
2. 更改 package.json
,增加了github
这个命令,大家可拆分看一下。
"scripts": {
"dev": "next -p 3006",
"start": "next start -p 3006",
"build": "next build",
"export": "next build && next export && serve out",
"github": "rm -rf node_modules/.cache && next build && next export && touch out/.nojekyll && git add out/ && git commit -m \"Deploy Next.js to gh-pages\" && git subtree push --prefix out origin gh-pages"
}
3. 在next.config.js
增加配置:assetPrefix
和publicRuntimeConfig
const withLess = require('@zeit/next-less');
const WithCss = require('@zeit/next-css');
// fix: prevents error when .less files are required by node
if (typeof require !== 'undefined') {
require.extensions['.less'] = file => {};
}
const prod = process.env.NODE_ENV === 'production';
module.exports = withLess(
WithCss({
lessLoaderOptions: {
modifyVars: {
'primary-color': '#1DA57A'
},
javascriptEnabled: true
},
// next-antd-ssr这个名字是你github项目名称
assetPrefix: prod ? '/next-antd-ssr' : '',
publicRuntimeConfig: {
linkPrefix: prod ? '/next-antd-ssr' : ''
}
})
);
4. 将pages下的index.js更改:增加了linkPrefix
和link中的as
import React, { Fragment } from 'react';
import Link from 'next/link';
import Head from '@/components/Head';
import './index.less';
import { Button} from 'antd';
import getConfig from 'next-server/config';
const { linkPrefix } = getConfig().publicRuntimeConfig;
const Home = () => (
<Fragment>
<Head title={'next-ssr'} />
<h1>欢迎来到next</h1>
{/* Link内需要a标签,不然爬虫识别不了,不用a可以加passHref,提高爬虫识别率 */}
<Link href="/userList" passHref as={`${linkPrefix}/userList`}>
<Button type="primary">用户列表页</Button>
</Link>
</Fragment>
);
export default Home;
5. 执行代码:
yarn github
6. 访问页面:大家在github的项目找到setting,往下翻到GitHub Pages
,点击链接就可以看到自己写的静态页面了。
image.png
image.png
作者的demo
github项目:https://github.com/muyu-zhilu/next-antd-ssr
发布的静态demo:https://muyu-zhilu.github.io/next-antd-ssr/
其他
为什么没用服务端server.js ?
next.js是默认服务端渲染,例如我们使用koa,是可以自由控制自己的路由,而且还可以写接口,做全栈开发。这里贴上我写的代码,供大家参考:
- 在根目录下建立
server.js
const Koa = require('koa');
const next = require('next');
const Router = require('koa-router');
const dev = process.env.NODE_ENV !== 'production';
const app = next({ dev });
const handle = app.getRequestHandler();
app.prepare().then(() => {
const server = new Koa();
const router = new Router();
router.get('*', async ctx => {
await handle(ctx.req, ctx.res);
ctx.respond = false;
});
server.use(async (ctx, next) => {
ctx.res.statusCode = 200;
await next();
});
server.use(router.routes());
// 防止出现控制台报404错误
server.use(async (ctx, next) => {
ctx.res.statusCode = 200;
await next();
});
server.listen(3001, () => {
console.log('server is running at http://localhost:3001');
});
});
- 更改
package.json
nodemon
可以自动重启服务,-i ./pages
是不需要重启的路径。
"scripts": {
"dev": "node ./server.js",
"build": "next build",
"start": "nodemon ./server.js -i ./pages ./components ./utils"
},
结束了,如果喜欢的话,点个✨,谢谢。有什么疑问,可以随时联系我。
如果大家不想用next
写服务端,其实是有koa2+react
也可以搭建,还有egg.js
可以写企业级应用。
有个名词叫同构应用,就是需要seo就用服务端渲染,不需要就用spa客户端渲染,不得不说路由跳转速度,spa单页特别快。所以之后的前端,不仅仅是页面搭建,而是创造更好体验的全栈工程师,一起加油吧!