2024年Web前端最新基于 Express 应用框架的技术方案选型浅谈(2),Web前端工程师面试该怎么准备

Vue 面试题

1.Vue 双向绑定原理
2.描述下 vue 从初始化页面–修改数据–刷新页面 UI 的过程?
3.你是如何理解 Vue 的响应式系统的?
4.虚拟 DOM 实现原理
5.既然 Vue 通过数据劫持可以精准探测数据变化,为什么还需要虚拟 DOM 进行 diff 检测差异?
6.Vue 中 key 值的作用?
7.Vue 的生命周期
8.Vue 组件间通信有哪些方式?
9.watch、methods 和 computed 的区别?
10.vue 中怎么重置 data?
11.组件中写 name 选项有什么作用?
12.vue-router 有哪些钩子函数?
13.route 和 router 的区别是什么?
14.说一下 Vue 和 React 的认识,做一个简单的对比
15.Vue 的 nextTick 的原理是什么?
16.Vuex 有哪几种属性?
17.vue 首屏加载优化
18.Vue 3.0 有没有过了解?
19.vue-cli 替我们做了哪些工作?

如果你觉得对你有帮助,可以戳这里获取:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】

  • 不利于 SEO

为了解决上述客户端的渲染问题,需要实现 React 服务端渲染。由于当时还没出现成熟的服务端渲染应用框架,因此只能自己摸索构建 React 服务端渲染方案:

  • 为了实现前后端代码同构,需要对服务端代码进行 Webpack 打包配置

  • 使用 script 标签以及全局变量的形式实现前后端 react-redux 数据 store 的统一(这个印象深刻,当时思索了很久)

使用了服务端渲染方案后,可以去除之前的 Ejs 模板引擎,当时设计的大致结构如下:

react-server-render

当页面发送路由请求时,Express 服务端使用 react-router 匹配相应路由对应的 React 组件实例并调用 renderToString 方法进行服务端页面渲染(实现页面的局部刷新)。当页面渲染完成后,由 React 打包后的静态资源对页面进行 hydrate 处理。此时的 React 代码是同构的,因此需要注意哪些会运行在服务端,哪些会运行在客户端。同时服务端需要对同构代码进行Webpack 打包处理。

以上实现记录在示例 rewatch 中,入口文件是 server.js  ,由于文件比较混乱(把客户端渲染和服务端渲染的示例放在了同一个文件项目中),这里给出另外一个非常简单的示例 rewatch-server-render,项目目录结构如下:

.

├── public                      # 静态资源目录

│   └── js

│      ├── bundle.js            # react 目录打包文件

│      ├── common.js            # react 目录打包公共文件

│      ├── react-dom.min.js     # react 库文件

│      └── react.min.js   # react 库文件

├── react                       # react 同构代码目录(没有 react-router,可以查看 rewatch 示例)

│   ├── actions

│   ├── components

│   ├── containers

│   ├── reducers

│   ├── store

│   └── index.js

├── server                      # 服务端

│   └── routes                  # 服务端路由(没有使用 react-router 同构,可以查看 rewatch 示例)

├── server.js                   # 开发态服务入口文件

├── server.bundle.js            # 生产态服务入口文件

├── webpack.browser.config.js   # 静态资源打包的 webpack 配置(目标文件 bundle.js、common.js)

└── webpack.node.config.js      # 服务端打包的 webpack 配置(目标文件 server.bundle.js)

Angular 技术方案选型


2016年10月到2017年3月,使用 Angular 设计了一个 Express 应用,大致的技术选型如下:

  • Ejs

  • Bootstrap

  • Angular-Chart

  • Mongoose

  • Redis

  • Sokect.io

这是一个简单的服务端多页应用示例,使用 Ejs 模板引擎进行页面渲染,渲染完成后交由 Anguar 进行页面的响应操作(发送请求使用 Angular 内置的 $http 服务)。该示例不需要额外的 Webpack 配置,只需要启动 Express 服务本身渲染设计即可。目录结构如下:

.

├── client                      # 静态资源目录

│   ├── css/                    # 样式

│   ├── imgs/                   # 图片

│   ├── js/                     # 脚本

│   │  ├── angular/             # angular应用

│   │  │  ├── controllers/    # angular控制器

│   │  │  ├── services/         # angular服务

│   │  │  └── webapp.js/  # angular自动引导应用程序

│   │  └── sockets/      # sockets应用

│   └── lib                     # 插件(包括angualr、bootstrap/bootstrap-table、chart等)

├── config                      # 配置(包括Redis、Mongoose配置)

│   ├── config.js               # 参数配置

│   └── index.config.js         # 导出配置

├── server                      # 服务端

│   ├── constants/              # 常量

│   ├── controllers/            # 控制器

│   ├── events/                 # 事件

│   ├── models/                 # 模型

│   ├── routes/                 # 路由

│   ├── sockets/                # socket.io

│   ├── pubs/                   # Redis发布

│   └── subs/                   # Redis订阅

├── views                       # 视图(使用Ejs模板引擎)

└── app.js                      # 服务入口文件

温馨提示: 这种多页应用框架是天然的 SSR 模型,一般都需要配合模板引擎进行设计。

Vue 技术方案选型


2018年6月,使用 Vue 设计了服务端渲染的 Express 应用,大致技术选型如下:

  • Mongoose

  • Nuxt

  • Vue

  • lokka

  • Muse-UI

  • 客户端和服务端同构代码的 Webpack 配置由 Nuxt 封装

  • 服务端 Backpack 配置

该技术选型最主要的特点如下:

  • 支持服务端渲染

  • 支持 Graphql 查询语言

  • 前后端统一 TypeScript 语法

选型详细说明

  • 为了支持 Graphql 查询语言,服务端选择使用支持 Express 中间件扩展的 graphql-yoga。

  • 客户端的 HTTP 请求需要符合 Graphql 请求格式,一种方式是使用 axios 等模拟 Graphql 的请求格式,另外一种方式是选用支持Graphql 请求格式的请求库,这里选用 lokka 作为 Graphql 客户端的请求库。

  • 为了快速设计页面,选用了基于 Vue 2.0 的 Material Design UI 组件库 Muse-UI。

  • 选用了 Nuxt 作为服务端渲染的中间件(基于 Vue.js 的通用应用框架,预设了服务端渲染应用所需要的各种配置)。

  • 为了支持客户端 TypeScript 语法,需要扩展 Nuxt 的默认 Webpack 配置,利用 Nuxt 的模块/注册自定义loaders配置 ts-loader,配合 nuxt-property-decorator 实现客户端 TypeScript 语法。

项目目录结构

在 Nuxt 的目录结构中,服务端引入的同构代码放在.nuxt 目录中,是 Webpack 打包后的代码文件,因此如果服务端不使用特殊的语法,完全不需要 Backpack 配置。此项目为了支持服务端 TypeScript 语法,使用 Backpack 对服务端代码进行构建(不影响同构部分代码的构建,同构代码在 Nuxt 里是通过读取文件的方式获取)。

.

├── .nuxt                       # Nuxt构建目录(Nuxt预设目录)

├── assets                      # 资源目录(Nuxt预设目录)

│   ├── img                 # 图片

│   ├── icon                 # 图标

│   └── style            # 样式

├── build                       # 配置(包括Redis、Mongoose配置)

│   └── main.js                 # 服务端Backpack构建的目标启动入口文件

├── common                      # 前后端通用

│   ├── constants/              # 常量

│   └── types/                  # TypeScript接口

├── components                  # 组件目录(Nuxt预设目录)

├── constants                   # 前端常量目录

├── docs                        # 文档目录(渲染.md文件)

├── graphql                     # 前端Graphql请求接口

├── layouts                # 布局目录(Nuxt预设目录)

├── middleware     # 中间件目录(Nuxt预设目录)

├── mixins         # 全局mixins

├── modules         # Nuxt模块(TypeScrpt的Webpack配置扩展)

├── pages         # 页面目录(Nuxt预设目录)

├── plugins         # 插件目录(Nuxt预设目录)

├── server         # 服务端目录

│   ├── constants/              # 常量

│   ├── database/               # 数据库模型

│   ├── express/                # 服务对外的公共API接口

│   │   ├── controllers/     # 控制器

│   │   ├── routes/      # 路由

│   │   └── services/   # 服务

│   ├── graphql/                # 服务内部的Graphql查询接口

│   │   ├── middlewares/     # Graphql中间件

│   │   ├── resolvers/     # Graphql Resolver

│   │   ├── schemas/      # Graphql Schema

│   │   └── index.ts   # graphql接口入口文件

│   ├── types/                  # TypeScript接口

│   ├── utils/                  # 工具方法

│   └── index.ts                # 服务端入口文件(Backpack构建入口地址)

├── static                      # 静态文件目录(Nuxt预设目录)

├── store                       # Vuex目录(Nuxt预设目录)

├── utils                       # 客户端工具方法

├── .cz-config.js               # cz提交配置文件

├── .env                  # 环境变量

├── .gitignore                # Git忽视文件

├── .huskyrc                 # Git钩子配置文件

├── .vcmrc      # cz校验配置

├── app.html     # html文件

├── backpack.config.js   # Backpack配置文件

├── CHANGELOG.md    # 升级日志

├── ecosystem.config.js   # PM2启动配置文件

├── index.d.ts     # TypeScript声明文件

├── nuxt.config.js    # Nuxt配置文件

├── package.json    # 项目描述文件

├── README.md     # 说明

├── tag.bat      # 项目打Tag脚本

└── tsconfig_node.json          # TypeScript配置文件

运行脚本设计

package.json中的配置脚本如下:

“build”: “cross-env NODE_ENV=production nuxt build && backpack build”,

“pm2”: “pm2 start ecosystem.config.js”,

“pm2:stop”: “pm2 stop ecosystem.config.js”,

“dev:client”: “cross-env NODE_ENV=development DEV_TYPE=nuxt ts-node --compiler ntypescript --project tsconfig_node.json ./server”,

“dev:server”: “cross-env NODE_ENV=development DEV_TYPE=server ts-node-dev --compiler ntypescript --project tsconfig_node.json ./server”

  • build:使用 Webpack 构建 Nuxt 资源包以及使用 Backpack 构建服务端入口文件(转义 TypeScript)

  • pm2:以生产模式启动一个进程守护的 Web 服务器

  • pm2:stop:停止运行 Web 服务器

  • dev:client:启动开发态热部署前端渲染服务

  • dev:server:启动开发态热启动服务端服务

虽然是服务端渲染框架(理论上可以一个人开发项目,启动一个热加载的服务端命令即可),但是在开发的过程中考虑到多人协作以及开发的便利性仍然将客户端和服务端进行分离。

在服务端配置 Nuxt 的 Builder 会导致服务端热加载过慢,因此将服务端 Nuxt 的 Builder 过滤掉,使用 ts-node-dev 做服务端热启动。在客户端使用 ts-node 启动服务,通过识别 DEV_TYPE 环境变量加载Nuxt的 Builder,实现 Web 前端的热加载功能。需要注意客户端向服务端发送请求是跨域的,因此在服务端的开发态环境需要配置允许跨域。

**温馨提示:**一个服务端渲染框架楞是让我拆成了前后端开发分离的框架模式。

最后

设计了以上三个方案后,发现从零开始构建一个 Express 应用时至少需要考虑以下几个方面:

  • 数据库( MongoDB / MySql 等)选型

  • 是否需要模板引擎以及模板引擎( Ejs / Jade 等)选型

  • 前端框架( JQuery / Angular / React/ Vue 等)选型

  • HTTP 请求库(axios / request / superagent 等)选型

  • 是否需要 UI 组件库以及 UI 组件库选型

  • 客户端是否需要 Webpack 构建

  • 服务端是否需要 Webpack / Backpack 构建

  • 其他(session、redis、socket.io 等)

  • 性能、监控等

简单的起手式

  • MongoDB
    总结:

  • 函数式编程其实是一种编程思想,它追求更细的粒度,将应用拆分成一组组极小的单元函数,组合调用操作数据流;

  • 它提倡着 纯函数 / 函数复合 / 数据不可变, 谨慎对待函数内的 状态共享 / 依赖外部 / 副作用;

开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】

Tips:

其实我们很难也不需要在面试过程中去完美地阐述出整套思想,这里也只是浅尝辄止,一些个人理解而已。博主也是初级小菜鸟,停留在表面而已,只求对大家能有所帮助,轻喷🤣;

我个人觉得: 这些编程范式之间,其实并不矛盾,各有各的 优劣势

理解和学习它们的理念与优势,合理地 设计融合,将优秀的软件编程思想用于提升我们应用;

所有设计思想,最终的目标一定是使我们的应用更加 解耦颗粒化、易拓展、易测试、高复用,开发更为高效和安全

  • 性能、监控等

简单的起手式

  • MongoDB
    总结:

  • 函数式编程其实是一种编程思想,它追求更细的粒度,将应用拆分成一组组极小的单元函数,组合调用操作数据流;

  • 它提倡着 纯函数 / 函数复合 / 数据不可变, 谨慎对待函数内的 状态共享 / 依赖外部 / 副作用;

开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】

Tips:

其实我们很难也不需要在面试过程中去完美地阐述出整套思想,这里也只是浅尝辄止,一些个人理解而已。博主也是初级小菜鸟,停留在表面而已,只求对大家能有所帮助,轻喷🤣;

我个人觉得: 这些编程范式之间,其实并不矛盾,各有各的 优劣势

理解和学习它们的理念与优势,合理地 设计融合,将优秀的软件编程思想用于提升我们应用;

所有设计思想,最终的目标一定是使我们的应用更加 解耦颗粒化、易拓展、易测试、高复用,开发更为高效和安全

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值