From 3c1ab9fa16b3cb3f4bd2b7063b0df54238feba06 Mon Sep 17 00:00:00 2001 From: shfshanyue Date: Tue, 22 Mar 2022 15:06:12 +0800 Subject: [PATCH] update --- douyin/minify.md | 20 ++++ frontend-engineering/deploy/simple-intro.md | 126 +++++++++++++++----- post/oc.md | 70 +++++++++++ post/zero-to-learn-node.md | 106 +++++++++++++++- test/mock.md | 106 ++++++++++++++++ 5 files changed, 393 insertions(+), 35 deletions(-) create mode 100644 post/oc.md create mode 100644 test/mock.md diff --git a/douyin/minify.md b/douyin/minify.md index e2ac289..e6a4479 100644 --- a/douyin/minify.md +++ b/douyin/minify.md @@ -39,6 +39,16 @@ function f(a,b){return a+b}console.log(f(3,4)) console.log(7) ``` +terser 是 js 中专业的代码压缩工具,在 webpack 中可使用 `terser-webpack-plugin` 进行代码压缩。 + +我们可以在 Terser REPL 中在线尝试压缩代码。 + +哦对,在测试环境中用以调试随便打的 console.log,出现在生产环境中是不不太好。 + +很多同学也将去除生产环境中的 console.log 写在简历上。 + +这仅仅需要对 terser 添加一个配置项 drop_console 即可完成。 + ## 纯文字 大家好,我是山月。 @@ -58,3 +68,13 @@ console.log(7) 我们开启代码压缩的神奇魔法,在编译期对代码进行预计算。 经优化,代码最终仅有 14 个字节。 + +terser 是 js 中专业的代码压缩工具,在 webpack 中可使用 terser-webpack-plugin 进行代码压缩。 + +我们可以在 Terser REPL 中在线尝试压缩代码。 + +哦对,在测试环境中用以调试随便打的 console.log,出现在生产环境中是不不太好。 + +很多同学也将去除生产环境中的 console.log 写在简历上。 + +这仅仅需要对 terser 添加一个配置项 drop_console 即可完成。 diff --git a/frontend-engineering/deploy/simple-intro.md b/frontend-engineering/deploy/simple-intro.md index d5c117f..cf0beac 100644 --- a/frontend-engineering/deploy/simple-intro.md +++ b/frontend-engineering/deploy/simple-intro.md @@ -2,9 +2,13 @@ 在所有人入门编程及学习更多编程语言时,敲下的第一行代码是: 输出 `hello, world`。 -初学如何部署前端,如同学习编程一样,第一步先根据最简单页面进行部署。 +``` js +console.log('hello, world') +``` + +初学部署前端,如同学习编程一样,第一步先根据最简单页面进行部署。 -比如本系列专栏,先部署一个最简单 HTML 如下所示,只有几行代码,我称它为**hello 版前端应用**。 +比如本系列专栏,先部署一个最简单 HTML 如下所示,只有几行代码,无任何 CSS/Javascript 代码,我称它为**hello 版前端应用**。 ``` html @@ -21,11 +25,20 @@ > PS: 本文以 [simple-deploy](https://github.com/shfshanyue/simple-deploy) 仓库作为实践 +我们将带着两个疑问,一步一步了解前端部署: + +1. 如何手写一个简单的静态资源服务器用以部署前端 +1. 为何需要 nginx、docker 等工具辅助前端部署 + ## HTTP 报文 -部署可看做对 HTTP 资源的服务,或者说,是对 HTTP 请求报文的响应。我们写一段服务器代码用以返回 HTML,便完成了对前端的部署。 +HTTP 是在互联网中进行数据交互的协议,你可从互联网中拿到文档、图片、音频及视频各种资源。 + +而最简部署可看做,你向服务器发送一个获取 HTML 资源的请求,而服务端将响应一段 HTML 资源。我们在请求资源的过程中将发送一段请求报文(Request Message),而服务端返回的 HTML 资源为响应报文(Response Message)。 -以下是对*hello版前端应用*的一段简单的 HTTP 请求及响应报文。 +我们写一段服务器代码,在 HTTP 响应报文中设置响应体为 HTML,便完成了对前端的部署。 + +以下是对**hello版前端应用**的真实的 HTTP 请求及响应报文。 > 通过 `curl -vvv localhost:3000` 可获得报文信息。 @@ -54,13 +67,34 @@ Keep-Alive: timeout=5 ``` +以下是对**hello版前端应用**的 HTTP 请求及响应报文的图文表示 + ![](https://cdn.jsdelivr.net/gh/shfshanyue/assets/2022-02-24/simple-deploy.67a117.webp) -## 一段简单的服务器部署代码 +好,那接下来我们写一段服务器代码,用以响应 HTML。 + +## 手写简单静态资源服务器: 响应字符串 + +作为前端,以我们最为熟悉的 Node 为例,写一段最简单的前端部署服务。该服务监听本地的 3000 端口,并在响应体返回我们的**hello 版前端应用**。 + +为求简单,我们直接将**hello 版前端应用**以字符串的形式进行响应。 -作为前端,以我们最为熟悉的 Node 为例,写一段最简单的前端部署服务。 +在 Node 中写服务端最重要的内置模块(`builtinModule`)为 [node:http](https://nodejs.org/api/http.html),通过 `node:` 前缀,可指明其为内置模块,被称作 `Protocol Import`。从而避免了 node 内置模块与第三方模块的命名冲突。 -该服务监听本地的 3000 端口,并返回我们的*hello 版前端应用*。 +``` js +const http = require('node:http') +``` + +通过 `http.createServer` 可对外提供 HTTP 服务,而 `res.end()` 可设置 HTTP 报文的响应体。以下是一段 hello 版本的 nodejs 服务。 + +``` js +const server = http.createServer((req, res) => res.end('hello, world')) +server.listen(3000, () => { + console.log('Listening 3000') +}) +``` + +我们将**hello 版前端应用**以字符串的方式在代码中进行维护,并通过 `res.end()` 设置其为响应报文的响应体。最终代码如下。 > PS: 该段服务器 nodejs 代码位于 [simple-deploy/server.js](https://github.com/shfshanyue/simple-deploy/blob/master/server.js) @@ -84,19 +118,36 @@ server.listen(3000, () => { }) ``` -启动服务,并在浏览器端打开 `localhost:3000`,可看见 `hello, shanyue`。 +通过 `node server.js` 启动服务,成功运行。 + +``` bash +$ node server.js +Listening 3000 +``` + +启动服务后,在浏览器端打开 `localhost:3000`,可查看到响应头及响应体 `hello, shanyue`。 ![](https://cdn.jsdelivr.net/gh/shfshanyue/assets/2021-12-31/clipboard-3621.529aef.webp) **恭喜你,部署成功!** -但是前端静态资源总是以文件的形式出现,我们对代码进一步优化。 +但是前端静态资源总是以文件的形式出现,我们需对代码进一步优化。 -## 一段稍微复杂的服务器代码: 文件系统 +## 手写简单静态资源服务器: 响应文件 + +当然,部署前端作为**纯静态资源**,需要我们使用文件系统(file system)去读取资源并将数据返回。 + +在代码中,html 以前以字符串形式进行维护,现在将其置于文件系统中的 `index.html` 中,并通过 nodejs 中文件系统读取文件的相关 API `fs.readFileSync('./index.html')` 进行获取文件内容,代码如下。 + +``` js +// fs 为内置模块, +const fs = require('node:fs') -当然,部署前端作为**纯静态资源**,需要我们使用文件系统(fs)去读取资源并将数据返回。 +// 通过 fs.readFileSync 可读取文件内容 +const html = fs.readFileSync('./index.html') +``` -在代码中,html 以前是个字符串,现在通过 nodejs 文件系统读取文件的相关 API `fs.readFileSync('./index.html')` 进行获取,代码如下。 +我们将**hello 版前端应用**以文件系统的方式进行维护,并通过 `res.end()` 设置其为响应报文的响应体。最终代码如下。 > PS: 该段服务器 nodejs 代码位于 [simple-deploy/server-fs.js](https://github.com/shfshanyue/simple-deploy/blob/master/server-fs.js) @@ -113,9 +164,16 @@ server.listen(3000, () => { }) ``` -当然,对于前端这类纯静态资源,**自己写代码无论从开发效率还是性能而言都是极差的**。 +接下来启动代码,成功运行。 + +``` bash +$ node server-fs.js +Listening 3000 +``` + +当然,对于前端这类纯静态资源,**自己写代码无论从开发效率还是性能而言都是极差的**,这也是我们为何要求助于专业工具 nginx 之类进行静态资源服务的原因所在。 -比如将文件系统修改为 `ReadStream` 的形式将会提升该静态服务器的性能,代码如下。 +比如将文件系统修改为 `ReadStream` 的形式进行响应将会提升该静态服务器的性能,代码如下。 ```js const server = http.createServer((req, res) => { @@ -130,58 +188,62 @@ const server = http.createServer((req, res) => { $ npx serve . ``` -在 create-react-app 构建成功后,它会提示使用 `serve` 进行部署。 +`serve` 是 `next.js` 的母公司 `vercel` 开发的一款静态资源服务器。作为前端久负盛名的静态服务器,广泛应用在现代前端开发中,如在 `create-react-app` 构建成功后,它会提示使用 `serve` 进行部署。本地环境而言,还是 [serve](https://github.com/vercel/serve) 要方便很多啊。 ![Creact React APP 构建后,提示使用 serve 进行部署](https://cdn.jsdelivr.net/gh/shfshanyue/assets/2021-12-31/clipboard-3980.619061.webp) **然而,Javascript 的性能毕竟有限,使用 `nginx` 作为静态资源服务器拥有更高的性能。** -但是对于本地环境而言,还是 [serve](https://github.com/vercel/serve) 要方便很多啊。 - ## 部署的简单理解 -那什么是部署呢,为什么说你刚才部署成功? +通过以上两个最简服务的成功运行,可以使我们更加深入的了解前端部署。我们再回头看,什么是部署呢,为什么说你刚才部署成功? + +假设此时你有一台拥有公共 IP 地址的服务器,在这台服务器使用 `nodejs` 运行刚才的代码,则外网的人可通过 `IP:3000` 访问该页面。那这可理解为部署,使得所有人都可以访问。 -假设此时你有一台拥有公共 IP 地址的服务器,在这台服务器使用 `nodejs` 运行刚才的代码,则外网的人可通过 `IP:3000` 访问该页面。 +假设你将该服务器作为你的工作环境,通过 `npm start` 运行代码并通过,所有人都可访问他,即可视为部署成功。看来你离所有人都可访问的部署只差一台拥有公共 IP 的服务器。 -那这可理解为部署,使得所有人都可以访问。 +实际上,有极少数小微企业在生产环境中就是直接 ssh 进生产环境服务器,并通过 `npm start` 部署成功后,通过 IP 与端口号的方式进行访问。当然通过 IP 地址访问的项目一般也非公开项目,如果公开使用域名的话,则用 nginx 配置域名加一层反向代理。 -假设你将该服务器作为你的工作环境,通过 `npm run start` 运行代码并通过,所有人都可访问他,部署成功。看来你离所有人都可访问的部署只差一台拥有公共 IP 的服务器。 +**不管怎么说,你现在已经可以通过裸机(宿主机)部署一个简单的前端应用了。** -不管怎么说,你现在已经可以通过裸机(宿主机)部署一个简单的前端应用了。 +## 关于部署的更多疑问解答 -## 一些疑问 +我们现在已经可以在本地跑起服务了,但是在生产环境部署为什么还需要 nginx,甚至 docker 呢? -*问: 那既然通过 `npm start` 可以启动服务并暴露端口对外提供五福,那为什么还需要 nginx 呢?* +接下来,我回应一些关于前端部署的更多疑问。 -**你需要管理诸多服务(比如A网站、B网站),通过 nginx 进行路由转发至不同的服务,这也就是反向代理**,另外 nginx 还可以提供 TLS、HTTP2 等功能。 +*一问: 那既然通过 `npm start` 可以启动服务并暴露端口对外提供服务,那为什么还需要 nginx 呢?* + +**你需要管理诸多服务(比如A网站、B网站),通过 nginx 进行路由转发至不同的服务,这也就是反向代理**,另外 TLS、GZIP、HTTP2 等诸多功能,也需要使用 nginx 进行配置。 当然,如果你不介意别人通过端口号去访问你的应用,不用 nginx 等反向代理器也是可以的。 ![反向代理](https://cdn.jsdelivr.net/gh/shfshanyue/assets/2022-02-24/Nginx.632fa5.webp) -*问: 我确实不介意别人通过 IP:Port 的方式来访问我的应用,那在服务器可以 npm run dev 部署吗?* +*二问: 我确实不介意别人通过 IP:Port 的方式来访问我的应用,那在服务器可以 npm run dev 部署吗?* -可以,但是非常不推荐。`npm run dev` 往往需要监听文件变更并重启服务,此处需要消耗较大的内存及CPU等性能。 +**可以,但是非常不推荐**。`npm run dev` 往往需要监听文件变更并重启服务,此处需要消耗较大的内存及CPU等性能。 针对 Typescript 写的后端服务器,不推荐在服务器中直接使用 `ts-node` 而需要事先编译的理由同样如此。 当然,如果你也不介意性能问题也是可以的。 -*问: 那为什么需要 Docker 部署?* +*三问: 那为什么需要 Docker 部署?* 用以隔离环境。 -假设你有三个后端服务,分别用 Java、Go、Node 编写,你需要在服务器分别安装三者的环境,非常麻烦。 +假设你有三个后端服务,分别用 Java、Go、Node 编写,你需要在服务器分别安装三者的环境,才能运行所有语言编写的代码,这对于开发者而言非常麻烦。 -假设你有三个 Node 服务,分别用 node10、node12、node14 编写,你需要在服务器分别安装三个版本 nodejs,非常麻烦。 +假设你有三个 Node 服务,分别用 node10、node12、node14 编写,你需要在服务器分别安装三个版本 nodejs 才能运行各个版本 nodejs 编写的代码,对于开发者而言也非常麻烦。 -而有了 Docker,就没有这种问题。 +而有了 Docker,就没有这种问题,它可单独提供某种语言的运行环境,并同时与宿主机隔离起来。 对于前端而言,此时你可以通过由自己在项目中单独维护 `nginx.conf` 进行一些 nginx 的配置,大大提升前端的自由性和灵活度,而无需通过运维或者后端来进行。 ## 小结 -本篇文章介绍了了一些对于前端部署的简单介绍,并使用 nodejs 写了两段代码用以提供静态服务,来加深理解。 +本篇文章介绍了了一些对于前端部署的简单介绍,并使用 nodejs 写了两段代码用以提供静态服务,加深对前端部署的理解。虽然我们可自写代码对前端静态资源进行部署,但从功能性与性能而讲,都是远不如专业工具的。 + +在本文章,将应用在本地或者宿主机进行成功运行,但是现代流行的前端部署方案,都是使用 docker 对前端进行部署。 而在下篇文章中,我们将介绍如何使用 Docker 将仅有十几行代码的 **hello 版前端应用** 跑起来。 diff --git a/post/oc.md b/post/oc.md new file mode 100644 index 0000000..b086de1 --- /dev/null +++ b/post/oc.md @@ -0,0 +1,70 @@ +大家好,我是山月。 + +昨天有一位同学私信我说,通过我在哔哩哔哩的模拟面试系列视频拿到了字节跳动的 **OC**。 + +我一想,`OC` 是什么意思,我一肚子狐疑,但又不好说我不知道让别人觉得我孤陋寡闻。都来感谢我了,肯定是个好事,我先恭喜恭喜总不会有错的。 + +事后,我查了一下万能的百度! + +![image.png](https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/32cfc830a5974555a50bd559acc34045~tplv-k3u1fbpfcp-watermark.image?) + +啥都没有,肯定是我搜索姿势有问题,程序员要用 Google 搜索! + +![image.png](https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/aa8fba25f8334afdaffeb4783672e354~tplv-k3u1fbpfcp-watermark.image?) + +好吧,还是啥都没有。 + +我猜测估计和 offer 有关,那我就和 offer 关键词一起进行搜索。 + +![image.png](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/95acdf7132ba44b1a44e0260e3fa2692~tplv-k3u1fbpfcp-watermark.image?) + +这下终于有了线索。顺藤摸瓜,在 [HC、JD、OC 是啥...求职、工作过程中可能遇到的英文缩略语整理](https://zhuanlan.zhihu.com/p/149051616) 我找到了它的最终释义! + +> OC (Offer Call),当企业决定录用你时,会打电话发 Offer,并询问你是否接受。一般 OC 也称为「开奖」。 + +大概就是口头 offer 的意思吧。 + +除此之外,还有 + ++ HC (Head Count),招聘名额 ++ JD(Job Description),工作职责描述 ++ BG(Business Group),事业群。如微信事业群,WeiXin Group,简称WXG ++ BU(Business Unit),业务线 ++ PR(Public Relationship),公关 ++ PM(Product Manager/Project Manager),产品经理或项目经理 ++ OD (Outsourcing Dispatcher),外包,比如华为的外包 + +曾几何时,我对这些互联网专业术语一窍不通,而现在已了然在胸。 + +今天的互联网黑话,你学会了吗?你对这些英文单词缩写词汇怎么看呢? + +![image.png](https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/a441e120c25e41b6b7f1775f954f518f~tplv-k3u1fbpfcp-watermark.image?) + +英文缩写学会了,那就再看看一些中文词汇吧! + +二字动词: + +复盘,赋能,沉淀,倒逼,落地,串联,协同,反晡,兼容,包装,重组,履约,晌应,量化,发力,布局,联动,细分,梳理,输出,加速,共建,支撑,融合,聚合,集成,对齐,对标,对焦,抓手,拆解,拉通,抽象,摸索,提炼,打通,打透,吃透,迁移,分发,分层,分装,穿梭,辐射,围绕,复用,渗透,扩展,开拓。 + +二字名词: + +漏斗,中台,闭环,打法,拉通,纽带,矩阵,刺激,规模,场景,聚焦,维度,格局,形态,生态,话术,体系,认知,玩法,体感,感知,调性,心智,战役,合力,心力。 + + + + +--- + +更多关于山月的文章: + +1. [我的专栏《前端工程化三十八讲》免费发布了,附视频讲解、代码示例](https://mp.weixin.qq.com/s/u4-AzPc7bmwi2f6oUCBNmQ) +1. [三分钟讲解什么是 corejs](https://mp.weixin.qq.com/s/ATM1Je1cYkJa6v6cgRD9rA) +1. [Javascript 体积优化时的代码压缩原理是什么](https://mp.weixin.qq.com/s/BcryGbaFLs4R-c8fFE3p5Q) +1. [简述 Javascript 的模块化方案](https://mp.weixin.qq.com/s/F-U4YP42QY9n1GSsTzX34w) +1. [什么是 CICD](https://mp.weixin.qq.com/s/fzBYqEp1sB-iAEiTlOQ9WA) + +--- + +欢迎扫码添加山月的微信,备注进群,加入山月的前端面试交流群: + + diff --git a/post/zero-to-learn-node.md b/post/zero-to-learn-node.md index c8867c4..ad00e7b 100644 --- a/post/zero-to-learn-node.md +++ b/post/zero-to-learn-node.md @@ -1,9 +1,109 @@ -## Node +# 零基础可操作的 Node 入门学习指南 -## 插曲: glob +1. 如何开始学习 Node? +2. Node 有哪些重要的内置模块需要重点学习? +3. 哪些源码可以推荐阅读? +4. 有没有路线图(Roadmap)可以进行系统学习? -## 插曲: braces +## 如何开始学习 Node? + +**根据公司的需求学习 node.js,在需求中进行学习,时间充分,成长快,事半功倍。** + +我们来看一看 nodejs 扮演的最重要的两个角色: + +1. 前端工具链 +2. Server + +而对于前端,接触最多的便是基于 Node 的前端工具,比如 webpack、rollup、vite、eslint、prettier、create-react-app、create-vue 等。因此这里先说下**前端工具链**这部分。 + +而这部分,最容易在工作中获得需求,如**构建一个脚手架**,也容易作为自己的 KPI/OKR。通过此,可获得 node 关于 **文件系统**、**终端操作** 一系列知识。 + +如果业务中不需要构建一个脚手架,那也有诸多的场景需要写一个脚本,其中涉及最多的也是文件系统。 + +比如,在详细了解并完成一个脚手架后,你至少可以了解一个问题? + +**如何判断文件是否存在?** + +再往下看,你会发现有很多关于文件系统的第三方包,他们是做什么的? + ++ [mkdirp](https://github.com/isaacs/node-mkdirp#readme): 什么是 `mkdir -p`,你自己实现会如何实现,如何设计 API?(当然这个在 node 10+ 已经原生实现,不过你仍然可以看看源码的实现) ++ [fs-extra](https://npm.devtool.tech/fs-extra): 你会发现很多脚手架都使用了 `fs-extra`,它又比原生的 `fs` 多了什么功能呢? ++ [fs-events](https://npm.devtool.tech/fsevents): 为什么不使用原生的 `fs.watch` 监听文件变化呢,监听文件变化的底层操作系统原理又是什么呢? ++ [graceful-fs](https://npm.devtool.tech/graceful-fs): 它为什么比原生的 `fs` 更加友好 (graceful) + + +继续深入,你会发现,一个东西叫 Glob,一个叫 Braces,它们又是啥?最后你发现,原来它们和语言无关,在终端就可以直接使用。 + +### glob + ++ `ls -lah *.js` + +### braces + Set: `{x,y,z}` + Sequence: `{1..10}` + Step: `{1..10..2}` + +## Node 有哪些重要的内置模块需要重点学习? + +好吧,假设这个大前提是,**我想要使用 Node 作为服务器端来使用,那我应该重点学习哪些重要模块?** + +那最重要的一个就是: + ++ `http` + +非常重要但是不那么紧急的有: + ++ `stream` ++ `buffer` ++ `net` + +这几个模块十分重要,但是学习起来非常枯燥。可参照我的示例代码 [node-native](https://github.com/shfshanyue/node-examples/tree/master/node-native) 进行学习。 + +最终也可以思考一个问题? + +**我需要考虑多少边界条件才能正确读取到 Request Body 呢?** 可以参考 [raw-body](https://github.com/stream-utils/raw-body) + +## 哪些源码可以推荐阅读? + ++ [lru-cache](https://github.com/isaacs/node-lru-cache): LRU Cache,前端及服务端框架中的常用依赖。 ++ [tsdx](https://github.com/formium/tsdx): 零配置的 npm 库开发利器,与 CRA 相似,不过它主要面向库开发者而非业务开发者,了解它是如何提供零配置功能,看懂默认配置做了那些优化,并了解它的所有工具链 (prettier、eslint、size、bundleanalyzer、rollup、typescript、storybook)。 ++ [create-react-app](https://github.com/facebook/create-react-app): React 最广泛的脚手架,读懂三点。一,如何生成脚手架;二,如何实现 eject;三,了解 cra 的所有重要依赖,读懂默认 webpack 配置。 ++ [axios](https://github.com/axios/axios): 请求库,了解它是如何封装源码且如何实现拦截器的。 ++ [koa](https://github.com/koajs/koa) ++ [body-parser](https://github.com/stream-utils/raw-body): express 甚至是大部分服务端框架所依赖的用以解析 body 的库 ++ [next](https://github.com/vercel/next.js) ++ [ws](https://github.com/websockets/ws): 了解 websocket 是如何构造 Frame 并发送数据的 (在此之前可阅读 node/http 源码) ++ [apollo-server](https://github.com/apollographql/apollo-server): GraphQL 框架,值得一看 ++ [node](https://github.com/nodejs/node): 最难的放到最后边 + +还有一些细节可以实现下: + ++ native http server ++ native http client ++ trie router ++ mustable ++ stream pipeline (nodejs): https://github.com/mafintosh/pump + +## 有没有线路图可以推荐下 + +目前关于 node 的学习路线图还不太有,我粗略总结一下,过几天做一个路线图出来: + +1. 了解 node.js 可以做什么 +2. 学习 node.js 的 http 模块,并了解一些简单的 HTTP Header 及状态码 +3. 学习 node.js 的 stream 并且了解如何最简单形式的读取 Request Body +4. 学习 node.js 的一个框架,比如 express、koa、fastify、nest +5. 学习 node.js 框架如何写中间件,并了解其 Context +6. 学习 node.js 的路由,了解两种,一种基于正则,一种基于前缀树 +7. 使用 docker 在本地搭建一个 postgres/redis,学习简单的数据库和 redis +8. 使用 sequelize 了解如何操作数据库 +9. 使用 node.js 写一个真正但简单的服务,比如成语接龙 +10. 日志设计,接入数据 +11. 部署 +12. 异常与报警设计 +13. 性能分析与调试 + +学习结束后可以根据面试进行系统训练: + ++ https://github.com/ElemeFE/node-interview: 关于 node 的面试合集 ++ https://github.com/goldbergyoni/nodebestpractices: ✅ The Node.js best practices list (February 2022) \ No newline at end of file diff --git a/test/mock.md b/test/mock.md new file mode 100644 index 0000000..abd6b07 --- /dev/null +++ b/test/mock.md @@ -0,0 +1,106 @@ +# Mock 神器 Apifox + +大家好呀,我是一名苦逼的前端开发工程师,为啥苦逼呢,这不,项目下周就要上线了,但是后端还没给我接口,没有接口我就无法调试,工作停滞不前,我也只能坐着干着急。 + +我报告给了我的老板狐哥: **老板,这后端不靠谱啊,都快上线了,接口还没出来**。 + +狐哥回道,**别着急呀,这不有 Mock 吗**? + +**Mock,什么是 Mock 啊?**我一脸狐疑,问向狐哥。 + +狐哥慢条斯理说,就是**前端自己启动一个 HTTP 服务,模拟后端接口的数据,这样就无需等待后端接口开发完成了,不会因为后端开发延误而阻塞你的工作进程了**。 + +嗯,真是个不错的注意,我仿佛发现了新大陆!以后再也不用受后端拖累了,心里暗暗开心,但转念一想不对啊,时间不够啊! + +我又沮丧了下来,转头向狐哥说道: **Mock 好是好,但是时间不够了啊,我重新启动一个 Mock HTTP Server,也要花不少时间呀**。 + +狐哥见我开了窍,又忙不迭地说: **咱们团队不是用的 Apifox 管理 API 吗,只需要点下按钮,就可以自动 Mock!** + +一键 Mock 数据,这么简单,那应该怎么使用 Apifox 自动 Mock 呢? + +狐哥接下来,缓缓道来。 + +## 使用 Apifox 智能 Mock + +Apifox,API 文档、API 调试、API Mock、API 自动化测试集成于一体的强大工具,可以在 [Apifox官网](https://www.apifox.cn/?utm_source=shanyue-question) 直接下载,在 Windows、Linux、Mac 下都可以使用。 + +![](https://files.mdnice.com/user/5840/2dea171d-ab32-42c2-89a9-ddac0993a046.png) + +下载成功后,可打开其中的**示例项目**,是一个关于宠物店的项目。打开宠物店的项目,可以在每个标签页看到四个标签: 文档、修改文档、运行、高级 Mock。 + +![](https://files.mdnice.com/user/5840/f9276d5a-59e4-4afb-ae44-3c33c80ca565.png) + +我们先看下这个**查询宠物详情**的接口,其请求接口为 `/pet/{petId}`,而响应数据为 `code` 与 `data`,`data` 是一个 `Pet` 的一个自定义数据类型。 + +![](https://files.mdnice.com/user/5840/7c0c7ba9-37cd-4052-b98a-bbed63258993.png) + +在数据模型选项卡中,可以看到 `Pet` 这个自定义数据类型,其中有两个字段为 `id`、`name` 和 `photoUrls`。 + +![](https://files.mdnice.com/user/5840/ff4c39ab-c0e7-4770-93c1-e66cd383971e.png) + +在我们的本地是肯定没有宠物店的这个项目和接口的,那我们现在就可以使用一键 Mock 服务,请求 Mock 出来的宠物店数据,非常方便! + +切换环境为**Mock服务**,此时地址栏前缀为 `http://127.0.0.1:4523/mock/533840`,点击运行按钮发送请求,见证奇迹的时刻到了,数据正确返回! + +![](https://files.mdnice.com/user/5840/68e12984-e582-44e0-8b8b-e48a466bf412.png) + +在项目中进行 Mock 时,使用 `http://127.0.0.1:4523/mock/533840` 代替后端的 API 前缀即可,特别好用是不是! + +但这仅仅是 Apifox 强大的只能 Mock 下的冰山一角! + +**假设,我们有一个用户接口,它有一个字段 email 期待返回邮箱格式的数据,一个字段 phone 期待返回手机格式的数据,一个字段 avatar 期待返回一个头像,而这在 Apifox 下都可以零配置完成!** + +这就是,Apifox 强大的智能 Mock 规则: **你需要做的仅仅是定义 API 接口文档中的响应数据,接下来一键 Mock 服务,全部只能工作都交给 Apifox 的智能 Mock 来完成**。 + +在 Apifox 内部,当接口响应的数据字段未配置 mock 规则时,系统会自动使用智能 Mock 规则来生成数据,以实现使用时零配置即可 mock 出非常人性化的数据。根据项目设置、功能设置、智能 Mock 设置即可打开默认配置。 + +![](https://files.mdnice.com/user/5840/7a2aa8ec-5b09-4dc1-a38b-9b1b0964ca76.png) + + +## 使用 Apifox 自定义 Mock + +在 Apifox 自动 Mock 非常方便,但我们需要自定义 Mock 功能,在上个接口中,宠物有一个字段是 `name`,表示宠物的名字,我们可不可以将宠物的名字仅仅定位为两个字符。 + +我们在 Apifox 数据模型设置中找到该宠物的数据模型,并配置其 `name` 字段。 + +![](https://files.mdnice.com/user/5840/adbe46af-c005-4d85-b0fb-c4eed92ade8e.png) + +`@cword(3)` 是[Apifox 的 Mock 语法](https://www.apifox.cn/help/app/mock/mock-rules/),完全兼容 Mock.js(数据占位符方式),并扩展了一些 Mock.js 没有的语法(如国内手机号 @phone)。 + +![](https://files.mdnice.com/user/5840/69d8e813-62c2-4f11-80be-431b77216584.png) + +如现有 Mock 语法无法满足需求,建议使用 正则表达式 `@regexp` 来实现灵活的定制。正则表达式基本能满足各种特殊场景的需求。 + +![](https://files.mdnice.com/user/5840/90098d40-a7f8-4a08-8872-f3238bd35cd8.png) + +而我们将宠物的名字限制为两个字符,即可使用: `@cword(2)` 替代。 + +## Apifox 的高级 Mock + +Apifox 的智能 Mock 与自定义 Mock 已经足够强大,但是他的功能远不止于此。我们尽管可以使用自定义 Mock 对数据进行每个字段更为精细的模拟,但远远无法满足复杂业务的多样性。 + +以以上**查询宠物详情**的接口为例,难免有记录不存在的示例,此时接口响应为完全不同的数据类型。此时,我们可以使用 Apifox 的高级 Mock 用以模拟数据。 + +![](https://files.mdnice.com/user/5840/e694b02c-ef90-4aa4-9d0e-1ef89d9d9caa.png) + +当我们查询宠物的 ID 为3时,返回不存在数据的相应格式,同时设置状态码为 404。 + +![](https://files.mdnice.com/user/5840/f8bc471d-ec66-4ba5-adf6-9844036a5b83.png) + +为了满足业务的多样性,我们还可以使用基于模板的高级 Mock 功能与 Apifox 的 Mock 语法相结合。这里使用了 Javascript 的 [nunjucks](https://github.com/mozilla/nunjucks) 模板语法,可以生成你想生成的任意数据。 + +![](https://files.mdnice.com/user/5840/d3759afb-8586-4c42-82f0-f7f5be4d44dc.png) + + +## 小结 + +今天关于 Apifox 强大的功能就介绍到了这里,你是不蠢蠢欲动也想下载尝试一下呢? + +客户端下载地址:https://www.apifox.cn/ +API Hub网页版地址:https://www.apifox.cn/apihub/ + +大家可前往下载体验一波~ + +如果有什么疑问,也可以进Apifox官方交流群和官方工作人员讨论交流。 + +![](https://mmbiz.qpic.cn/mmbiz_png/nRXib819UwN10LkP959TE1FKNEC1nw0wBdw2ZWQLr2M1Lq3WHP4VzMMvzaJGvpCIXp9qEtPbDqhttFC9HgwHE0g/640?wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1)