前端进阶之旅前端进阶之旅
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片
  • 场景篇按分类整理的大前端场景考点
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
  • 动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
  • AI 助手随时提问,即时解析
  • AI 模拟面试模拟真实面试 + 报告
  • AI 知识地图串起全站知识点
  • AI 定制路线按你的简历现排
AI 热点
旧版
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片
  • 场景篇按分类整理的大前端场景考点
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
  • 动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
  • AI 助手随时提问,即时解析
  • AI 模拟面试模拟真实面试 + 报告
  • AI 知识地图串起全站知识点
  • AI 定制路线按你的简历现排
AI 热点
旧版
  • 基础篇

    • 环境搭建
    • node部署
    • 基础应用
  • 内置模块

    • 1.0 本地路径处理 path
    • 2.0 文件系统操作 fs
    • 3.1 基础调试 console
    • 3.2 本地调试远程服务器上的Node代码
    • 4.1 网络服务 http
    • 4.2 网络服务 http res
    • 4.3 网络服务 http req
    • 4.4 网络服务 http server
    • 4.5 网络服务 http client
    • 4.6 网络服务 https
    • 4.7 网络TCP net
    • 4.8 网络UDP dgram
    • 4.9 域名解析 dns
    • 5.0 网络地址解析 url
    • 5.1 URL查询字符串 querystring
    • 6.1 流操作 stream
    • 6.2 逐行读取 readline
    • 7.1 进程相关 process
    • 7.2 子进程 child
    • 8.1 二进制数据 buffer
    • 8.2 二进制解码 string_decoder
    • 9.1 事件机制 events
    • 9.2 实用工具模块 util
    • 9.3 数据加密 crypto
    • 9.4 MD5入门介绍及crypto模块的应用
    • 9.4 资源压缩 zlib
    • 9.5 集群 cluster
    • 9.6 v8
  • 进阶篇

    • 5分钟入门非对称加密用法
    • cluster
    • cookie_parser深入
    • crypto模块之理论篇
    • express+cookie_parser签名机制深入剖析
    • express+session实现简易身份认证
    • https
    • log4js入门实例
    • node8_napi
    • 使用 async 控制并发
    • 使用 eventproxy 控制并发
    • 使用 superagent 与 cheerio 完成简单爬虫
    • 基于express+muter的文件上传
    • 将图片转成datauri嵌入到html
    • 常用中间件 body_parser 实现解析
    • 日志模块morgan
    • 服务端字符编解码&乱码处理 charset_enc_dec
    • 测试用例mocha,should,istanbul
    • 调试日志打印debug模块
  • Express

    • 1.1 Express概览篇
    • 1.2 Express
  • Koa2

    • 1.0 koa2概览篇
    • 1.1 快速开始
    • 1.2 async await使用
    • 1.3 koa2简析结构
    • 1.4 koa中间件开发与使用
    • 10.1 单元测试
    • 11.1 开发debug
    • 12.1 快速启动
    • 12.2 框架设计
    • 12.3 分层操作
    • 12.4 数据库设计
    • 12.5 路由设计
    • 12.6 webpack4环境搭建
    • 12.7 使用react
    • 12.8 登录注册功能实现
    • 12.9 session登录态判断处理
    • 13.1 import export使用
    • 2.1 原生koa2实现路由
    • 2.2 koa router中间
    • 3.1 GET请求数据获取
    • 3.2 POST请求数据获取
    • 3.3 koa bodyparser中间件
    • 4.1 原生koa2实现静态资源服务器
    • 4.2 koa static中间件
    • 5.1 koa2使用cookie
    • 5.2 koa2实现session
    • 6.1 koa2加载模板引擎
    • 6.2 ejs模板引擎
    • 7.1 busboy模块
    • 7.2 上传文件简单实现
    • 7.3 异步上传图片实现
    • 8.1 mysql模块
    • 8.2 async await封装使用mysql
    • 8.3 项目建表初始化
    • 9.1 原生koa2实现JSONP
    • 9.2 koa jsonp中间件
  • 其他

    • 操作数据库
    • Session 与 Token
    • Cookie、Session、Token、JWT
    • Socket

# 使用react

30 秒速记

  • 这个项目是客户端渲染:Koa 返回一个空壳 HTML,浏览器加载打包好的 JS,由 React 渲染页面
  • 链路:src/apps 写页面组件 → src/pages 挂载入口 → Webpack 编译到 output/dist → 模板用 <script> 引用
  • 要服务端渲染(SSR)就得在 Koa 里用 renderToString 出 HTML,客户端再 hydrate,两边代码版本必须一致
  • 把服务端数据塞进 <script> 时要转义 <,否则一个 </script> 就能注入脚本
  • React 18 起挂载用 createRoot,ReactDOM.render 在 React 19 被移除

在 Koa 项目里用 React,最常见的就是客户端渲染:服务端只给一个带挂载节点的页面,真正的界面由浏览器里的 React 画出来。 具体链路是 src/apps 写页面组件,src/pages 里调用渲染方法挂到 #app 上,Webpack 把它们编译到 output/dist,Koa 的模板再用 <script> 引进来。它的缺点是首屏要等 JS 下载执行完,对 SEO 也不友好,要解决就得上 SSR,那时候服务端和客户端的构建版本必须对上,不然 hydrate 会报不匹配。

理解「使用react」时,要先明确输入、运行阶段和可观察输出。这里的交互实验会分别执行正常路径与失败路径,并把 Node.js 的关键状态变化和同屏代码对应起来;不能只记命令名称。

工程中还要验证退出码、资源清理和异常输入。属于 module 场景的配置应保持最小可复现,并在开发环境与 CI 中使用相同命令复跑,避免把平台差异或隐式默认值带到线上。

在 Koa 里用 React,先要分清是哪种模式:

  • 客户端渲染:Koa 只返回一个带空节点的 HTML,浏览器下载打包好的 JS 后由 React 生成界面。这个项目就是这种。
  • 服务端渲染(SSR):Koa 里用 react-dom/server 的 renderToString 先生成完整 HTML 返回,浏览器拿到就有内容,JS 加载后再 hydrate 接管交互。
  • 静态生成:构建时就把页面渲染成 HTML 文件,Koa 只当静态服务器。

客户端渲染的整条链路:

// src/apps/index.jsx:只定义页面长什么样
export default function App() { return <h1>index</h1> }

// src/pages/index.js:Webpack 入口,负责挂载
import { createRoot } from 'react-dom/client' // React 18+
import App from '../apps/index.jsx'
createRoot(document.getElementById('app')).render(<App />)
@前端进阶之旅: 代码已经复制到剪贴板
<!-- Koa 返回的模板 -->
<div id="app"></div>
<script src="/output/dist/vendorjs/vendor.js"></script>
<script src="/output/dist/vendorjs/index.js"></script>
<!-- 浏览器执行后,#app 里出现 <h1>index</h1> -->
@前端进阶之旅: 代码已经复制到剪贴板

版本差异要说清:React 17 及以前用 ReactDOM.render(<App />, el);React 18 改成 createRoot(el).render(<App />),旧写法还能用但会警告,并且退回到不支持并发特性的旧模式;React 19 已经把 ReactDOM.render 移除了。如果以后要上 SSR,服务端往页面里注入初始数据时要转义 <,防止 </script> 注入。

面试官追问

追问 1页面空白,构建命令退出码是 0,怎么继续查?
参考回答

退出码 0 只说明编译没报错。打开 DevTools 看三处:Console 有没有运行时报错、Network 里脚本是不是 404 或返回了 HTML、Elements 里挂载节点存不存在。

追问 2客户端渲染和服务端渲染,怎么选?
参考回答

后台管理、登录后才能看的页面,客户端渲染就够了,简单。要 SEO 或者很在意首屏速度的公开页面,比如文章详情、商品页,才值得上 SSR,代价是服务端要跑 React、多一套构建。

追问 3服务端把用户信息用 JSON.stringify 写进 <script> 标签,有什么风险?
参考回答

如果数据里有 </script><script>alert(1)</script>,浏览器会提前结束标签执行后面的脚本。要把 < 转义成 \u003c 再输出,或者用 serialize-javascript,也别把手机号、token 这类敏感字段带进去。

追问 4做 SSR 时控制台报 hydration 不匹配,常见原因是什么?
参考回答

服务端和客户端渲染出的内容不一样:比如组件里直接用了 Date.now()、Math.random(),或者读了 window,又或者服务端和客户端用的不是同一版构建。会变的东西放到 useEffect 里在客户端再算。

# 使用react.js

# react.js简介

30 秒速记

  • React 是做视图的库,不是全家桶框架:路由、请求、状态管理要自己选
  • 核心思想:界面 = 函数(状态),状态变了 React 重新算界面,你不用手动改 DOM
  • JSX 是 React.createElement 的语法糖,要编译后才能在浏览器跑
  • 虚拟 DOM 让 React 算出最小改动再更新真实 DOM,它的价值是声明式写法,不是「一定更快」
  • 配套常见选型:路由 react-router、状态 zustand / redux,要整套方案可以直接用 Next.js

React 是一个专门负责视图渲染的 JavaScript 库,不是包办一切的框架。 它的核心思路是你只描述「数据是这样时界面长什么样」,数据变了 React 自己算出该怎么改 DOM。界面用 JSX 写,它看着像 HTML,其实会被编译成 React.createElement 调用,生成虚拟 DOM 对象。正因为它只管视图,路由、数据请求、目录规范都要自己搭配,想要开箱即用的整套方案,现在一般会选 Next.js 这类基于 React 的框架。

react.js 是作为前端渲染的js库(注意:不是框架)。react.js用JSX开发来描述DOM结构,通过编译成virtual dom的在浏览器中进行view渲染和动态交互处理。更多了解可查阅GitHub https://facebook.github.io/react/

面试官追问

追问 1JSX 编译后是什么样子?
参考回答

<div className="a">hi</div> 会变成 React.createElement('div', { className: 'a' }, 'hi'),返回一个描述节点的普通对象。React 17 起的新 JSX 转换会改用 react/jsx-runtime 的 jsx(),所以文件里不再必须 import React。

追问 2筛选条件变了,数据也拿到了,列表就是不刷新,常见原因?
参考回答

数据存在普通变量里,或者直接改了 state 对象,比如 list.push(x) 后 setList(list),引用没变 React 认为没变化。要用 setList([...list, x]) 这种生成新引用的写法。

追问 3虚拟 DOM 一定比直接操作 DOM 快吗?
参考回答

不一定。手写一次精准的 DOM 操作肯定比「生成虚拟 DOM、对比、再更新」快。虚拟 DOM 的价值是让你用声明式写法也能有不错的性能,代码好维护。

追问 4一个几乎没交互的资讯详情页,要不要改成 React?
参考回答

一般不值得。纯展示页面用服务端模板输出 HTML 就够了,首屏更快、SEO 更好。有大量状态变化和交互、组件复用多的页面,React 才划算。

# 编译使用

30 秒速记

  • 浏览器不认识 JSX,必须编译:<App /> → React.createElement(App)
  • 分工:Babel(@babel/preset-react)翻译语法,Webpack 组织依赖、打包输出
  • 页面引用的是 output/dist 里的产物,引用 src 里的 .jsx 必然报 Unexpected token '<'
  • Unexpected token '<' 还有一种情况:脚本地址 404 被回退成了 HTML 页面
  • 学习时可以用 @babel/standalone 在浏览器里实时编译,生产不能这么干

JSX 浏览器直接跑不了,所以开发和运行之间一定有一步编译,最常用的是 Webpack 加 Babel。 Babel 负责把 JSX 翻译成 React.createElement 调用,顺便把新语法降级;Webpack 从入口出发把组件、第三方库打包到一起,输出到 output/dist。页面上引用的必须是编译后的文件。排查时我见得最多的报错是 Unexpected token '<',要么是引用了源码,要么是脚本地址 404 了,服务端返回了一个 HTML 页面。

基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片
  • 场景篇按分类整理的大前端场景考点
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
  • 动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
  • AI 助手随时提问,即时解析
  • AI 模拟面试模拟真实面试 + 报告
  • AI 知识地图串起全站知识点
  • AI 定制路线按你的简历现排
AI 热点
旧版
  • 基础篇

    • 环境搭建
    • node部署
    • 基础应用
  • 内置模块

    • 1.0 本地路径处理 path
    • 2.0 文件系统操作 fs
    • 3.1 基础调试 console
    • 3.2 本地调试远程服务器上的Node代码
    • 4.1 网络服务 http
    • 4.2 网络服务 http res
    • 4.3 网络服务 http req
    • 4.4 网络服务 http server
    • 4.5 网络服务 http client
    • 4.6 网络服务 https
    • 4.7 网络TCP net
    • 4.8 网络UDP dgram
    • 4.9 域名解析 dns
    • 5.0 网络地址解析 url
    • 5.1 URL查询字符串 querystring
    • 6.1 流操作 stream
    • 6.2 逐行读取 readline
    • 7.1 进程相关 process
    • 7.2 子进程 child
    • 8.1 二进制数据 buffer
    • 8.2 二进制解码 string_decoder
    • 9.1 事件机制 events
    • 9.2 实用工具模块 util
    • 9.3 数据加密 crypto
    • 9.4 MD5入门介绍及crypto模块的应用
    • 9.4 资源压缩 zlib
    • 9.5 集群 cluster
    • 9.6 v8
  • 进阶篇

    • 5分钟入门非对称加密用法
    • cluster
    • cookie_parser深入
    • crypto模块之理论篇
    • express+cookie_parser签名机制深入剖析
    • express+session实现简易身份认证
    • https
    • log4js入门实例
    • node8_napi
    • 使用 async 控制并发
    • 使用 eventproxy 控制并发
    • 使用 superagent 与 cheerio 完成简单爬虫
    • 基于express+muter的文件上传
    • 将图片转成datauri嵌入到html
    • 常用中间件 body_parser 实现解析
    • 日志模块morgan
    • 服务端字符编解码&乱码处理 charset_enc_dec
    • 测试用例mocha,should,istanbul
    • 调试日志打印debug模块
  • Express

    • 1.1 Express概览篇
    • 1.2 Express
  • Koa2

    • 1.0 koa2概览篇
    • 1.1 快速开始
    • 1.2 async await使用
    • 1.3 koa2简析结构
    • 1.4 koa中间件开发与使用
    • 10.1 单元测试
    • 11.1 开发debug
    • 12.1 快速启动
    • 12.2 框架设计
    • 12.3 分层操作
    • 12.4 数据库设计
    • 12.5 路由设计
    • 12.6 webpack4环境搭建
    • 12.7 使用react
    • 12.8 登录注册功能实现
    • 12.9 session登录态判断处理
    • 13.1 import export使用
    • 2.1 原生koa2实现路由
    • 2.2 koa router中间
    • 3.1 GET请求数据获取
    • 3.2 POST请求数据获取
    • 3.3 koa bodyparser中间件
    • 4.1 原生koa2实现静态资源服务器
    • 4.2 koa static中间件
    • 5.1 koa2使用cookie
    • 5.2 koa2实现session
    • 6.1 koa2加载模板引擎
    • 6.2 ejs模板引擎
    • 7.1 busboy模块
    • 7.2 上传文件简单实现
    • 7.3 异步上传图片实现
    • 8.1 mysql模块
    • 8.2 async await封装使用mysql
    • 8.3 项目建表初始化
    • 9.1 原生koa2实现JSONP
    • 9.2 koa jsonp中间件
  • 其他

    • 操作数据库
    • Session 与 Token
    • Cookie、Session、Token、JWT
    • Socket
完整面试题地址:
作者:程序员poetry
扫码关注作者公众号:「前端进阶之旅」 每天分享技术干货
前端进阶之旅公众号二维码

使用react|Nodejs专题系列

# 使用react

30 秒速记

  • 这个项目是客户端渲染:Koa 返回一个空壳 HTML,浏览器加载打包好的 JS,由 React 渲染页面
  • 链路:src/apps 写页面组件 → src/pages 挂载入口 → Webpack 编译到 output/dist → 模板用 <script> 引用
  • 要服务端渲染(SSR)就得在 Koa 里用 renderToString 出 HTML,客户端再 hydrate,两边代码版本必须一致
  • 把服务端数据塞进 <script> 时要转义 <,否则一个 </script> 就能注入脚本
  • React 18 起挂载用 createRoot,ReactDOM.render 在 React 19 被移除

在 Koa 项目里用 React,最常见的就是客户端渲染:服务端只给一个带挂载节点的页面,真正的界面由浏览器里的 React 画出来。 具体链路是 src/apps 写页面组件,src/pages 里调用渲染方法挂到 #app 上,Webpack 把它们编译到 output/dist,Koa 的模板再用 <script> 引进来。它的缺点是首屏要等 JS 下载执行完,对 SEO 也不友好,要解决就得上 SSR,那时候服务端和客户端的构建版本必须对上,不然 hydrate 会报不匹配。

理解「使用react」时,要先明确输入、运行阶段和可观察输出。这里的交互实验会分别执行正常路径与失败路径,并把 Node.js 的关键状态变化和同屏代码对应起来;不能只记命令名称。

工程中还要验证退出码、资源清理和异常输入。属于 module 场景的配置应保持最小可复现,并在开发环境与 CI 中使用相同命令复跑,避免把平台差异或隐式默认值带到线上。

在 Koa 里用 React,先要分清是哪种模式:

  • 客户端渲染:Koa 只返回一个带空节点的 HTML,浏览器下载打包好的 JS 后由 React 生成界面。这个项目就是这种。
  • 服务端渲染(SSR):Koa 里用 react-dom/server 的 renderToString 先生成完整 HTML 返回,浏览器拿到就有内容,JS 加载后再 hydrate 接管交互。
  • 静态生成:构建时就把页面渲染成 HTML 文件,Koa 只当静态服务器。

客户端渲染的整条链路:

// src/apps/index.jsx:只定义页面长什么样
export default function App() { return <h1>index</h1> }

// src/pages/index.js:Webpack 入口,负责挂载
import { createRoot } from 'react-dom/client' // React 18+
import App from '../apps/index.jsx'
createRoot(document.getElementById('app')).render(<App />)
@前端进阶之旅: 代码已经复制到剪贴板
<!-- Koa 返回的模板 -->
<div id="app"></div>
<script src="/output/dist/vendorjs/vendor.js"></script>
<script src="/output/dist/vendorjs/index.js"></script>
<!-- 浏览器执行后,#app 里出现 <h1>index</h1> -->
@前端进阶之旅: 代码已经复制到剪贴板

版本差异要说清:React 17 及以前用 ReactDOM.render(<App />, el);React 18 改成 createRoot(el).render(<App />),旧写法还能用但会警告,并且退回到不支持并发特性的旧模式;React 19 已经把 ReactDOM.render 移除了。如果以后要上 SSR,服务端往页面里注入初始数据时要转义 <,防止 </script> 注入。

面试官追问

追问 1页面空白,构建命令退出码是 0,怎么继续查?
参考回答

退出码 0 只说明编译没报错。打开 DevTools 看三处:Console 有没有运行时报错、Network 里脚本是不是 404 或返回了 HTML、Elements 里挂载节点存不存在。

追问 2客户端渲染和服务端渲染,怎么选?
参考回答

后台管理、登录后才能看的页面,客户端渲染就够了,简单。要 SEO 或者很在意首屏速度的公开页面,比如文章详情、商品页,才值得上 SSR,代价是服务端要跑 React、多一套构建。

追问 3服务端把用户信息用 JSON.stringify 写进 <script> 标签,有什么风险?
参考回答

如果数据里有 </script><script>alert(1)</script>,浏览器会提前结束标签执行后面的脚本。要把 < 转义成 \u003c 再输出,或者用 serialize-javascript,也别把手机号、token 这类敏感字段带进去。

追问 4做 SSR 时控制台报 hydration 不匹配,常见原因是什么?
参考回答

服务端和客户端渲染出的内容不一样:比如组件里直接用了 Date.now()、Math.random(),或者读了 window,又或者服务端和客户端用的不是同一版构建。会变的东西放到 useEffect 里在客户端再算。

# 使用react.js

# react.js简介

30 秒速记

  • React 是做视图的库,不是全家桶框架:路由、请求、状态管理要自己选
  • 核心思想:界面 = 函数(状态),状态变了 React 重新算界面,你不用手动改 DOM
  • JSX 是 React.createElement 的语法糖,要编译后才能在浏览器跑
  • 虚拟 DOM 让 React 算出最小改动再更新真实 DOM,它的价值是声明式写法,不是「一定更快」
  • 配套常见选型:路由 react-router、状态 zustand / redux,要整套方案可以直接用 Next.js

React 是一个专门负责视图渲染的 JavaScript 库,不是包办一切的框架。 它的核心思路是你只描述「数据是这样时界面长什么样」,数据变了 React 自己算出该怎么改 DOM。界面用 JSX 写,它看着像 HTML,其实会被编译成 React.createElement 调用,生成虚拟 DOM 对象。正因为它只管视图,路由、数据请求、目录规范都要自己搭配,想要开箱即用的整套方案,现在一般会选 Next.js 这类基于 React 的框架。

react.js 是作为前端渲染的js库(注意:不是框架)。react.js用JSX开发来描述DOM结构,通过编译成virtual dom的在浏览器中进行view渲染和动态交互处理。更多了解可查阅GitHub https://facebook.github.io/react/

面试官追问

追问 1JSX 编译后是什么样子?
参考回答

<div className="a">hi</div> 会变成 React.createElement('div', { className: 'a' }, 'hi'),返回一个描述节点的普通对象。React 17 起的新 JSX 转换会改用 react/jsx-runtime 的 jsx(),所以文件里不再必须 import React。

追问 2筛选条件变了,数据也拿到了,列表就是不刷新,常见原因?
参考回答

数据存在普通变量里,或者直接改了 state 对象,比如 list.push(x) 后 setList(list),引用没变 React 认为没变化。要用 setList([...list, x]) 这种生成新引用的写法。

追问 3虚拟 DOM 一定比直接操作 DOM 快吗?
参考回答

不一定。手写一次精准的 DOM 操作肯定比「生成虚拟 DOM、对比、再更新」快。虚拟 DOM 的价值是让你用声明式写法也能有不错的性能,代码好维护。

追问 4一个几乎没交互的资讯详情页,要不要改成 React?
参考回答

一般不值得。纯展示页面用服务端模板输出 HTML 就够了,首屏更快、SEO 更好。有大量状态变化和交互、组件复用多的页面,React 才划算。

# 编译使用

30 秒速记

  • 浏览器不认识 JSX,必须编译:<App /> → React.createElement(App)
  • 分工:Babel(@babel/preset-react)翻译语法,Webpack 组织依赖、打包输出
  • 页面引用的是 output/dist 里的产物,引用 src 里的 .jsx 必然报 Unexpected token '<'
  • Unexpected token '<' 还有一种情况:脚本地址 404 被回退成了 HTML 页面
  • 学习时可以用 @babel/standalone 在浏览器里实时编译,生产不能这么干

JSX 浏览器直接跑不了,所以开发和运行之间一定有一步编译,最常用的是 Webpack 加 Babel。 Babel 负责把 JSX 翻译成 React.createElement 调用,顺便把新语法降级;Webpack 从入口出发把组件、第三方库打包到一起,输出到 output/dist。页面上引用的必须是编译后的文件。排查时我见得最多的报错是 Unexpected token '<',要么是引用了源码,要么是脚本地址 404 了,服务端返回了一个 HTML 页面。

由于react.js开发过程用JSX编程,无法直接在浏览器中运行,需要编译成浏览器可识别运行的virtual dom。从JSX开发到运行,需要有一个编译的过程。目前最常用的方案是用webpack + babel进行编译打包。

面试官追问

追问 1线上报 Unexpected token '<',指向一个 .js 文件,可能是什么原因?
参考回答

两种:一是引用的是没编译的 .jsx 源码;二是脚本地址写错了,服务端把 404 回退成了 index.html,浏览器把 HTML 当 JS 解析。去 Network 面板看这个文件的响应内容就能分清。

追问 2只用 Babel 不用 Webpack 行不行?
参考回答

单文件可以,babel src -d lib 就能把每个文件单独转好。但多页面、有 import 依赖和第三方库的项目,浏览器还得自己处理模块加载,Webpack 负责把依赖打成几个文件,两者是配合关系。

追问 3.jsx 文件 import 时不写扩展名报找不到模块,怎么配?
参考回答

在 Webpack 里加 resolve: { extensions: ['.js', '.jsx'] },同时确认 babel-loader 的 test 写的是 /\.jsx?$/,两个都要配。

追问 4为什么不在浏览器里用 @babel/standalone 直接编译 JSX?
参考回答

它要在每个用户的浏览器里加载一个很大的编译器,再现场编译代码,又慢又费流量。只适合写 demo,正式项目一定是构建时编译好。

# 前端待编译源文件目录

← 12.6 webpack4环境搭建12.8 登录注册功能实现 →

fe