走近 Next.js:全栈框架的简介与应用
如果你现在正在找工作,可以私信“web”或者直接添加下方小助理进群领取前端面试小册、简历优化修改、大厂内推以及更多阿里、字节大厂面试真题合集,和p8大佬一起交流。
1. Next.js
Next.js 是一个使用 React 构建单页应用程序(SPA)的开源 JavaScript 框架。它使得构建服务端渲染(SSR)和静态网站生成(SSG)的 React 应用程序变得简单和高效。Next.js 由 Vercel(原 Zeit)公司开发,并且自推出以来得到了广泛的关注和使用。
Next.js 提供了一系列的特性和优势,包括但不限于:
-
服务端渲染(SSR):每次页面请求时,都在服务器上实时渲染页面,这有助于提高首屏加载速度并改善搜索引擎优化(SEO)。
-
静态网站生成(SSG):在构建时生成静态的 HTML 页面,可以部署到任何静态网站托管服务上,进一步提高性能和扩展性。
-
文件系统路由:Next.js 通过
/pages
目录中的文件结构自动创建路由,每个 React 组件文件对应一个路由。 -
自动代码拆分:Next.js 会自动对每个页面进行代码拆分,只加载当前页面所需的代码,这有助于减少页面的加载时间。
-
API 路由:可以在
/pages/api
目录下创建 API 路由,方便构建 API 接口。 -
内置 CSS 和 Sass 支持:Next.js 支持 CSS Modules,并内置了对 CSS-in-JS 库的支持,同时也支持预处理器如 Sass。
-
开箱即用的 TypeScript 支持:Next.js 提供了对 TypeScript 的内置支持,无需额外的配置。
-
插件生态系统:社区提供了大量的 Next.js 插件,可以很容易地扩展应用的功能。
Next.js 的开发体验通常被认为是它的主要优点之一,因为它简化了许多传统上需要手动配置的部分,例如路由和代码拆分。这使得开发者可以专注于编写应用逻辑,而不是花费过多时间在构建配置上。由于其灵活性和性能,Next.js 已经被许多企业用于构建生产级的网站和应用。
2. 诞生背景
首次发布于 2016 年。它的诞生背景是基于开发者和企业对构建更快、更优化的 Web 应用程序的需求,特别是在服务端渲染(SSR)和搜索引擎优化(SEO)方面。React 本身是一个客户端渲染的库,这意味着 JavaScript 需要在用户的浏览器中运行才能生成 HTML 内容。这种模式在用户体验和性能上存在一些挑战,尤其是对首屏加载时间和 SEO 不友好。
Next.js 主要解决了以下问题:
-
SEO 和首屏加载性能: 传统的客户端渲染的 React 应用可能不利于搜索引擎爬虫的抓取,且首次加载时间较长。Next.js 提供服务端渲染作为默认行为,这意味着页面在服务器上被渲染为 HTML,然后发送给客户端。这样做可以显著提升首屏加载速度,并对搜索引擎优化友好。
-
开发效率: 在使用 React 开发大型应用时,开发者通常需要配置路由、代码拆分、构建优化等。Next.js 通过约定大于配置的方式,减少了这些常见任务的手动设置,提供了简易的文件系统路由、自动的代码拆分和热加载,提高了开发效率。
-
构建和部署: Next.js 提供现成的构建系统和对持续集成的优化,使得将应用从开发阶段迁移到生产变得简单。此外,与 Vercel 平台的无缝集成也让部署变得异常轻松。
-
灵活的数据获取策略: Next.js 提供了灵活的数据获取方法,如
getStaticProps
和getServerSideProps
,使得开发者可以根据页面的需求选择不同的数据预渲染策略,例如静态生成或服务器端渲染。 -
无需额外设置的 TypeScript 支持: Next.js 从一开始就考虑了对 TypeScript 的支持,让开发者能够享受到强类型语言带来的好处,而无需复杂的配置。
-
API 路由: Next.js 允许开发者在同一个项目中构建前端页面和 API 接口,简化了全栈应用的开发过程。
-
生态系统和社区支持: Next.js 随着时间的推移建立起了一个健康的插件生态系统,并且得到了强大的社区支持,这为开发者提供了各种资源和第三方库的集成。
总之,Next.js 的出现是为了简化和优化基于 React 的应用开发流程,同时提供了高性能和 SEO 友好的解决方案,它代表了当代 Web 应用开发的一个重要趋势。
3. 安装
安装 Next.js 非常简单,主要有两种方式:使用 create-next-app
脚手架来创建新项目,或者手动添加到现有的 React 项目中。以下是安装 Next.js 的步骤:
使用 create-next-app 创建新项目
-
使用
npx
(npm
的包执行工具)执行以下命令来创建一个新的 Next.js 应用。这会自动下载create-next-app
并创建一个新的项目。
npx create-next-app my-next-app
-
进入项目目录:
cd my-next-app
-
启动开发服务器:
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 提供了一个强大且灵活的框架,允许开发者迅速启动项目并按需进行扩展。
最小工作流程
-
pages/index.tsx
或pages/index.js
这是 Next.js 应用程序的默认入口页面,也就是访问站点根 URL(如http://localhost:3000/
)时加载的页面。使用 TypeScript 编写时后缀为.tsx
,纯 JavaScript 时为.js
。 -
pages/_app.tsx
或pages/_app.js
这是 Next.js 中的一个特殊文件,它允许你初始化所有页面。你可以使用这个文件来保持页面布局,保持状态(如 Redux 或 MobX)时使用,或者用于全局 CSS 的插入。这个文件是可选的,如果你的应用不需要全局初始化,则不需要创建它。 -
pages/_document.tsx
或pages/_document.js
_document
也是一个特殊文件,用于自定义文档结构。Next.js 会使用这个文件来渲染网站的 HTML 结构。默认情况下,Next.js 为你生成文档结构,但如果你需要自定义<html>
和<body>
标签或在<head>
中添加额外的链接和脚本,你可以通过创建_document
文件来实现。这个文件也是可选的,只有在需要自定义整个 HTML 页面结构时才需要它。 -
app/layout.tsx
或app/layout.js
layout
文件并不是 Next.js 的特定组件或约定。但在开发过程中,通常会创建一个Layout
组件来封装页面结构,比如包含导航栏和页脚的共享布局。此组件可以在不同页面中复用,以便保持一致的外观和行为。通常,开发者会根据项目需要自行创建和组织Layout
组件。 -
app/page.tsx
或app/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.tsx
或 app/page.tsx
这样的文件则更多取决于你个人或团队的项目结构和组件组织方式。
4. 目录结构
本页面提供了 Next.js 应用程序的项目结构概览。它涵盖了顶层文件和文件夹、配置文件,以及在 app
和 pages
目录内的路由约定。
点击文件和文件夹名称以了解每个约定的更多信息。
顶层文件夹
顶层文件夹用于组织应用程序的代码和静态资源。
-
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 的安全设置,比如使用 Secure
和 SameSite
属性,并对密码进行哈希处理和加盐等安全措施。此外,你可能还需要考虑使用第三方认证服务,如 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 install
或 yarn
来安装依赖(如果你没有一同上传 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,欢迎大家关注,微信搜索“好朋友乐平”关注公众号。
-
在线整理的确实很好,对文章进行了一个汇总整理,在线备战面试、刷题指南,拿走不谢,要学会站在别人的肩膀上提升自己点击这里-->
最后:
如果你现在正在找工作,可以私信“web”或者直接添加下方小助理进群领取前端面试小册、简历优化修改、大厂内推以及更多阿里、字节大厂面试真题合集,和p8大佬一起交流。
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)