React Nextjs (上)

nextjs

还是 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/就可以看到下面的画面。

图1

通过引入 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;
图2

在 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

创建组件

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


图3
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>
    );
  }
}

图5

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


图6

这个文件无需引入,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 文件


next.config

然后添加下面代码 zeit 就是 next 的作者吧。

const withSass = require("@zeit/next-sass")
module.exports = withSass();
yarn add @zeit/next-sass node-sass

做好准备工作我们就可以开始 sass 了。怎么写 sass 我就不做更多说明了,今天重点不在于此。而是如何将 sass 引入到项目中已经如何使用。


scss
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
图7
图8
$green : green;
@import '_vars.scss';

nav {
    padding: 10px;

    a {
        text-decoration: none;
        color: $green;
    }
}
图9
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";
图10

引入 PostCSS

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

postcss

在项目根目录下创建 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
server

将我们的 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 路径


图1
react 生态
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容