基础知识

1、从js到react

1、nextjs所处的位置

next.js的位置

2、命令式编程和声明式编程

命令式编程和声明式编程

3、函数组件和类组件的选择

函数组件和类组件的选择

4、在react中,组件是函数。

5、react组件应该大写。

6、在jsx中使用变量,用{}包裹。

2、从react到next.js

......

3、next.js的工作流程

Next.js简化代码转换和底层基础设施,以便更容易地将应用程序投入生产环境。这得益于Next.js内置的基于Rust编写的编译器和SWC平台。

SWC(Speedy Web Compiler)是一个用于JavaScript/TypeScript的高性能源代码转换器。它是用Rust编写的,这是一种低级编程语言,因此它在性能方面非常出色。SWC可以用于编译、压缩、打包等任务。

Next.js选择使用SWC,因为它提供了比传统的Babel和Webpack更高的性能。通过使用SWC,Next.js能够更快地进行开发构建和生产构建,从而提高开发人员的工作效率。

总之,这段文字解释了Next.js如何利用基于Rust编写的编译器和SWC平台简化代码转换和底层基础设施,使得将应用程序投入生产环境更加容易。SWC是一个高性能的源代码转换器,用于JavaScript/TypeScript的编译、压缩和打包等任务。

1、编译(compiling)

将jsx、ts、记忆js的现代化版本,编译为浏览器能理解的js代码。

2、简化(minifying)

简化是在不改变代码功能的情况下删除不必要的代码格式和注释的过程。目标是通过减少文件大小来提高应用程序的性能。

3、打包(bundling)

打包

Next.js 是一个基于 Webpack 的框架,它在内部进行了优化以支持更高效的代码分割和加载。Next.js 自动为每个页面生成一个独立的 JavaScript 和 CSS 文件。这意味着,当用户访问一个页面时,只有所需的代码才会被加载。这有助于提高性能,尤其是对于大型应用。

所以,虽然 Webpack 默认会将所有的组件整合为一个 js 和一个 css 文件,但实际上,在生产环境中,为了获得更好的性能,通常会使用代码分割来创建多个较小的文件。Next.js 已经内置了这些优化功能。

4、next.js工作流程

  • 代码分割

代码分割

代码分割是一种将代码拆分为较小的独立文件(通常称为“chunks”或“bundles”)的技术。这种方法能够显著提高应用程序的性能,特别是对于较大的应用程序。通过代码分割,你可以按需加载所需的代码,而不是一次性加载整个应用程序。

Next.js 默认支持代码分割。在 Next.js 中,代码分割主要依赖于页面和动态导入。

  1. 页面:Next.js 使用文件系统基于页面的路由。每个位于 pages 目录下的文件(除了_app.js_document.js_error.js等特殊文件)都会被视为一个独立的页面。Next.js 会自动为每个页面生成一个单独的 JavaScript 和 CSS 文件。这样,当用户访问一个页面时,只有这个页面所需的代码才会被加载,而不是整个应用程序的代码。
  2. 动态导入:除了基于页面的代码分割之外,Next.js 还支持动态导入。动态导入允许你在运行时按需加载模块。这意味着,只有在需要时,这些模块才会被加载和执行。要使用动态导入,你可以使用 import() 函数。

5、next.js中的渲染

  • 服务器端渲染
  • 客户端渲染
  • 静态站点生成

服务器端渲染和静态生成被称为预渲染。

6、客户端渲染 vs 预渲染

客户端渲染

预渲染

7、react中的hydrate 描述的是 ReactDOM 复用 ReactDOMServer 服务端渲染的内容时尽可能保留结构,并补充事件绑定等 Client 特有内容的过程。

react中的hydration

Next.js学习笔记1

1、创建第一个应用

npx create-next-app@latest nextjs-blog --use-npm --example "https://github.com/vercel/next-learn/tree/master/basics/learn-starter"
cd nextjs-blog
npm run dev

# 创建nextjs项目
# 文档:https://nextjs.org/docs/pages/api-reference/create-next-app
pnpm create next-app

2、在页面之间导航

1、页面基于文件名与路由关联。

2、next.js中创建不同页面的方法:在page目录下创建一个js文件,文件的路径就变成了URL路径。

3、next.js中link组件的使用

import Link from 'next/link'

<Link href=""></Link>

注:在next.js 12.2以前,Link组件需要包装标签,但是在12.2及以上版本中不需要这样做。

4、<Link>组件的优势

当使用Next.js的<Link>组件时,浏览器不会加载整个页面,而是进行客户端导航。这说明<Link>子组件的一个主要优势是支持部分刷新(Partial Refresh)。

在传统的网页导航中,当用户点击一个链接时,浏览器会请求并加载整个新页面。这种方式可能会导致页面加载速度变慢,影响用户体验。而Next.js的<Link>组件通过实现客户端导航,避免了这种情况。客户端导航意味着只有当前页面发生变化的部分会被更新,而不是整个页面。这样可以提高页面加载速度,提升用户体验。

5、代码分割和预加载

Next.js的两个主要优点:代码分割(Code Splitting)和预加载(Prefetching)。这些优点有助于提高网站的性能和用户体验。

  1. 代码分割(Code Splitting):Next.js会自动对代码进行分割,这样每个页面只加载所需的代码。这意味着在渲染主页时,其他页面的代码不会被加载。即使网站拥有数百个页面,主页的加载速度也能得到保证。此外,代码分割还使页面之间相互隔离,如果某个页面出现错误,其他页面仍能正常工作。
  2. 预加载(Prefetching):在Next.js的生产环境中,当<Link>组件出现在浏览器视口中时,Next.js会自动在后台预加载链接页面的代码。这样当用户点击链接时,目标页面的代码已经在后台加载完成,页面切换将非常迅速。

注:如果要链接一个next.js应用程序之外的一个外部页面,使用<a>标签,而不是<Link>组件。

6、总结

Next.js通过代码分割(Code Splitting)、客户端导航(Client-side Navigation)和预加载(Prefetching,在生产环境中)来实现最佳性能。

在Next.js中,你可以通过在pages目录下创建文件来设置路由,同时使用内置的Link组件进行导航,无需额外的路由库。

3、静态资源、元数据以及CSS

1、Image组件

  1. next/image是HTML <img>元素的扩展,为现代Web环境而设计。它提供了更多特性和优化,使得图像处理在Next.js项目中更加高效和便捷。
  2. Next.js默认支持图像优化。这包括调整图像尺寸、优化图像质量以及在浏览器支持的情况下,使用现代格式(如WebP)呈现图像。这样可以避免向小视口设备发送过大的图像,提高加载速度。此外,Next.js还能自动适应未来的图像格式,并为支持这些格式的浏览器提供服务。
  3. 自动图像优化功能支持任何图像源。即使图像托管在外部数据源(如CMS)上,Next.js仍然可以对其进行优化。

2、Image组件的优势

  1. 按需优化:Next.js在用户请求图像时进行优化,而不是在构建时。这与静态站点生成器和静态解决方案不同,Next.js不会因为处理大量图像而增加构建时间,无论是10张图像还是1000万张图像。
  2. 默认懒加载:Next.js默认对图像进行懒加载。这意味着页面速度不会因为视口之外的图像而受到影响。当用户滚动到图像所在位置时,图像才会加载。
  3. 避免累积布局偏移(Cumulative Layout Shift):Next.js渲染图像的方式能有效避免累积布局偏移,这是一个关键的网络性能指标(Core Web Vital),Google将在搜索排名中使用这一指标。通过避免累积布局偏移,Next.js能够提供更好的页面稳定性和用户体验。

综上,这段话强调了Next.js中Image组件的灵活性和优势,如按需优化、懒加载和避免累积布局偏移,这些特性有助于提高网站性能和用户体验。

3、<Head>是一个构建在next.js中的react组件,它允许你修改页面的<head>

4、Script组件会在获取和加载外部脚本的时候,对其进行优化。

import Script from 'next/script'

<Script src="" strategy="" onload={} />

优势:

<Script>组件的优势

5、<Layout>组件

注:要使用css模块,css文件名必须以.module.css结尾。

css模块会自动生成唯一的类型,只要使用css模块,就不必担心类型冲突。此外,Next.js 的代码分割特性也适用于 CSS 模块。它确保为每个页面加载最少量的 CSS。这将导致更小的捆绑包大小。

6、全局css文件在pages/_app.js中导入。

7、添加tailwind css。via

npm install -D tailwindcss autoprefixer postcss

8、postcss和tailwind css之间的关系

postcss和tailwind css之间的关系

4、预渲染和数据获取

1、预渲染

默认情况下,Next.js会为每个页面进行预渲染。这意味着Next.js会提前为每个页面生成HTML,而不是将所有工作都交给客户端JavaScript来完成。预渲染可以带来更好的性能和SEO优化。

每个生成的HTML都与该页面所需的最小JavaScript代码相关联。当浏览器加载页面时,它的JavaScript代码会运行,使页面完全互动。这个过程被称为“hydration”。

总结一下,Next.js中的预渲染是指在服务器端提前生成页面的HTML,而不是依赖客户端JavaScript来生成。预渲染有助于提高性能和SEO。生成的HTML和最小化的JavaScript代码一起工作,使页面在浏览器中加载并变得完全互动。这个过程被称为hydration。

2、和没有预渲染功能的react app比较

和没有预渲染功能的react app比较

3、预渲染的好处

  • 改善SEO
  • 允许你的应用可以在没有js的情况下工作

解释说明:

预渲染好处的解释

4、为什么浏览器中禁用js,next.js应用的css不会加载,此时js会加载吗?

为什么浏览器中禁用js,next.js应用的css不会加载,此时js会加载吗?

5、预渲染的两种形式

  • 静态生成
  • 服务器端渲染

预渲染的两种形式

注:

在开发模式下(当您运行 npm run dev 或纱线 dev 时) ,每个请求都会预先呈现页面。这也适用于静态生成,以使其更容易开发。进入生产环境时,静态生成只会在构建时发生一次,而不是在每个请求上发生。

6、什么时候使用静态生成?什么时候采用服务器端渲染?via

image-20230318163928211

7、有数据和无数据的静态生成

Static Generation without Data

Static Generation with Data

8、使用getStaticProps异步函数来进行有数据的静态生成。

9、解析md文件中front matter所用到的库gray-matter安装

npm install gray-matter

10、开发环境和生产环境中的getStaticProps

  • 在开发环境中,getStaticProps在每个请求上运行
  • 在生产环境中,getStaticProps在构建时运行

11、在Next.js应用程序中,你不需要单独导入 fetch() 函数,因为Next.js已经在客户端和服务器端为你提供了这个函数的实现(polyfill)。换句话说,你可以直接使用 fetch() 函数进行HTTP请求,而无需担心兼容性问题。

12、getStaticProps只能从一个页面导出,不能从非页面文件导出,这样限制的原因之一是,React需要在呈现页面之前拥有所有必需的数据。

13、需要在请求时获取数据,需要使用服务器端渲染。静态生成在构建时发生一次,所以它不适合更新频繁的数据或在每个用户请求上进行更改的数据。

14、服务器端渲染

服务器端渲染

15、静态生成+客户端渲染

静态生成+客户端渲染

5、动态路由

1、页面路径取决于外部数据

页面路径取决于外部数据

2、静态生成含有动态路径的页面

静态生成含有动态路径的页面

3、渲染markdown,使用remark库。

npm install remark remark-html

4、格式化日期,使用date-fns库或者使用dayjs库。

npm install date-fns
或者
npm install dayjs

5、getStaticPaths函数

在Next.js中,getStaticPaths函数用于预渲染静态页面。这意味着在构建时生成HTML文件,以便在运行时直接发送给用户。在Next.js中,开发环境和生产环境的行为略有不同。下面是关于两者差异的解释。

  • 开发环境

当您使用npm run devyarn dev命令在开发模式下运行应用程序时,getStaticPaths将在每次请求时运行。这意味着,当您访问一个静态生成的页面时,getStaticPaths会重新生成可用路径,以便您在开发过程中查看最新的更改。这在开发过程中非常有用,因为您可以立即看到对静态页面的任何更改,而无需重新构建整个应用程序。

  • 生产环境

在生产环境中,getStaticPaths在构建时运行。这意味着,当您使用npm run buildyarn build命令构建应用程序时,getStaticPaths会生成静态页面的所有可用路径。在生产环境中,预渲染的静态页面会被缓存,以便在运行时快速发送给用户,从而提高性能。

这种差异的主要原因是,在开发过程中,我们希望实时查看更改,而在生产环境中,我们希望尽可能快地向用户提供内容。通过在开发环境中实时生成路径并在生产环境中缓存预渲染的页面,Next.js为开发人员提供了更好的开发体验,同时在生产环境中为用户提供了更快的性能。

6、getStaticPaths函数的fallback属性

getStaticPaths函数的fallback属性

6、API路由

不应该在getStaticPropsgetStaticPaths中调用API路由。相反,你应该直接在getStaticPropsgetStaticPaths中编写服务器端代码(或调用辅助函数)。

原因如下:

  1. getStaticPropsgetStaticPaths仅在服务器端运行,永远不会在客户端运行。这意味着你可以在这些函数中编写仅在服务器上执行的代码。
  2. 由于这些函数不会包含在浏览器的JS包中,因此你可以编写诸如直接数据库查询的代码,而无需将它们发送到浏览器。这有助于保护敏感信息和减小浏览器中加载的代码量。

因此,在编写Next.js应用程序时,确保在getStaticPropsgetStaticPaths中直接编写服务器端代码,而不是调用API路由。这样,你可以充分利用服务器端渲染的优势,同时保持代码更简洁、更安全。

7、部署应用

1、DPS web开发流程

DPS web开发流程

Next.js学习笔记2

1、搜索引擎优化简介

1、SEO重要的原因

  1. 质量:访问者变成客户的概率增加。
  2. 可信度:对品牌或使命的信任度更高。
  3. 低成本:除了投入的时间和精力外,良好的SEO实践可以提高搜索引擎排名,且无需直接成本。在顶部自然搜索结果中出现无需额外费用。

2、优化的三大支柱

网站优化过程可以分为三个主要支柱:

  1. 技术:优化网站以实现爬虫和Web性能的提升。
  2. 创作:创建针对特定关键词的内容策略。
  3. 知名度:通过使用反向链接(指向你的网站的第三方站点)提高网站在线知名度,让搜索引擎知道你是可信赖的来源。

3、谷歌机器人索引网页的流程

谷歌机器人索引网页的流程

2、爬取和索引

1、next.js中永久重定向使用的状态码默认是308,而不是301,因为它是较新的版本,并被认为是更好的选择。

301和308状态之间的区别是:301状态码允许将POST更改为GET,而308状态码不允许。

301 vs 308

nginx中原本http301重定向至https,是否需要更改为308重定向?

nginx中原本http301重定向至https,是否需要更改为308重定向?

2、sitemap.xml

根据Google的说法,您可能需要一个站点地图,原因如下:

  1. 网站非常大。因此,Google网络爬虫可能会忽略抓取您的一些新的或最近更新的页面。
  2. 网站有大量内容页面存档,这些页面相互之间隔离或链接不够紧密。如果您的网站页面不自然地相互引用,您可以在站点地图中列出它们,以确保Google不会忽略其中的一些页面。
  3. 网站是新的,并且很少有外部链接。Googlebot和其他网络爬虫通过从一个页面跟踪到另一个页面的链接来浏览网络。因此,如果没有其他网站链接到它们,Google可能不会发现您的页面。
  4. 网站包含大量的富媒体内容(视频、图片)或显示在Google新闻中。如果提供站点地图,Google可以在适当的情况下为搜索考虑更多的信息。

虽然站点地图对于优秀的搜索引擎性能并非强制性的,但它们可以方便爬虫抓取和索引,从而使您的内容更快地被发现并获得相应的排名。

强烈建议使用站点地图,并在网站中添加新内容时使它们动态更新。静态站点地图也是有效的,但对于Google来说,它们在持续发现方面可能不太有用。

对于个人博客系统,我推荐使用 getStaticProps 生成站点地图。这是因为个人博客通常内容更新频率较低,而且 Next.js 提供了非常棒的静态生成能力。这样一来,站点地图只会在构建时生成,避免了每次请求时重新生成,从而提高了性能。

3、元标签

vercel学习笔记

1、Vercel strongly connects to the words versatile(功能多样), accelerate(速度飞快), and excel(追求卓越).

补充知识

1、nextjs默认的编译器采用的是webpack5。

2、使用mdx

  npm install @next/mdx @mdx-js/loader @mdx-js/react
  
  const withMDX = require('@next/mdx')({
  extension: /\.mdx?$/,
  options: {
    remarkPlugins: [],
    rehypePlugins: [],
  },
});

const nextConfig = {
  pageExtensions: ['ts', 'tsx', 'js', 'jsx', 'md', 'mdx'],
  reactStrictMode: true,
  async rewrites() {
    return [
      {
        source: '/sitemap.xml',
        destination: '/api/sitemap',
      },
    ];
  },
  webpack: (config) => {
    config.resolve.fallback = { fs: false };
    return config;
  },
};

module.exports = withMDX(nextConfig);

3、import导入顺序规范

在Next.js和其他JavaScript项目中,没有严格的导入顺序规定。但是,遵循一些通用的导入顺序规范可以使代码更加整洁和易于阅读。以下是一种推荐的导入顺序:

  1. 第三方库和框架(如react, next, styled-components等)
  2. 组件(如Layout, Date等)
  3. 工具和辅助函数(如getSortedPostsData
  4. 常量和配置文件
  5. 样式文件(如CSS或Sass模块)

4、什么时候在next.js项目中使用import React from 'react'

-Importing react into pages in next.js (and also React and CRA apps

5、从 Next.js 12 开始,支持使用 ES modules 语法编写配置文件 next.config.js,只需要将其改名为 next.config.mjs 即可。在之前的版本中,只支持使用 CommonJS 语法编写配置文件。

6、next.js中的_app.js_document.js的区别与联系

chatgpt总结的_document.js和_app.js的区别与联系

7、可视化报告

# 安装@next/bundle-analyzer
pnpm add @next/bundle-analyzer

# 在next.config.mjs中进行相关的配置

# 运行Bundle Analyzer
# 生成交互式的可视化报告展示了你的Next.js应用的bundle大小和构成。
ANALYZE=true npm run build

next.config.mjs中的相关配置

import remarkGfm from 'remark-gfm';
import createMDX from '@next/mdx';
import NextBundleAnalyzer from '@next/bundle-analyzer';

const withMDX = createMDX({
    extension: /\.mdx?$/,
    options: {
        remarkPlugins: [remarkGfm],
        rehypePlugins: [],
    },
});

// 添加这一行来配置NextBundleAnalyzer
const withBundleAnalyzer = NextBundleAnalyzer({
    enabled: process.env.ANALYZE === 'true',
});

export default withBundleAnalyzer(
    withMDX({
        pageExtensions: ['ts', 'tsx', 'js', 'jsx', 'md', 'mdx'],
        reactStrictMode: true,
        async rewrites() {
            return [
                {
                    source: '/sitemap.xml',
                    destination: '/api/sitemap',
                },
            ];
        },
        webpack: (config) => {
            config.resolve.fallback = { fs: false };
            return config;
        },
    })
);

8、纪录片

知识回顾

1、getStaticPathsgetStaticProps函数的作用

getStaticPropsgetStaticPaths是Next.js中特定的函数,它们用于静态生成页面。在构建时,Next.js将使用这些函数预渲染页面,从而提高页面加载速度和性能。

  • getStaticProps: 此函数在构建时运行,用于获取页面所需的数据。这意味着它将从外部数据源(如API、数据库或文件系统)获取数据,并将这些数据作为props传递给页面组件。这允许您在构建过程中生成页面,以便在部署时提供完全渲染的HTML。

getStaticProps应该导出一个异步函数,该函数返回一个对象,该对象包含一个名为props的属性。props属性应包含一个对象,其中包含所有要传递给页面组件的属性。

  • getStaticPaths: 对于动态路由页面,getStaticPaths允许您指定哪些参数组合应该在构建时生成。在构建时,Next.js将使用这些参数组合为每个动态路由生成静态页面。

getStaticPaths应该导出一个异步函数,该函数返回一个对象,该对象包含一个名为paths的属性。paths属性应包含一个对象数组,每个对象表示一个动态路由的参数组合。还可以包含一个名为fallback的属性,它可以设置为falsetrue'blocking',以决定如何处理未在paths中指定的路由。

常见问题

1、Module not found: Can't resolve 'fs'

# 在next.config.js文件中添加以下配置
  webpack: (config) => {
    config.resolve.fallback = { fs: false };

    return config;
  },

在Next.js应用中,当您尝试在客户端代码中使用fs(文件系统)模块时,会遇到“module not found”错误。这是因为fs模块是Node.js的内置模块,仅在服务器端环境中可用。在客户端浏览器环境中,fs模块不可用,因此Next.js在编译客户端代码时会抛出错误。

要解决这个问题,您可以在next.config.js中修改Webpack配置,将fs模块设置为false,以告知Webpack不要尝试在客户端代码中解析fs模块。这样,Webpack就会将fs模块的所有引用替换为一个空对象,从而避免了模块未找到的错误。

需要注意的是,这种方法仅解决了客户端代码中的“module not found”错误。您仍然需要确保不在客户端代码中使用fs模块的任何功能。为了避免在客户端代码中使用fs模块,您应该将fs模块的使用限制在服务器端代码中,例如在getStaticPropsgetServerSideProps函数中。

2、使用remark库将md或者mdx文件转换为html时,代码块高亮、引用快、表格语法失效的解决办法

  • 代码块高亮使用remark-prism
# 安装remark-prism库
npm i remark-prism
  • 在lib/posts/index.js中导入remark-prism库,并使用该库来给转换
import prism from 'remark-prism';

  const processedContent = await remark()
    .use(gfm)
    .use(html, { sanitize: false })
    .use(prism)
    .process(matterResult.content);
  const contentHtml = processedContent.toString();

3、使用remark库将markdown文件内容转为html形式,<转换为了&lt;>转化为了&gt;如何解决?

解决方案:

npm i remark remark-html remark-gfm remark-prism unist-util-visit

remark 是一个处理 Markdown 的库,它将 Markdown 文本转换为一个抽象语法树(AST)。抽象语法树是一种表示源代码结构的树形数据结构。在这种情况下,remark 生成了一个表示 Markdown 源代码结构的树。

自定义的 restoreSpecialCharacters 插件会对这个抽象语法树进行操作。remark 在将 Markdown 转换为 HTML 之前,会先将其转换为 AST。您的插件会在转换过程中对文本节点执行操作,还原尖括号、单引号和双引号。因此,您的插件实际上是在操作 Markdown 和 HTML 之间的转换过程产生的抽象语法树。这确保了最终生成的 HTML 中的特殊字符(尖括号、单引号和双引号)正常显示。

可以见这些issue

4、tailwind css只支持CommonJS,目前还不支持ESM。I have content declared but getting "The content option in your Tailwind CSS configuration is missing or empty" #8029

image-20230322154510491

5、mjs、js、Common JS、ESM