1. Next.js

Next.js 是一个使用 React 构建单页应用程序(SPA)的开源 JavaScript 框架。它使得构建服务端渲染(SSR)和静态网站生成(SSG)的 React 应用程序变得简单和高效。Next.js 由 Vercel(原 Zeit)公司开发,并且自推出以来得到了广泛的关注和使用。

Next.js 提供了一系列的特性和优势,包括但不限于:

  1. 服务端渲染(SSR):每次页面请求时,都在服务器上实时渲染页面,这有助于提高首屏加载速度并改善搜索引擎优化(SEO)。

  2. 静态网站生成(SSG):在构建时生成静态的 HTML 页面,可以部署到任何静态网站托管服务上,进一步提高性能和扩展性。

  3. 文件系统路由:Next.js 通过 /pages 目录中的文件结构自动创建路由,每个 React 组件文件对应一个路由。

  4. 自动代码拆分:Next.js 会自动对每个页面进行代码拆分,只加载当前页面所需的代码,这有助于减少页面的加载时间。

  5. API 路由:可以在 /pages/api 目录下创建 API 路由,方便构建 API 接口。

  6. 内置 CSS 和 Sass 支持:Next.js 支持 CSS Modules,并内置了对 CSS-in-JS 库的支持,同时也支持预处理器如 Sass。

  7. 开箱即用的 TypeScript 支持:Next.js 提供了对 TypeScript 的内置支持,无需额外的配置。

  8. 插件生态系统:社区提供了大量的 Next.js 插件,可以很容易地扩展应用的功能。

Next.js 的开发体验通常被认为是它的主要优点之一,因为它简化了许多传统上需要手动配置的部分,例如路由和代码拆分。这使得开发者可以专注于编写应用逻辑,而不是花费过多时间在构建配置上。由于其灵活性和性能,Next.js 已经被许多企业用于构建生产级的网站和应用。

2. 诞生背景

首次发布于 2016 年。它的诞生背景是基于开发者和企业对构建更快、更优化的 Web 应用程序的需求,特别是在服务端渲染(SSR)和搜索引擎优化(SEO)方面。React 本身是一个客户端渲染的库,这意味着 JavaScript 需要在用户的浏览器中运行才能生成 HTML 内容。这种模式在用户体验和性能上存在一些挑战,尤其是对首屏加载时间和 SEO 不友好。

Next.js 主要解决了以下问题:

  1. SEO 和首屏加载性能: 传统的客户端渲染的 React 应用可能不利于搜索引擎爬虫的抓取,且首次加载时间较长。Next.js 提供服务端渲染作为默认行为,这意味着页面在服务器上被渲染为 HTML,然后发送给客户端。这样做可以显著提升首屏加载速度,并对搜索引擎优化友好。

  2. 开发效率: 在使用 React 开发大型应用时,开发者通常需要配置路由、代码拆分、构建优化等。Next.js 通过约定大于配置的方式,减少了这些常见任务的手动设置,提供了简易的文件系统路由、自动的代码拆分和热加载,提高了开发效率。

  3. 构建和部署: Next.js 提供现成的构建系统和对持续集成的优化,使得将应用从开发阶段迁移到生产变得简单。此外,与 Vercel 平台的无缝集成也让部署变得异常轻松。

  4. 灵活的数据获取策略: Next.js 提供了灵活的数据获取方法,如 getStaticPropsgetServerSideProps,使得开发者可以根据页面的需求选择不同的数据预渲染策略,例如静态生成或服务器端渲染。

  5. 无需额外设置的 TypeScript 支持: Next.js 从一开始就考虑了对 TypeScript 的支持,让开发者能够享受到强类型语言带来的好处,而无需复杂的配置。

  6. API 路由: Next.js 允许开发者在同一个项目中构建前端页面和 API 接口,简化了全栈应用的开发过程。

  7. 生态系统和社区支持: Next.js 随着时间的推移建立起了一个健康的插件生态系统,并且得到了强大的社区支持,这为开发者提供了各种资源和第三方库的集成。

总之,Next.js 的出现是为了简化和优化基于 React 的应用开发流程,同时提供了高性能和 SEO 友好的解决方案,它代表了当代 Web 应用开发的一个重要趋势。

3. 安装

安装 Next.js 非常简单,主要有两种方式:使用 create-next-app 脚手架来创建新项目,或者手动添加到现有的 React 项目中。以下是安装 Next.js 的步骤:

使用 create-next-app 创建新项目

  1. 使用 npxnpm 的包执行工具)执行以下命令来创建一个新的 Next.js 应用。这会自动下载 create-next-app 并创建一个新的项目。

npx create-next-app my-next-app

  1. 进入项目目录:

cd my-next-app

  1. 启动开发服务器:

npm run dev

或者,如果你使用的是 yarn

yarn dev

这样,你的 Next.js 应用就会在 localhost:3000 上启动,你可以在浏览器中访问它。

手动添加到现有的 React 项目

如果你已经有一个 React 项目,你可以通过安装以下几个包来将其转换为 Next.js 项目:

npm install next react react-dom

或者,如果你使用 yarn

yarn add next react react-dom

之后,你需要在 package.json 中添加几个脚本来启动 Next.js:

"scripts": {
  "dev": "next",
  "build": "next build",
  "start": "next start"
}

Next.js 的基本目录和工作结构

Next.js 有一个约定优于配置的原则,这意味着项目的基本目录结构和工作方式已经被预设好了。以下是 Next.js 应用的常见目录结构:

my-next-app/
|
|   |
|   |
|   `
|
|
|
|
|
`

  • pages/:这是存放页面组件的目录,每个文件都会自动对应一个路由。例如,pages/about.js 会对应 /about 这个路由。

  • public/:用于存放静态资源,如图片、字体等,这些文件可以直接通过 / 路径在浏览器中访问。

  • styles/:保存 CSS 文件的地方,你可以根据需要组织你的样式文件。

  • node_modules/:存放所有安装的依赖包。

  • package.json:定义了项目的依赖和可运行的脚本。

  • next.config.js:可选的配置文件,用于自定义 Next.js 的高级配置,比如添加环境变量、修改构建的 Webpack 配置等。

通过这种目录结构,Next.js 提供了一个强大且灵活的框架,允许开发者迅速启动项目并按需进行扩展。

最小工作流程

  1. pages/index.tsxpages/index.js 这是 Next.js 应用程序的默认入口页面,也就是访问站点根 URL(如 http://localhost:3000/)时加载的页面。使用 TypeScript 编写时后缀为 .tsx,纯 JavaScript 时为 .js

  2. pages/_app.tsxpages/_app.js 这是 Next.js 中的一个特殊文件,它允许你初始化所有页面。你可以使用这个文件来保持页面布局,保持状态(如 Redux 或 MobX)时使用,或者用于全局 CSS 的插入。这个文件是可选的,如果你的应用不需要全局初始化,则不需要创建它。

  3. pages/_document.tsxpages/_document.js _document 也是一个特殊文件,用于自定义文档结构。Next.js 会使用这个文件来渲染网站的 HTML 结构。默认情况下,Next.js 为你生成文档结构,但如果你需要自定义 <html><body> 标签或在 <head> 中添加额外的链接和脚本,你可以通过创建 _document 文件来实现。这个文件也是可选的,只有在需要自定义整个 HTML 页面结构时才需要它。

  4. app/layout.tsxapp/layout.js layout 文件并不是 Next.js 的特定组件或约定。但在开发过程中,通常会创建一个 Layout 组件来封装页面结构,比如包含导航栏和页脚的共享布局。此组件可以在不同页面中复用,以便保持一致的外观和行为。通常,开发者会根据项目需要自行创建和组织 Layout 组件。

  5. app/page.tsxapp/page.js 这同样不是 Next.js 的特定组件或约定。它可能是开发者根据项目需要自定义的一个组件或页面逻辑。在实际的 Next.js 项目中,你可能不会看到这个文件,除非团队有特定的组织结构或命名习惯。

工作流程如下:

  • 当用户访问网站时,Next.js 会根据请求的路径查找 pages 目录中相应的页面组件。

  • 如果存在 _app 文件,Next.js 会使用它来初始化所有页面,你可以在这里插入全局样式或共享组件。

  • 如果存在 _document 文件,Next.js 会使用它来构建 HTML 文档结构。这只会在服务器端渲染时发生,且仅用于初始页面加载。

  • 如果你使用了 Layout 组件,通常会在 _app 文件中引入并包裹页面内容,从而为你的页面提供统一的布局。

在实际的 Next.js 应用中,你可能会根据实际的需要添加或省略这些文件。例如,对于一个简单的项目,你可能只需要 pages/index.tsx 文件。对于复杂一点的项目,可能会加入 _app.tsx_document.tsx 来进行全局布局和文档结构的自定义。其他如 app/layout.tsxapp/page.tsx 这样的文件则更多取决于你个人或团队的项目结构和组件组织方式。

4. 目录结构

本页面提供了 Next.js 应用程序的项目结构概览。它涵盖了顶层文件和文件夹、配置文件,以及在 apppages 目录内的路由约定。

点击文件和文件夹名称以了解每个约定的更多信息。

顶层文件夹

顶层文件夹用于组织应用程序的代码和静态资源。

  • app - 应用路由器

  • pages - 页面路由器

  • public - 将要提供服务的静态资源

  • src - 可选的应用源代码文件夹

顶层文件

顶层文件用于配置应用程序,管理依赖项,运行中间件,集成监控工具,以及定义环境变量。

Next.js
  • next.config.js - Next.js 的配置文件

  • package.json - 项目依赖和脚本

  • instrumentation.ts - OpenTelemetry 和检测文件

  • middleware.ts - Next.js 请求中间件

  • .env - 环境变量

  • .env.local - 本地环境变量

  • .env.production - 生产环境变量

  • .env.development - 开发环境变量

  • .eslintrc.json - ESLint 的配置文件

  • .gitignore - Git 忽略的文件和文件夹

  • next-env.d.ts - Next.js 的 TypeScript 声明文件

  • tsconfig.json - TypeScript 的配置文件

  • jsconfig.json - JavaScript 的配置文件

app 路由约定

以下文件约定用于在应用路由器中定义路由和处理元数据。

路由文件
  • layout .js .jsx .tsx - 布局

  • page .js .jsx .tsx - 页面

  • loading .js .jsx .tsx - 加载 UI

  • not-found .js .jsx .tsx - 未找到页面 UI

  • error .js .jsx .tsx - 错误 UI

  • global-error .js .jsx .tsx - 全球错误 UI

  • route .js .ts - API 端点

  • template .js .jsx .tsx - 重新渲染的布局

  • default .js .jsx .tsx - 平行路由备用页面

嵌套路由
  • folder/ - 路由片段

  • folder/folder/ - 嵌套路由片段

动态路由
  • [folder] - 动态路由片段

  • [...folder] - 捕获所有路由片段

  • [[...folder]] - 可选的捕获所有路由片段

路由组和私有文件夹
  • (folder) - 不影响路由的路由组

  • _folder - 让该文件夹及其所有子片段退出路由

平行路由和拦截路由
  • @folder - 命名插槽

  • (.)folder - 拦截同一层级

  • (..)folder - 拦截上一层级

  • (..)(..)folder - 拦截两层以上

  • (...)folder - 从根部拦截

元数据文件约定
应用图标
  • favicon .ico - 网站图标文件

  • icon .ico .jpg .jpeg .png .svg - 应用图标文件

  • icon .js .ts .tsx - 生成的应用图标

  • apple-icon .jpg .jpeg .png - Apple 应用图标文件

  • apple-icon .js .ts .tsx - 生成的 Apple 应用图标

Open Graph 和 Twitter 图片
  • opengraph-image .jpg .jpeg .png .gif - Open Graph 图片文件

  • opengraph-image .js .ts .tsx - 生成的 Open Graph 图片

  • twitter-image .jpg .jpeg .png .gif - Twitter 图片文件

  • twitter-image .js .ts .tsx - 生成的 Twitter 图片

SEO
  • sitemap .xml - 网站地图文件

  • sitemap .js .ts - 生成的网站地图

  • robots .txt - 机器人文件

  • robots .js .ts - 生成的机器人文件

pages 路由约定

以下文件约定用于在页面路由器中定义路由。

特殊文件
  • _app .js .jsx .tsx - 自定义应用程序

  • _document .js .jsx .tsx - 自定义文档

  • _error .js .jsx .tsx - 自定义错误页面

  • 404 .js .jsx .tsx - 404 错误页面

  • 500 .js .jsx .tsx - 500 错误页面

路由
文件夹约定
  • index .js .jsx .tsx - 主页

  • folder/index .js .jsx .tsx - 嵌套页面

文件约定
  • index .js .jsx .tsx - 主页

  • file .js .jsx .tsx - 页面文件

动态路由
文件夹约定
  • [folder]/index .js .jsx .tsx - 动态路由片段

  • [...folder]/index .js .jsx .tsx - 捕获所有路由片段

  • [[...folder]]/index .js .jsx .tsx - 可选的捕获所有路由片段

文件约定
  • [file] .js .jsx .tsx - 动态路由片段

  • [...file] .js .jsx .tsx - 捕获所有路由片段

  • [[...file]] .js .jsx .tsx - 可选的捕获所有路由片段

5. 路由

Next.js 拥有两种不同的路由器:App Router 和 Pages Router。App Router 是一种较新的路由器,它允许你使用 React 的最新特性,例如服务器组件(Server Components)和流式传输(Streaming)。Pages Router 是原始的 Next.js 路由器,它允许你构建服务端渲染(Server-Rendered)的 React 应用程序,并且继续支持旧版本的 Next.js 应用程序。

pages 路由器(Pages Router)

pages 目录是 Next.js 最初提供的默认路由机制。在这个目录下,文件系统被用作路由器的基础,即每个文件(除了一些特殊的文件如 _app.js_document.js)都会自动映射到一个 URL 路径上。例如:

  • pages/index.js 映射到站点的根 URL (/)。

  • pages/about.js 映射到 /about

  • pages/posts/[id].js 映射到一个动态路由,如 /posts/1

这种方式可以快速创建新页面,并且无需手动配置路由。

app 路由器(App Router)

随着 Next.js 12 的发布,app 路径(目前处于实验阶段)引入了一个新的路由系统,它提供了更灵活的路由定义方式,包括对路由组、布局、加载状态、错误处理和并行路由等的支持。app 目录允许开发者使用文件和文件夹来定义路由,同时也可以用各种新的文件命名约定来控制路由行为。例如:

  • app/page.js 是一个页面。

  • app/layout.js 是一个布局,可以被包含在多个页面中。

  • app/loading.js 定义了加载状态的 UI。

  • app/404.js 提供了一个404错误页面。

  • app/(users)/[id].js 创建了一个路由组。

使用 app 路由器,你可以更细致地控制应用的路由和渲染行为,更好地组织代码逻辑。

6. 示例

6.1 前后端接口声明&调用

当然,这里给出一个使用 Next.js 的示例,展示如何在前端页面与后端 API 接口之间进行调用。

1. 创建后端 API 接口

首先,你需要在 Next.js 的 pages/api 目录下创建一个 API 接口。这将使得 Next.js 为你自动处理 API 路由。例如,创建一个简单的 API 接口来获取用户数据。

pages/api/user.js 文件中:

export default function handler(req, res) {
  
  const user = {
    id: 1,
    name: "John Doe",
    email: "john@example.com",
  };

  
  res.status(200).json(user);
}

2. 前端页面调用 API 接口

接着,在前端页面中调用上述 API。你可以使用 fetch API 或者其他 HTTP 客户端库,如 axios,来进行 API 调用。

pages/index.js 文件中:

import { useEffect, useState } from "react";

export default function Home() {
  const [user, setUser] = useState(null);

  useEffect(() => {
    
    async function fetchUserData() {
      const response = await fetch("/api/user");
      const userData = await response.json();
      setUser(userData);
    }

    fetchUserData();
  }, []); 

  
  return (
    <div>
      <h1>User Profile</h1>
      {user ? (
        <div>
          <p>Name: {user.name}</p>
          <p>Email: {user.email}</p>
        </div>
      ) : (
        <p>Loading...</p>
      )}
    </div>
  );
}

在本例中,当页面加载时,useEffect 钩子会触发,并执行 fetchUserData 函数来获取用户数据。数据被成功获取后,它会更新状态 user,并重新渲染页面以显示用户的信息。如果数据尚未加载完成,则会显示 "Loading..."。

请注意,这里的 API 调用是指向相对路径 /api/user,这是因为 Next.js 会自动处理这个路径到我们在 pages/api/user.js 中定义的 API 接口。

6.2 登录场景

要实现一个完整的登录示例,包括登录后的鉴权、登录态保持和退出机制,在 Next.js 中通常会涉及到 API 路由、Cookies 或者其他存储方式以及前端状态管理。以下是一个简化的示例:

1. 创建登录 API 接口

pages/api/login.js 文件中,我们创建一个处理登录请求的 API:

export default function handler(req, res) {
  if (req.method === "POST") {
    const { username, password } = req.body;

    
    
    if (username && password) {
      
      res.setHeader("Set-Cookie", "token=valid-token; path=/; HttpOnly");
      res.status(200).json({ message: "登录成功" });
    } else {
      
      res.status(401).json({ message: "登录失败" });
    }
  } else {
    
    res.setHeader("Allow", "POST");
    res.status(405).end(`Method ${req.method} Not Allowed`);
  }
}

在上述代码中,我们仅接受 POST 请求,并简单地假设所有的登录尝试都是有效的。在实际应用中,你需要添加真实的身份验证逻辑并安全地处理密码。

2. 创建前端登录页面

在前端,你需要一个表单来收集用户的用户名和密码,然后将这些信息发送到登录 API。

pages/login.js 文件中:

import { useState } from "react";
import Router from "next/router";

export default function Login() {
  const [username, setUsername] = useState("");
  const [password, setPassword] = useState("");

  const handleSubmit = async (event) => {
    event.preventDefault();

    const response = await fetch("/api/login", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ username, password }),
    });

    if (response.ok) {
      
      Router.push("/profile");
    } else {
      
      alert("登录失败");
    }
  };

  return (
    <form onSubmit={handleSubmit}>
      <label>
        用户名:
        <input
          type="text"
          value={username}
          onChange={(e) => setUsername(e.target.value)}
        />
      </label>
      <label>
        密码:
        <input
          type="password"
          value={password}
          onChange={(e) => setPassword(e.target.value)}
        />
      </label>
      <button type="submit">登录</button>
    </form>
  );
}

在这个登录表单中,我们收集用户名和密码,然后将其作为 JSON 发送到登录 API。如果登录成功,我们会重定向用户到受保护的个人资料页面。

3. 登录态保持和退出登录机制

登录状态通常由服务器通过设置 HTTP Cookie 来保持。在上述登录 API 中,我们设置了一个名为 'token' 的 Cookie。你可以在服务器上验证此 Cookie 以确认用户是否登录。

退出登录只需删除或清空 Cookie 即可。创建一个退出 API 接口:

pages/api/logout.js 文件中:

export default function handler(req, res) {
  
  res.setHeader(
    "Set-Cookie",
    "token=; path=/; expires=Thu, 01 Jan 1970 00:00:00 GMT"
  );
  res.status(200).json({ message: "已退出登录" });
}

然后在前端添加一个退出登录的按钮:

import Router from "next/router";

export default function LogoutButton() {
  const handleLogout = async () => {
    const response = await fetch("/api/logout", { method: "POST" });

    if (response.ok) {
      
      Router.push("/");
    }
  };

  return <button onClick={handleLogout}>退出登录</button>;
}

4. 登录后的鉴权

对于登录后的鉴权,你需要在服务端检查请求中是否包含有效的登录态(例如,检查 token Cookie)。对于需要鉴权的 API,你可以添加逻辑来确保只有已登录的用户才能访问:

pages/api/protected.js 文件中:

export default function handler(req, res) {
  
  const { token } = req.cookies;

  if (token === "valid-token") {
    
    res.status(200).json({ data: "受保护的数据" });
  } else {
    
    res.status(401).json({ message: "未授权" });
  }
}

在实际应用中,你会使用更复杂的逻辑来生成和验证 token,可能还会使用刷新 token 机制等。

请记住,这只是一个简化的登录示例。在实际项目中,你应该为所有敏感操作使用 HTTPS 来保护数据的安全,确保 cookie 的安全设置,比如使用 SecureSameSite 属性,并对密码进行哈希处理和加盐等安全措施。此外,你可能还需要考虑使用第三方认证服务,如 Auth0、Firebase Auth 或 NextAuth.js,它们为身份验证和会话管理提供了更鲁棒的解决方案。

6.3 接口平台场景

Next.js 的 API 路由允许你创建可以被其他域访问的接口服务。你可以创建无服务器函数(Serverless Functions)来处理 HTTP 请求,并通过设置适当的 CORS(跨源资源共享)策略,允许其他域名的请求访问你的 API。

以下是创建可以被其他域访问的 API 路由的步骤:

步骤 1: 创建 API 路由

/pages/api 目录下创建一个新的 .js 文件来定义你的 API 路由,例如 hello.js

export default function handler(req, res) {
  res.status(200).json({ message: "Hello World!" });
}

步骤 2: 设置 CORS

在你的 API 路由文件中,你可以使用 Next.js 提供的 micro-cors 或手动设置 HTTP 头来实现跨域资源共享。下面是一个手动设置 HTTP 头的示例:

export default function handler(req, res) {
  
  res.setHeader("Access-Control-Allow-Credentials", true);
  res.setHeader("Access-Control-Allow-Origin", "*"); 
  res.setHeader(
    "Access-Control-Allow-Methods",
    "GET,OPTIONS,PATCH,DELETE,POST,PUT"
  );
  res.setHeader(
    "Access-Control-Allow-Headers",
    "X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, X-Api-Version"
  );

  
  if (req.method === "OPTIONS") {
    res.status(204).end();
    return;
  }

  
  res.status(200).json({ message: "Hello World!" });
}

这样设置后,你的 API 现在可以接受跨域请求。Access-Control-Allow-Origin 头部决定了哪些源可以访问资源。如果你想要限制特定的域名而非所有域都可以访问,可以将 '*' 替换为具体的源地址。

7. 部署

如果你已经有一个自己的服务器,并配置了 Node.js 环境,那么部署 Next.js 应用会相对简单。以下是在你自己的服务器上部署 Next.js 应用的步骤:

步骤 1: 构建应用

首先,在你的本地开发环境中构建 Next.js 应用。这将生成 .next 目录,其中包含了用于生产环境的优化过的应用版本。

next build

步骤 2: 安装依赖

在服务器上,导航到应用的目录,运行 npm installyarn 来安装依赖(如果你没有一同上传 node_modules 目录)。

cd /path/to/your/app
npm install

步骤 3: 启动应用

使用 next start 来启动你的应用。该命令将会启动一个 Node.js 服务器,该服务器提供了生产环境下的 HTTP 服务。

next start -p YOUR_PORT

其中 YOUR_PORT 是你希望应用运行的端口号(如80,443,3000等)。如果你不指定端口,Next.js 默认会使用 3000 端口。

步骤 4: 使用进程管理器(可选)

在生产环境中,你可能会希望应用能够在后台运行,并在崩溃时自动重启。这时你可以使用进程管理器如 pm2。如果你还没有 pm2,可以通过 npm 安装它:

npm install pm2 -g

然后,使用 pm2 启动你的 Next.js 应用:

pm2 start "next start -p YOUR_PORT" --name "nextjs-app"

这将启动你的应用,并允许 pm2 来管理它。

步骤 5: 设置环境变量(可选)

如果你的应用依赖于环境变量,确保在服务器上设置这些环境变量。你可以在服务器的 .bashrc.profile 或其他适用于你的 shell 的配置文件中设置环境变量,或者在启动应用时直接设置:

ENV_VAR1=value1 ENV_VAR2=value2 pm2 start "next start -p YOUR_PORT" --name "nextjs-app"

步骤 6: 反向代理设置(可选)

如果你在服务器上运行了 Nginx 或 Apache,你可能想要设置一个反向代理,将来自外部的请求转发到 Next.js 应用的端口上。这样可以让你使用 SSL,自定义域名,以及其他高级功能。

这是一个简单的 Nginx 反向代理配置示例:

server {
    listen 80;
    server_name yourdomain.com;

    location / {
        proxy_pass http://localhost:YOUR_PORT;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
    }
}


来自-lecepin,欢迎大家关注,微信搜索“好朋友乐平”关注公众号。

github原文地址

  • 在线整理的确实很好,对文章进行了一个汇总整理,在线备战面试、刷题指南,拿走不谢,要学会站在别人的肩膀上提升自己点击这里-->

最后:

如果你现在正在找工作,可以私信“web”或者直接添加下方小助理进群领取前端面试小册、简历优化修改、大厂内推以及更多阿里、字节大厂面试真题合集,和p8大佬一起交流。

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐