基于nodejs实现服务端内核引擎

122 阅读17分钟

引用抖音哲玄前端

基于nodejs实现服务端内核引擎

1. 创建项目-git环境搭建

(一)Git的简单使用方式?

1.远端git clone将代码拉到本地,在本地进行相关开发

2.开发完成后通过git add && git commit两个命令提交到本地仓库

3.再通过git push推送到远程仓库

4.当有迭代开发的时候通过git pull将远端代码拉下来

5.在本地仓库通过git cheout:创建或切换分支,在新分支中进行相关功能开发

6.开发完成后继续用git add && git commit 提交到本地仓库

7.再通过git rebase 同步代码分支代码

8.再通过git push将代码推送到远端仓库

9.再通过pull request/ merge request进行和并请求

(二)可视化管理工具用的什么?下载地址?

Sourcetree:www.sourcetreeapp.com

(三)将来的流水线、部署仓库在哪个代码托管平台管理?网页地址?

Coding:coding.net

腾讯工蜂:git.code.tencent.com

腾讯工蜂使用教程:blog.csdn.net/qq_44930306…

 

(四)Pr、MR是什么?

Pull Request(PR)Merge Request(MR)都是和并请求只不过不同代码托管平台叫法存在差异

2. gitflow协同流程操作

(一)gitflow是什么?

Gitflow是一种基于Git的软件开发工作流程模型,是2010年提出,他为项目分支管理和版本发布提供了一套规范且清晰的模式。

线上分支(固定):master

线上修复分支:hotfix-a

研发分支(固定):develop

功能分支:

feature-a

feature-b

feature-c

(二)Gitflow的流程是怎么样的?

Master为线上分支,只有更新版本时会对此进行操作

Develop为研发分支,在进行研发时对此进行操作,当feature之下的功能测试好之后再上线前进行测试合并到master线上

Feature之下为功能分支,在研发时研发模块、功能时所创建,只有研发模块、功能测试好了再合并到Develop研发分支上

Hotfix为线上修复分支,当线上出问题了就会新建fotfix之下的分支,修复好之后对研发以及线上进行合并

3. 项目初始化

(一)此项目用的是什么node版本?以及node官网地址

18.19.0

Node:nodejs.org/zh-cn

(二)Nvm地址以及使用方法?

nvm-mac: github.com/nvm-sh/nvm#…

nvm-windows:github.com/coreybutler…

nvm list 查看有哪些nodejs版本

nvm install 18.19.0 安装nodejs的18.19.0的版本

nvm use 18.19.0 切换到node18.19.0版本

node -v 查看当前node版本

(三) .gitignore文件是做什么的?

用来提交git代码忽略文件

在.gitgnore中写入根目录下所需要忽略的代码提交时即可忽略

(四)Node环境如何初始化?

终端输入npm init 出现配置项将所需写入

*Git repoistory写入项目代码管理地址

*author 写入作者名

(五)在node初始化之后的package.json中dependencis与devDenpdencis是做什么用的?

dependencis下是项目的依赖

devDenpdencis下是开发依赖,在运行过程中不需要,开发过程中需要

(六)如何安装依赖?

在终端中Npm install之后会在项目中找到package.json下的dependencis与devDenpdencis下的依赖

如果npm install --save那么只会安装dependevcis

如果npm install --save-dev那么就会既安装项目依赖,又安装开发依赖

往往在国内使用npm会出现不能用的情况,这时就要用到cnpm了,一旦装了这个cnpm就会在特定源上进行下载

cnpm地址:www.npmjs.com/package/cnp…

下载命令:npm install cnpm -g --registry=registry.npmmirror.com

查看是否下载好:cnpm -v

使用:cnpm install --save-dev进行下载依赖

安装好依赖根目录会出现node_module文件夹,在文件夹中会出现所有package下所有依赖版本的包。

(七)如何查看源和修改源以及还原源?

修改源:npm config set registry registry.npmmirror.com

查看源:npm config list

还原源:npm config set registry

(八)Koa的使用?

地址:koa.bootcss.com/

(九)如何启动服务?

项目根目录终端中使用 node index.js这个文件中有node的启动代码

(十)ESlint如何配置,以及是做什么用的?

ESLint 是一个用于识别和报告 JavaScript 代码中模式问题的工具,它可帮助开发者编写高质量、风格统一且无潜在错误的代码。

在package.json的devDependcis中有这三个依赖

    "eslint": "^7.32.0",

    "eslint-plugin-import": "^2.28.1",

    "eslint-plugin-vue": "^9.17.0",

在根目录下创建.eslintrc配置文件和.eslintignore忽略两个文件分别进行配置

(十一)如何设置项目启动命令?

在package.json下的scripts中操作

Eslint启动:”lint”: “eslint --quiet --ext js,vue .”

(十二)Git的代码提交规范?以及如何检测?

():

feat:新功能

fix:修文档

docs:文档

style:格式(不影响代码运行的变动)

refactor:重构(既不是新增功能,也不是修改bug的代码变动)

test:增加测试

chore:构建过程或辅助工具的变动

"validate-commit-msg": "~2.14.0",主要用于验证 Git 提交信息是否符合特定的格式和规范的库

"ghooks": "~1.0.3"主要用于用于在特定的 Git 操作(如提交、推送等)前后执行自定义脚本

在package.json中最底下新增config配置:

 "config" :{

    "ghooks" : {

      "commit-msg" : "validate-commit-msg",

      "pre-commit" : "npm run lint"

    }

  }

(十三)基础知识点

1.process.env是什么?

是node里的一个全局对象,用于访问进程里的环境变量

2.try catch是做什么用的?

try 块:包含了可能会抛出异常的代码。当 try 块中的代码执行时,如果发生异常,JavaScript 会立即停止 try 块中后续代码的执行,然后跳转到 catch 块。

catch 块:用于捕获并处理 try 块中抛出的异常。catch 块接收一个参数(通常命名为 error),这个参数是一个包含异常信息的对象,通过 error.message 可以获取异常的具体描述。

内核引擎设计

(一)内核引擎设计是怎么样的?

整个项目是建立于nodejs上,内核引擎设计就是BFF层的设计,有规范的而目录结构同时实现core核心,在核心中有各种各样的loader,将目录解析出来,通过项目启动将目录文件通过core中的loader进行解析到运行时,这个core就是一个轻量的eggjs的内核

 

 

 

(二)什么是SSR?

SSR 即 Server-Side Rendering,也就是服务器端渲染,是一种在服务器端将网页的 HTML 结构生成好,再发送到客户端进行展示的网页渲染技术。

(三)什么是BFF?

BFF 即 Backend For Frontend(服务于前端的后端),它是一种为特定前端应用量身定制后端服务的架构模式。这种模式在微服务架构盛行的背景下应运而生,旨在解决前端与后端之间交互的复杂性和适配问题。

引擎内核实现(一)

(一)基础知识

1.module.exports是什么?

module.exports 是 js 中用于实现模块导出功能的重要机制,主要用于在一个模块里定义变量、函数、类等内容,并将其提供给其他模块使用。

2.require(‘’)是什么?

当你需要在某个文件中使用其他模块的功能时,就可以借助 require() 函数把这些模块导入。该函数会返回被导入模块通过 module.exports 或者 exports 导出的内容。

3.start(options = {}) {}optioins是什么意思?

当用到start函数时,如果没有传入options,那么默认是空对象

4.process.cwd是什么意思?

process.cwd() 是 Node.js 中 process 对象的一个方法,process 对象是一个全局对象,提供了与当前 Node.js 进程进行交互的接口,而 process.cwd() 用于返回当前 Node.js 进程执行时的工作目录

5.path.resolve是什么?

 path.resolve() 是 Node.js 里 path 模块提供的一个方法,其主要功能是将一系列路径或路径片段解析为绝对路径。

6.??是什么语法?

?? 是空值合并运算符,它是 ES2020 引入的新特性。该运算符用于在左侧操作数为 null 或者 undefined 时,返回右侧的操作数;若左侧操作数不为 null 或 undefined,则返回左侧操作数。 

7.glob.sync是什么?

glob.sync 是 Node.js 的 glob 模块提供的一个同步方法,用于根据指定的 glob 模式来同步匹配文件和目录,会返回一个包含匹配到的文件和目录路径的数组。如果没有匹配到任何文件或目录,将返回一个空数组。

8.substring的作用?

substring() 是 JavaScript 中用于提取字符串中指定部分的一个内置方法。它允许你从一个字符串中截取一段连续的字符,并返回一个新的字符串,而不会改变原始字符串

9.LastIndexOf的作用?

lastIndexOf() 是 JavaScript 中字符串和数组都具有的方法,用于返回指定元素在字符串或数组中最后一次出现的索引位置。如果没有找到指定元素,则返回 -1。

10.replace的作用?

replace() 方法,它是 JavaScript 中用于替换字符串中部分内容的重要方法,既可以用于字符串对象,也能在正则表达式场景下发挥作用。

11.toUpperCase的作用?

toUpperCase() 是 JavaScript 中的一个字符串方法,其作用是将调用该方法的字符串中的所有字母转换为大写形式,并且返回一个新的字符串,而不会改变原始字符串。

12.split的作用?

split() 是 JavaScript 中字符串对象的一个方法,在其他编程语言(如 Python、Java 等)里也有类似的功能。它的主要作用是根据指定的分隔符将一个字符串分割成多个子字符串,并将这些子字符串存储在一个数组中。

(二)path是用来做什么的?以及其中的sep属性是做什么的?

path是node一个内置模块,它提供了一些实用工具,用于处理和转换文件路径。由于不同操作系统使用不同的路径分隔符(例如,Windows 使用反斜杠 \,而 POSIX 系统使用正斜杠 /),path 模块可以帮助开发者编写跨平台兼容的代码

sep属性用来兼容不同操作系统的斜杠

(三)glob是用来做什么的?

glob 是一种用于指定文件路径名模式的字符串,它借助特定的通配符来匹配多个文件或目录。通过 glob 模式,你可以方便地指定一组文件,而无需列出每个文件的完整路径。

(四)Koa的middlewares是什么?

是Koa框架的中间件核心特性之一

(五)Json-Schema是什么?

JSON Schema 是一种用于验证和描述 JSON(JavaScript Object Notation)数据结构的标准。它提供了一套规则,用于定义 JSON 数据应该具有的结构、数据类型、取值范围等约束条件,使得开发者能够确保 JSON 数据的质量和一致性

(六)AJV是什么?

AJV(Another JSON Schema Validator)是一个快速、功能丰富且广泛使用的 JavaScript 库,用于验证 JSON 数据是否符合 JSON Schema 定义的规则。

引擎内核实现(二)

(一)基础知识

1.new关键字用来做什么?

在 JavaScript 里,new 关键字用于创建一个对象实例,其主要作用是调用构造函数并且返回一个新的对象。

3.Object.assign的作用?

Object.assign() 是 JavaScript 中的一个内置方法,主要用于将一个或多个源对象的所有可枚举属性复制到目标对象,并返回修改后的目标对象。

4.?.是什么?

?. 是 JavaScript 中的可选链操作符(Optional Chaining Operator),它于 ES2020 版本被引入。该操作符主要用于在访问对象属性或者调用对象方法时,当对象为 null 或者 undefined 的情况下,避免抛出错误,而是直接返回 undefined。

 

(二)Koa的路由兜底以及注册的作用?

Koa路由兜底*通配符,只要没有具体路径的路由都会被进行此逻辑处理

app.use(router.routes())这行代码的作用是将 koa-router 定义的路由规则注册到 Koa 应用中,使得 Koa 应用能够根据客户端的请求路径和 HTTP 方法,找到对应的路由处理函数并执行。

app.use(router.allowedMethods())这行代码的主要功能是处理客户端请求的 HTTP 方法不被允许的情况,当客户端请求的路径存在,但使用的 HTTP 方法未在路由中定义时,它会返回合适的响应状态码和头部信息。

引擎内核应用

(一)如何配置启动命令以及环境?

在package.json的script下设置启动命令以及环境

Windows:

npm install cross-env -D下载依赖

"dev:win": "cross-env _ENV=local nodemon ./index.js",

"beta:win": "cross-env _ENV=beta node ./index.js",

"prod:win": "cross-env _ENV=production node ./index.js",

Mac:

"dev:mac": "_ENV='local' nodemon ./index.js",

"beta:mac": " _ENV='beta' node ./index.js",

"prod:mac": " _ENV='production' node ./index.js"

(二)Koa-nunjucks-2是什么?

koa-nunjucks-2是一个在 Koa 框架中用于集成 Nunjucks 模板引擎的中间件。

网址:www.npmjs.com/package/koa…

(三)基础知识

1.path.join是做什么用的?

path.join() 是 Node.js 中 path 模块的一个方法,用于将多个路径片段连接成一个规范化的、跨平台兼容的路径字符串。

2.bind的作用?

在 JavaScript 中,bind() 是函数对象的一个内置方法,用于创建一个新函数,在调用时会将 this 关键字绑定到指定的对象上,并且可以预设参数。这在处理回调函数、事件处理程序或需要固定 this 上下文的场景中非常有用。

3.ctx是什么?

ctx 是 Koa 的上下文对象,包含请求和响应信息

4.render是什么?

 render 方法(由 koa-nunjucks-2 中间件提供)

5.什么是js继承?

在 JavaScript 中,继承是一种允许一个对象直接使用另一对象的属性和方法的机制。它是面向对象编程(OOP)的核心概念之一,主要用于实现代码复用、抽象和多态。

6.状态码301、302的区别?

301永久重定向

302临时重定向

7.IndexOf的作用?

indexOf() 是 JavaScript 中用于查找数组或字符串中特定元素 / 子字符串位置的方法。

8.toLowerCase是什么意思?

toLowerCase() 是 JavaScript 中用于将字符串转换为小写形式的内置方法

(四)在使用koa-nunjucks-2时 为什么用.tpl而不用.html?

.tpl(Template)明确表示这是待渲染的模板文件,包含动态语法(如 {{变量}}、{% 逻辑 %}),需要在服务端处理后才能生成完整的 HTML。

.html 通常代表最终的静态 HTML 文件,用户浏览器直接解析的成品。

(五)Koa-static是做什么的?

koa-static 是一个用于 Koa 框架的中间件,用于处理静态文件(如 HTML、CSS、JavaScript、图片等)的请求。它可以将指定目录下的文件直接返回给客户端,无需额外的路由处理,简化了静态资源的管理。

(六)superagent 是做什么的?

superagent 是一个轻量级、灵活的 HTTP 请求库,专为 Node.js 和浏览器环境设计。它提供了简洁的 API,支持多种 HTTP 方法(GET、POST、PUT、DELETE 等)、请求参数处理、文件上传、认证和响应解析,是前后端通用的网络请求解决方案。

(七)koa-bodyparser 是做什么的?

koa-bodyparser 是 Koa 框架的一个中间件,用于解析 HTTP 请求体(如 JSON、表单数据等),并将解析后的结果挂载到 ctx.request.body 上。它是处理 POST、PUT 等包含请求体的请求时必不可少的工具。

(八)Log4js是做什么的?

log4js 是一个流行的 Node.js 日志库,灵感来源于 Java 的 log4j 框架。它提供了灵活的日志记录功能,支持多级别日志、日志分类、日志输出到不同目标(文件、控制台、数据库等),是 Node.js 应用中最常用的日志解决方案之一。

(九)md5是做什么的?

把任意长度的字节串变换成 128 位(16 字节)的大整数,以固定长度值代表原始数据,即便数据微小变动,生成的摘要也大不相同,具有雪崩效应 。

(十)Axios是做什么的?

Axios 是一个基于 Promise 的 HTTP 客户端,主要用于浏览器和 Node.js 环境中发送 HTTP 请求。

CDN引用地址:cdn.jsdelivr.net/npm/axios/d…


(十一)Koa洋葱圈模型是靠什么实现的?

Koa 洋葱圈模型中,当请求到达最内层的路由处理函数后,会开始从内向外执行中间件的后半部分逻辑,这主要是通过next()函数来实现的。

 

总结

(一)在基于nodejs实现服务端内核引擎中做了什么事?

1.新增必要文件+环境配置

2.渲染一个页面

3.注入变量

4.引入资源

5.实现一个接口

6.增加可维护性

7.添加post body解释器

8.添加日志

9.增加健壮性:errrorHandler

10.增加健壮性:apiSignVerify

11.增加健壮性:apiParamsVerify

(二)说一下整个内核引擎启动后的流程

这个项目整个项目是SSR渲染,内核引擎是建立在nodejs上,BFF架构模式,是一个轻量egg.js。

1.这个项目启动后首先会将项目名与路径以对象的形式传入Core核心文件。

2.在核心文件中创建koa实例app,将刚刚传入的对象挂载到app.options(应用配置)上

3.项目运行时路径挂载到app.baseDir(基础路径),也就是绝对路径项目根目录

4.app文件夹路径挂载到app.businessPath(业务文件路径)

5.将判断初始化环境是开发、测试、生产挂载到app.env中

6.开始加载中间件(middlewareLoader解析器解析)将app/middleware文件夹下的文件进行处理,并以对象的形式挂载到app.middlewares,middlewares是koa的核心特性之一。

7.开始加载路由校验(routerSchemaLoader解析器解析)将app/router-schema文件夹下的文件进行处理,并将返回的json schema的格式的内容通过对象嵌套挂载到app.routerSchema上

8.开始加载控制器(controllerLoader解析器解析)将app/controller文件夹下的文件进行处理,并返回对象挂载到app.controller中,对象内容是文件名:对象实例。

9.开始加载服务(serviceLoader解析器解析)将app/service文件夹下的文件进行处理,并返回对象挂载到app.controller中,对象内容是文件名:对象实例。

10.开始加载配置(configLoader解析器解析)将./config文件夹下的文件根据环境变量按需引入,并通过覆盖默认config配置挂载到app.config。

11.开始加载拓展(extendConfig解析器解析)将app/extend文件夹下的文件进行处理,将拓展文件内容直接挂载到app.文件名中

12.开始注册全局中间件,将app/middleware文件进行启动,配置静态根目录、模板引擎渲染、解析body中间件、异常捕获中间件、签名合法校验、api的json-schema校验

13.开始注册路由,找到app/router文件夹下的所有文件,进行路由注册

14.最后启动服务器。

(三)说一下访问路径内核引擎走的流程

(1)访问有效页面路径

1.进行浏览器localhost:端口号/router注册的ssr路径访问

2.页面发起请求

3.进入到路由器中分发路由

4.进入运行时异常报错处理中间件遇到next进行下一步

5.再进入到业务逻辑处理controller控制器中进行render渲染以及模板页面传参

6.按照中间件相反顺序next后逻辑出模型

7.出页面响应即可访问

(2)请求有效API路径

1.API请求发起

2.进入路由器中分发路由

3.进入运行时异常报错处理中间件遇到next进行下一步

4.进入签名合法性校验中间件遇到next进行下一步

5.进入API参数JSON-schema校验遇到next进行下一步

6.进入controller控制器

7.再进入service服务层去运行与数据层交互逻辑进行获取数据并返回

8.再按照中间件相反顺序next后逻辑出模型

9.出API响应

(3)访问无效 页面路径

1.进行浏览器localhost:端口号/router注册的ssr路径访问,

2.页面发起请求

3.进入到路由发现没有路径,进行302临时重定向,跳转到启动时传入路径

(4)请求无效API路径

1. API发起请求

2. 进入到路由发现没有路径,进行302重定向跳转