
还是 React 的生态,今天聊聊 React 服务端渲染框架 Nextjs。
创建初始化项目
npm init -y
安装 react 、react-dmo next 依赖
yarn add react react-dom next
在 pages 文件夹下创建一个 index.js 当访问 "/" 就会返回这个文件的内容,在 next 中我们这里无需引用 React 就是可以使用 jxs。
const Index = () => <h1>Hello World from Next JS</h1>;
export default Index;
我们修改一下 next 启动命令。
"scripts": {
"dev": "next"
},
值得注意也是我们为 Nextjs 而叫好的就是 pages 中结构就实际路由的结构。访问 https://localhost:8000/就可以看到下面的画面。

通过引入 next 的 Link 可以进行导航。Link 的属性 href 可以指向一个地址。
import Link from "next/link";
const Index = () => (
<section>
<h1>Hello World from Next JS</h1>
<Link href="/about">
<a title="About NextJS">About Next JS Project</a>
</Link>
</section>
);
export default Index;

在 pages 跟目录下创建 about.js 对应于 /about 的 url。当访问到 /about 就会开启该页面。
const About = () => (
<section>
<h1>about page</h1>
</section>
)
export default About;
import React, { Component } from "react";
import Link from "next/link";
export default class Navbar extends Component {
constructor(props) {
super(props);
this.props = props;
}
render() {
return (
<div>
<div>
<Link href="/">
<a title="About Next JS">Home</a>
</Link>
<Link href="/about">
<a title="About Next JS">About Next JS</a>
</Link>
</div>
</div>
);
}
}

创建组件
创建一个名词为 components 文件夹,在该文件夹下可以创建组件,创建组件的方式与 react 项目中创建组件并没有特别之处。

import Navbar from "../components/Navbar";
const Index = () => (
<section>
<h1>Hello World from NextJS</h1>
<Navbar />
</section>
);
export default Index;
创建好组件便可以在我们 index.js 文件引入后进行使用。
import React, { Component } from "react";
import Link from "next/link";
export default class Navbar extends Component {
constructor(props) {
super(props);
this.props = props;
}
render() {
return (
<nav>
<div>
<Link href="/">
<a title="About Next JS">Home</a>
</Link>
<Link href="/about">
<a title="About Next JS">About Next JS</a>
</Link>
</div>
<style jsx scoped>{`
a {
padding: 10px;
text-decoration: none;
color: "skyblue";
}
`}</style>
</nav>
);
}
}

在项目 pages 下可以创建一个可以被 next 自动识别的文件 _document.js 大家可能已经注意到了这个文件是以 _ 开头。
这个文件用于控制整个页面的骨架. 这个自定义的 _document.js 可以让覆盖默认的页面布局, 添加样式, 等等。以一种更优雅方式来添加样式而不是写奇怪的 jsx。

这个文件无需引入,Next 会知道如何使用这个文件
import Document, { Head, Main, NextScript} from 'next/document';
export default class MDocument extends Document{
render(){
return (
<html>
<Head>
<title>Next JS Awesome Kit</title>
</Head>
<body>
<Main/>
<NextScript/>
</body>
</html>
)
}
}
引入 Sass
- 写 css 当然更底层,更底层就表示更难于控制,现在我更愿意写 sass 、less 或者 stylus 来高效地写样式表。
要在项目中应用 sass,我们需要做一些工作才能在项目中写 sass。在根目录下创建一个名为 next.config.js 文件

然后添加下面代码 zeit 就是 next 的作者吧。
const withSass = require("@zeit/next-sass")
module.exports = withSass();
yarn add @zeit/next-sass node-sass
做好准备工作我们就可以开始 sass 了。怎么写 sass 我就不做更多说明了,今天重点不在于此。而是如何将 sass 引入到项目中已经如何使用。

nav {
$green: green;
nav {
padding: 10px;
a {
text-decoration: none;
color: $green;
}
}
<html>
<Head>
<title>Next JS Awesome Kit</title>
<link rel="stylesheet" href="/_next/static/style.css"/>
</Head>
<body>
<Main/>
<NextScript/>
</body>
</html>
yard add node-sass


$green : green;
@import '_vars.scss';
nav {
padding: 10px;
a {
text-decoration: none;
color: $green;
}
}

render() {
return (
<nav>
<div>
<Link href="/">
<a title="About Next JS">Home</a>
</Link>
<Link href="/about">
<a title="About Next JS">About Next JS</a>
</Link>
<mark className="badge">Hello!</mark>
</div>
</nav>
);
}
mark {
border-radius: 10px;
background-color: lightblue;
}
import "./Navbar.scss";

引入 PostCSS
都知道我们应用中 less 写的样式中某些属性在不同浏览器中不同前缀,许多方式可实现对属性名称进行补全而无需 developer 手动来添加前缀。之前项目中是使用的 gulp 的插件来实现。在 postcss 也有对应的插件。
prefix 添加多个浏览器支持的前缀。

在项目根目录下创建 postcss.config.js 也就是 postcss 的配置文件,我们可以在这个配置文件中添加插件。
module.exports = {
plugins:[
require("autoprefixer")({})
]
}
yarn add autoprefixer -D
import Navbar from "../components/Navbar";
import Head from 'next/head'
import "../scss/style.scss";
const Index = () => (
<section>
<Head>
<title>Hello world</title>
</Head>
<h1>Hello World from NextJS</h1>
<Navbar />
</section>
);
export default Index;
添加 express 作为后端
添加 express 依赖到项目中,然后在项目根目录下新建的 server 文件夹用于存放服务文件。
yarn add express

将我们的 dev 脚本命令修改一下修改为 node server/index.js 通过 express 来启动我们项目。
"scripts": {
"dev": "node server/index.js"
},
然后就是搭建我们服务了。
const express = require("express")
const next = require("next")
const PORT = process.env.PORT || 3000
const dev = process.env.NODE_ENV !== 'production'
const app = next({dev})
const handle = app.getRequestHandler();
app.prepare()
.then(()=>{
const server = express();
server.get("*",(req,res)=>{
return handle(req,res);
})
server.listen(PORT, err => {
if(err) throw err;
console.log(`> Ready on ${PORT}`);
})
.catch(ex => {
console.error(ex.stack);
process.exit(1);
})
})
- 引入 express 和 next 依赖
- 设置端口 PORT 默认为 3000
- 获取 next 应用的实例
- 在 prepare 方法返回 promise 设置 express 服务和定义路由。
server.get("/api/shows",(req,res)=>{
return res.end('api shows')
})
server.get("*",(req,res)=>{
return handle(req,res);
})
可以设置 api 路径

