NextJS 极速上手

1,275 阅读6分钟

如果你是使用react的开发者,想要生成服务端渲染和静态的网页,可以使用Next框架,它基于react的,可以让你使用react的技术来开发。

如果你只会vue,可以去看nuxt,跟next相似。

服务端渲染和静态生成的优势

  • 为什么要用服务端渲染和静态生成?它们都是预渲染的,核心是为了做搜索引擎优化,让用户能在搜索引擎里搜索跟你网站相关的关键字时候,你的网站能出现在搜索结果页的前面,能被用户优先看见。
  • 减少白屏时间,带来更好的性能,因为服务端渲染和静态生成的话,网站的几乎所有东西都已经准备(预渲染)好了(如html,js、css和数据等),不像客户端渲染,所有东西都在浏览器里面(使用js)生成,生成的这段等待时间,会让用户看到一段时间的白屏,影响用户的体验。
  • 静态网站,配合cdn,缓存页面,性能更佳。

为什么不必用next?

如果你的网站不需要是静态的和不是内容型网站(如知乎、简书等),你不必使用它,直接使用react/vue,在index.html的head里配好需要让搜索引擎知道的的信息就可以了。

发车

下面主要介绍使用next开发项目核心需要知道的东西,对于一个刚使用next开发项目的开发者,只看官方文档然后进入开发项目还是挺困难的,在这里我会告诉你,使用next开发项目核心要用到哪些东西,知道这些东西将帮助你建立快速上手next的全局视野。下面的东西你快速扫一眼即可,看不明白也没关系,当实际开发中需要的时候,配合文档,你就会明白了。

pages

创建在pages下的文件即页面的路由,这是约定好的。 如: pages/index.js -> / pages/foo.js -> /foo ,我一般习惯文件夹+index文件的格式 pages/foo/index.js -> /foo

pages更多介绍:

路由

next自带了路由,一个是路由组件link,一个是router对象,提供页面跳转的能力。

  • link 对已打开过的页面具有缓存的能力,如果跳转的是相同的路由,不会重载刷新页面。
  • router对象也提供路由跳转,它还提供了在组件里访问路由对象信息的能力,如pathname路径、query参数等。

文档:

Head组件

每个网页都有个head标签,next的Head组件让你可以在页面中配置head信息。

import Head from 'next/head'

function Home() {
  return (
    <div>
      <Head>
        <title>写文章 - NextJS 极速上手 - 掘金</title>
        <meta name="viewport" content="initial-scale=1.0, width=device-width" />
        <link rel="shortcut icon" href="https://p1-jj.byteimg.com/tos-cn-i-t2oaga2asx/gold-assets/favicons/favicon.ico~tplv-t2oaga2asx-image.image">
      </Head>
    </div>
  )
}

export default Home

css

我一般使用scss只需要安装sass就可以直接使用了。支持组件级样式,需要这样创建使用:xxx.module.scss

npm install sass
#or
yarn add sass

API

next提供简单的后端服务功能,支持REST模式和GraphQL等,它定义在pages下的api目录里. 使用create-next-app创建项目的时候,你会看到pages/api/hello.js,运行项目,在浏览器里访问http://localhost:3000/api/hello,你会看到请求该api返回的信息。

为页面获取数据

数据让应用内容更丰富,那怎么获取数据呢?如果你的数据不需要预请求,可以使用官方推荐的SWR的数据fetch库。

//来自官方示例,打开下面文档地址,滚动最底下就能看到。
import useSWR from 'swr'

function Profile() {
  const { data, error } = useSWR('/api/user', fetch)

  if (error) return <div>failed to load</div>
  if (!data) return <div>loading...</div>
  return <div>hello {data.name}!</div>
}

官方还提供了3个页面获取数据,然后预渲染的方法。

  • getStaticProps (用于静态生成): 在应用构建时获取数据
  • getStaticPaths (用于静态生成):使用动态路由来预渲染基于数据的页面.
  • getServerSideProps (用于服务端渲染): 让网站的页面在服务端也能预渲染,但该方法需要启动服务。

如果你的某些数据需要让搜索引擎捕获到,你可以研究和使用上面这3个方法,否则用swr在客户端获取数据就好了。

next.config.js

这是一个next的配置文件,在这里可以配置一些应用的行为。在这里我主要介绍我在项目中常用到的5个东西。

环境变量

环境变量让我们能够在不同环境下构建应用的时候注入一些东西。 比如在开发环境或生产环境,应用的名称是不同的。那我们可以在项目的根目录下创建2个文件,.env.development(开发) .env.production(生产),并在里面定义好相关内容。

// .env.development
title=foo

//.env.production
title=bar

//next.config.js 
module.exports = {
  env: {
    Title:process.env.title,
  },
}

import Head from 'next/head'

function Home() {
  return (
    <div>
      <Head>
        <title>{process.env.Title}</title>
        <meta name="viewport" content="initial-scale=1.0, width=device-width" />
        <link rel="shortcut icon" href="https://p1-jj.byteimg.com/tos-cn-i-t2oaga2asx/gold-assets/favicons/favicon.ico~tplv-t2oaga2asx-image.image">
      </Head>
    </div>
  )
}

export default Home

Base Path

你要在域名子路径部署网站的话,可以配置basePath

// next.config.js
module.exports = {
  basePath: '/foo',
}

那网站就会部署在如localhost:3000/foo下。

Rewrites

这是一个代理路由的东西,能够把source映射到 destination,还挺有用的,可以让你渐进式迁移到next,先看下面配置吧。

// next.config.js
module.exports = {
  async rewrites() {
    return [
      // 默认使用定义在pages下的路由,否则将代理到 https://www.nextjs.cn/,需要注意的是pages下定义的路由有最高优先级。
      {
        source: '/:path*',
        destination: '/:path*'
      },
      {
        source: '/:path*',
        destination: `https://www.nextjs.cn/:path*`
      }
    ]
  }
}


// pages/index.js
const Index = () => (
      <div>
        <Link href="/docs/api-reference/next.config.js/rewrites" >
          <a>打开rewrites</a>
        </Link>
      </div>
)

export default Index

点击按钮的时候,你会看到它打开的是https://www.nextjs.cn/docs/api-reference/next.config.js/rewrites里的网页,但却是出现在我们的域名之下的http://localhost:8000/docs/api-reference/next.config.js/rewrites,当我们想要把这个网站迁移到next,但其中某个页面还不想去用next重写,我们就可以这么干。当然还有更多使用方法,请看官方文档。

cdn

设置cdn很简单,看下面配置

const isProd = process.env.NODE_ENV === 'production'

module.exports = {
  //在生产使用cdn,本地不用
  assetPrefix: isProd ? 'https://cdn.mydomain.com' : '',
}

Trailing Slash

这是给网站地址的最后是否加/的。有啥用呢?当用户刷新你的网站出现找不到网页。当出现这种情况,把它配置为true即可。

module.exports = {
  trailingSlash: true,//true表示在网址后显示/,否则不显示
}

构建部署

部署混合应用(服务端渲染和静态融合)

默认package.jsonscripts定义了devbuildstart,当你要部署的时候你都要先执行build,start会对你build的网页启动node服务,如果你的网页中用到了某些需要node服务的api,那就必须要用start。

导出静态html

在package里像下面声明即可,执行yarn build 或 npm run build,会生成out目录。

//package.json
"scripts": {
  "build": "next build && next export"
}

注意:有些api,是不能export的,当你要构建静态网站的时候,别写完了才发现,希望你尤其注意。

比如你使用了API路由next/imagegetStaticPathsfallback:true,getServerSideProps,exportPathMap等,这里列的不全,当你使用某个api的时候,需要详细看文档。

结束

如果上面存在你不理解地方,那一定是我故意的。

当你开始使用next开发项目的时候,如果看了这篇文章,相信你会少走很多弯路,也不必担心被官方文档的大量内容而吓到,上面提到的都是我在开发项目的时候主要使用到的技术,重点看上面我提到的东西就好,然后边开发边查文档。祝你上手愉快!