阅读 1402

[重学 Next.js] — 你应该知道的 Next.js 高级技巧 10 点 (上)

这是我参与8月更文挑战的第4天,活动详情查看:8月更文挑战

前言

之前出过很多 Next.js 系列的文章,也因此收获了很多朋友,不敢说 Next.js 用的有多好,但是个人对于 Next.js 应该绝对算得上是真爱了。之前因为个人原因,Next.js 更多的是停留在用的阶段,并且因为工作原因,还有大概一年半的时间没用过 Next.js 写项目,最近随着经验和年限增加,回过头来看感觉有些意难平,希望重新拾起对 Next.js 的热情,因此准备了一个系列 —— 《重学 Next.js》,希望从更深的角度去重温这位老朋友。文章可能会分为几个方向,看感觉随机写:

  • 1 - 实践系列。比如高级用法、最佳实践以及新特性的使用等等。

  • 2 - 源码系列。既然要更深入,那么源码就躲不过去,还是要啃的。

  • 3 - 翻译系列。翻译国外很多大牛的文章,其实 Next.js 的受众,还是国外居多。如果是翻译,会先征得作者的同意

废话少说,开始第一篇文章,第一篇文章就简单的溜溜缝,在一年半之前最后使用 Next.js 更新的版本还是 Version 8,看一下官网他已经更新到了 Version 11,真的是非常感慨啊。有很多新特性都不清楚,所以从官网上找了一篇文章或者说文档更为准确,进行了一下翻译以及简单实用,理解自身的理解并且搭配 Demo,给大家说一下使用 Next.js 你应该掌握的 10 点高级用法。

【注意】:如果觉得不喜欢看中文,或者就喜欢看原版,可以直接点击这里 —— 原文链接,本文不是直译,会带有个人分析总结和代码。

I - Next.js Redirects —— 重定向

【版本】: >= Next.js Version 9.5

【功能】: 将原路径重定向到一个新路径。

【解释】: 原路径包含在你的应用内部任何可访问的路径,包括 pages 文件夹下的路由以及 public 文件夹下的静态资源。

重要参数

  • source :传入的请求路径,也就是原路径
  • destination 目标路径,也就是重定向到目标路径
  • permanent 是否是永久重定向,如果为 true 就是永久重定向也就是 302,如果为 false 就是暂时的,也就是 301。

更多参数以及详细解释可以去看官网:Next.js Redirects

示例代码

// next.config.js

module.exports = {
  async redirects() {
    return [
      {
        source: '/home',
        destination: '/',
        permanent: true,
      },
    ]
  },
}
复制代码

上述代码,可以将 /home 路径重定向到 /,通过一个实际例子来看看效果。

image.png

熟悉 Next.js 的同学应该都知道,如上图所示,pages 文件夹就会被自动解析注册路由,那么现在我们整个系统里来说,其实只存在一个跟路径 /,并没有编写 /home 路由,正常来说如果没有使用 redirects 应该是 404,而现在我们是用了 redirects,看看是什么效果。

2021-08-23 19.27.55.gif

可以看到,没有出现 404,而是输入 /home 直接帮我们进行了重定向,除此之外,还能进行多级路径匹配,功能很强大,感兴趣的可以自己去实际使用看看效果。

II - Next.js Rewrites —— 重写

介绍完 Redirects 我们紧接着就来介绍一个官方也承认的和 Redirects 非常像的一个兄弟功能 —— Rewrites。

【版本】: >= Next.js Version 9.5

【功能】: 将原路径充当代理以此来屏蔽目标路径。

【解释】: 就是你看起来像是在访问目标路径,但实际上页面交互和效果都是原路径,简单来说就是用户无感知,因为重写并没有改变他们的在网站的位置。

示例代码

 <Link href="/list">
    <a className={styles.card}>
      <h2>List &rarr;</h2>
      <p>List 列表页.</p>
    </a>
 </Link>

<Link href="/rewrites">
    <a className={styles.card}>
      <h2>Rewrites &rarr;</h2>
      <p>路由 /rewrites.</p>
    </a>
</Link>
复制代码
// next.config.js

async rewrites() {
    return [
      {
        source: '/rewrites',
        destination: '/list',
      }
    ]
  },
复制代码

首先,明确的是我们的路由系统没有 /rewrites 这个路由,有的是 /list,通过 Rewrites 把 /rewrites 重写成了 /list 对应的页面,来看一下效果:

2021-08-24 17.11.14.gif

可以非常清楚地看到,我们访问一个路由系统里不存在的页面 /rewrites,原本应该是 404,但是因为我们对它进行了重写,所以最后呈现出来的是 /list 路由对应的页面。

Rewrites 和 Redirects 有什么区别呢?

那么,看起来 Rewrites 和 Redirects 这俩兄弟功能做的事差不多啊,那么为啥还要做两个功能呢?这俩到底有啥区别呢?别着急,下面就来简单分析一下:

  • 表现形式不同

仔细看上面两个 Demo 截图的效果,Redirects 和 Rewrites 从表现形式上来看有两点不同。

1 - 第一点:路径呈现效果不同,Redirects 呈现的是 destination 也就是目标路径,而 Rewrites 呈现的是 source 也就是元路径。

2 - 第二点:页面实际效果不同,Redirects 呈现的是一个类似刷新页面或者说 <a /> 标签的一个效果,看起来像脱离了站点,而 Rewrites 呈现的就是一个站内前端路由的一个效果,没有刷新跳转的过程。

如果截图效果没看出来,大家可以自己亲自动手实践一下。

  • 编译时调用时机不同

Redirects 是在检查整个文件系统 pagespublic 之前调用。

Rewrites 是在检查整个文件系统 pagespublic 之后且在生成动态路由之前,进行调用。

上面这两句话可能看不太懂,没关系,我们还是通过代码来看看:

// next.config.js

 async redirects() {
   return [
     {
       source: '/home',
       destination: '/',
       permanent: true,
     },
     {
       source: '/rewrites',
       destination: '/list',
       permanent: true,
     }
   ]
 },
 async rewrites() {
   return [
     {
       source: '/rewrites',
       destination: '/list',
     }
   ]
 },
复制代码

可以看到,我们在 Redirects 和 Rewrites 都做了差不多的处理,在 Redirects 里我们把 /rewrites 重定向到 /list,在 Rewrites 里我们把 /rewrites 重写成 /list,那么通过最后页面的实际展现效果,我们也能知道二者的执行顺序,如果最后页面是 /list,那么就说明 Redirects 是后调用的,如果最后页面是 /rewrites 那么说明 Rewrites 是后调用的。

2021-08-24 17.11.14.gif

最后的效果和上面总结的一样,说明 Redirects 是先被调用的,而 rewrites 是后被调用的,所以总结来说,虽然二者有很多相似的地方,但是存在着本质上的不同,所以还是两个 API,需要根据场景去使用。

III - Next.js Preview Mode —— 预览模式

【版本】: >= Next.js Version 9.3

【功能】: 针对 CMS 网站,做一些草稿提前预览的功能。

【解释】: 预览模式允许开发人员在将静态生成的内容发布到 Web 之前查看它的草稿。Next.js 能够在请求时间而不是构建时间生成这些草稿页面,以便开发人员可以看到他们的内容在发布时的样子。

预览模式的应用场景在平时开发过程中基本没怎么使用过,所以这里不做过多介绍,如果你恰好有类似的场景,比如 CMS,那么可以去官网查阅相关内容。对的没错就是这么随意,个人感觉应用场景不足,也没怎么使用过,介绍下来也不过是浪费时间,还不如去官网。

IV - Hooking into Build Process —— 构建过程钩子

Next.js 是一个约定大于配置的框架,大部分的通用的基础功能 Next.js 框架本身已经帮开发者预置好了一套便捷可用方案,与此同时,如果你还是需要在构建时做一些额外的工作的话,那么 Next.js 也是支持的,它为开发者开了一个口子 —— next.config.js,在里面我们可以做诸如:Webpack 配置创建站点地图等。关于配置的详细信息,可以在此查看 -> next.config.js 文档

V - Next.js with Preact

众所周知,Next.js 是基于 React.js 的框架,但是其实 React.js 框架本身并不算轻量,如果你并不去及时的使用 React.js 的高级功能,只是使用 React.js 开发模式以及语法,那么 Next.js 支持将 React.js 切换成 Preact.js 来减小体积。

示例代码

 "dependencies": {
    "next": "11.1.0",
    "preact": "^10.5.14",
    "preact-render-to-string": "^5.1.19",
    "react": "17.0.2",
    "react-dom": "17.0.2"
 },
复制代码
// next.config.js

 webpack: (config, { dev }) => {
    // Replace React with Preact only in client production build
    if (!dev) {
      Object.assign(config.resolve.alias, {
        react: 'preact/compat',
        'react-dom/test-utils': 'preact/test-utils',
        'react-dom': 'preact/compat'
      });
    }

    return config;
 }
复制代码

通过非常简单的配置,就可以完成 Preact 无缝替换 React,并且我们只需要在生产环境开启替换,所以也避免了开发过程就需要我们去熟悉掌握 Preact 相关知识这一问题,接着来直观对比一下二者的打包体积:

  • React

image.png

  • Preact

image.png

相同项目,核心 js 文件使用 React.js 比 Preact.js 单文件普遍大上 30 Kb 左右,当路由系统多了以后,几十个几百个页面,这个体积上的缩小还是十分可观的。

总结

由于十点一起说完内容过多怕大家不容易消化,所以剩下的五点在下一篇文章给大家介绍,剩下的五点更加的有趣,敬请期待~

项目地址

文章分类
前端
文章标签