龙空技术网

基于 Express 应用框架的技术方案选型浅谈

Echa攻城狮 114

前言:

如今看官们对“jquerysubs”大约比较着重,姐妹们都想要剖析一些“jquerysubs”的相关知识。那么小编在网上网罗了一些对于“jquerysubs””的相关资讯,希望看官们能喜欢,大家一起来学习一下吧!

作者:前端迷

转发链接:

前言

现在的 Node 对于前端而言可以涵盖各个方面,包括命令行接口、插件、依赖库、脚手架以及 Web 服务等。本文是一篇对于 Node 使用的浅谈文章,会简单讲解一些个人使用 Node 的经验,分享的内容主要可分为三个方面:

工具篇插件篇服务篇

工具篇会讲解使用 NPM 发布命令行接口的简单教程。插件篇主要讲述如何开发一个有趣的 Webpack 插件(Vue CLI / Babel 插件同理)。服务篇会讲解一些基于 Express 应用框架的技术选型方案,这类技术往往对于做一些前端工具平台非常有用(例如 Mock 平台、多语言平台等,往往可配合命令行接口进行设计)。由于篇幅较长,本文只讲解服务篇内容。

Web 应用框架

基于 Node.js 的 Web 应用框架很多,包括但不限于

Express :已经成为开发 Node.js WEB 应用的标准框架,大多数工程师都很熟悉他的设计思想(极简的内核,但能让你用各种中间件来扩展他的功能)Koa :设计思想非常类似 Express,区别在于它是使用 ES6 中的 generator 编写,这种写法解决了大家所熟知的回调地狱问题Feathers:用来实现面向服务架构的一种灵活的解决方案,非常适合创建 Node.js 微服务Sails :是一个全能的 MVC 框架,主要是受到 Ruby on Rails 启发,已经存在很长时间,支持各种数据库,不管是 SQL 还是 No-SQLEgg :为企业级框架和应用而生Modal:创建基于 PostgreSQL 的无状态的、分布式的服务Keystone:快速搭建基于 MongoDB 的管理后台的最佳解决方案,基于数据模型的定义即可自动生成后台界面,支持常见的增删改查操作和灵活的数据过滤Loopback:内置了很多特性的成熟框架,支持基于 token 的认证,支持各种数据库。loopback 的“杀手锏”功能是 API 浏览器,该功能能让开发者用非常直观的方式查看所有的 API 接口,如果你需要创建 API 服务的话,它无疑是个很好的选择

本文主要讲解 Express 应用框架,虽然它提供的能力非常简单,但对于一些工具平台的开发完全可以胜任,并且可以写出各种千奇百怪的 MVC 模式(如果对服务端 MVC 不是很清晰可以阅读 服务端 MVC 之 Model2 的衍生)。这里简单介绍以前设计的几种基于 Express 扩展的技术选型方案,恰好涵盖了 React、Angular 以及 Vue 这三个 Web 前端框架。

温馨提示: 接下来使用的示例项目都相对简单,希望对刚入门 Express 的小白们有所启示。

React 技术方案选型

2016年7月到10月,从零开始学习 React 并使用 React 设计了服务端渲染的 Express 应用(同年10月25日诞生了 Next.js ),大致的技术选型如下:

BootstrapReactMongooseWebpackKarma/Chai

由于对 React 不是很熟悉,首先实现了单页应用,然后实现了服务端渲染应用。

实现 React 单页应用(SPA)React 学习和设计过程

在使用 React 之前只会简单的使用 Bootstrap,当时对 React 的学习历程大致如下:

学习 React 语法学习 ES6 / ES7 语法学习 Babel / Webpack,打包代码支持 ES6 / ES7 / JSX 语法学习 webpack-dev-server / Hot Module Replacement,启动开发环境的 Express 服务,实现热加载功能学习 flux / react-redux学习 react-router学习 mocha / karma

学习总结文档如下:

WebpackServerReact-ReduxReact-RouterMochaKarma

以上学习过程记录在 react-demo 和 react-start-kit (小而全的概念性参考价值)中,此时只是简单的 React 单页应用设计过程。大致结构如下:

enter image description here

**温馨提示:**在前后端分离的开发模式中,如果 Web 前端实现的是 SPA(单页应用),服务端可以选用不同的设计语言,例如 Node.js、Java 或者 Golang 等。Web 前端可以通过 Express渲染服务器 进行后端的请求代理转发。如果想要前端先行,可以使用 Easy Mock 或者自己设定的 JSON 数据模拟后端提供的接口规范。

Express 服务端设计过程

服务端的设计选用 Node.js 的 Express 框架,大致实现步骤如下:

搭建服务端 Express,设计服务端 MVC 目录结构设置 Express 的静态资源目录,将 Web 前端的 Webpack 构建目录设置成 Express 的静态资源目录设置单页应用的路由和路由服务启动服务查看页面是否可以渲染成功

以上实现过程记录在一个简单的示例 rewatch 里,入口文件是 app.js。此时前后端分离,可以同时启动服务端 Express 服务和启动开发态 React 调试页面服务(webpack-dev-server),并使用开发态页面向 Express 服务发送请求获取接口数据(当时使用 JQuery 的$.ajax 发送请求)。设计完成后将开发态页面使用 Webpack 打包构建,构建目录为服务端 Express 的静态资源目录。首屏渲染的工作交给 Ejs 模板引擎(事实上也可以直接使用 HTML 字符串渲染)进行处理。大致结构如下:

react-full

实现 React 服务端渲染(SSR)

单页应用在路由跳转时不需要额外的请求静态资源,可以提升用户的体验。但是如果应用较大,首次请求静态资源和进行页面动态渲染的过程中会产生以下问题:

首屏加载慢,产生白屏效果不利于 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 应用,大致的技术选型如下:

EjsBootstrapAngular-ChartMongooseRedisSokect.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 应用,大致技术选型如下:

MongooseNuxtVuelokkaMuse-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 等)性能、监控等简单的起手式MongoDBEjs 模板引擎JQueryJQuery 内置的$.ajaxBootstrap(可选)客户端和服务端都不需要 Webpack 配置

对于 Express 新手而言,可以先尝试多页应用 + MongoDB + 模板引擎 + JQuery 的选型方案:

使用 Ejs 模板引擎需要额外了解 Ejs 语法,但是语法相对简单,学习成本低。使用 JQuery 不需要考虑 HTTP 请求库选型,JQuery 内置了 HTTP 请求的 API。如果对于页面布局以及样式设计不熟悉,可以考虑选用 Bootstrap 前端框架。不需要深入了解 ES6 / ES7 / JSX 等语法,因此不需要学习和使用 Webpack 配置。使用 Ejs 模板引擎进行渲染的 Express 应用,是天然的服务端渲染应用。主流框架的应用设计MongoDB无需模板引擎React / Vue 等axios / request / superagent 等Ant Design / Ant Design Vue / Element / Muse-UI 等客户端 Webpack 配置服务端是否需要 Webpack / Backpack 配置依据情况而定

如果前端框架选型是 React 或 Vue(通常是单页应用设计),并且需要使用 ES6 / ES7 / JSX 以及 Vue 的 SFC 格式等语法,那么Web前端势必要设计 Webpack 的构建配置,此时可以使用类似于 webpack-dev-server 的 Express 开发态渲染服务器设计和调试开发态前端页面。当然目前的 Web 前端开发针对不同的前端框架都有自己设计的脚手架,因此可以直接使用脚手架进行开发设计和静态资源构建。同时如果框架中没有内置 HTTP 请求库,可以自己封装或者使用一些成熟的 HTTP 库,例如axios、request以及superagent等。如果需要使用 UI 组件库进行页面设计,可以根据使用的框架进行 UI 组件库选型,例如 React 的 Ant Design、Vue 的 Element 等。Express 服务端的设计由于使用了主流框架的动态渲染能力,因此可以去除模板引擎渲染功能。如果想支持 Node.js 不支持的 ES6 / ES7 / TypeScript 语法等,那么需要 Backpack 进行服务端构建。

**温馨提示:**主流框架的应用设计和简单的起手式不同,前后端开发可以完全分离,这样的应用设计大大解放了前端的生产力(前端不再受限于服务端的模板引擎)。例如目前的主流框架设计的一些脚手架,可以优雅的将 Webpack 配置,开发态渲染服务器以及请求代理结合在一起,做到开箱即用,提升用户的开发体验。

推荐Vue学习资料文章:

《带你五步学会Vue SSR》

《记一次Vue3.0技术干货分享会》

《Vue 3.x 如何有惊无险地快速入门「进阶篇」》

《「干货」微信支付前后端流程整理(Vue+Node)》

《带你了解 vue-next(Vue 3.0)之 炉火纯青「实践」》

《「干货」Vue+高德地图实现页面点击绘制多边形及多边形切割拆分》

《「干货」Vue+Element前端导入导出Excel》

《「实践」Deno bytes 模块全解析》

《细品pdf.js实践解决含水印、电子签章问题「Vue篇」》

《基于vue + element的后台管理系统解决方案》

《Vue仿蘑菇街商城项目(vue+koa+mongodb)》

《基于 electron-vue 开发的音乐播放器「实践」》

《「实践」Vue项目中标配编辑器插件Vue-Quill-Editor》

《基于 Vue 技术栈的微前端方案实践》

《消息队列助你成为高薪 Node.js 工程师》

《Node.js 中的 stream 模块详解》

《「干货」Deno TCP Echo Server 是怎么运行的?》

《「干货」了不起的 Deno 实战教程》

《「干货」通俗易懂的Deno 入门教程》

《Deno 正式发布,彻底弄明白和 node 的区别》

《「实践」基于Apify+node+react/vue搭建一个有点意思的爬虫平台》

《「实践」深入对比 Vue 3.0 Composition API 和 React Hooks》

《前端网红框架的插件机制全梳理(axios、koa、redux、vuex)》

《深入Vue 必学高阶组件 HOC「进阶篇」》

《深入学习Vue的data、computed、watch来实现最精简响应式系统》

《10个实例小练习,快速入门熟练 Vue3 核心新特性(一)》

《10个实例小练习,快速入门熟练 Vue3 核心新特性(二)》

《教你部署搭建一个Vue-cli4+Webpack移动端框架「实践」》

《2020前端就业Vue框架篇「实践」》

《详解Vue3中 router 带来了哪些变化?》

《Vue项目部署及性能优化指导篇「实践」》

《Vue高性能渲染大数据Tree组件「实践」》

《尤大大细品VuePress搭建技术网站与个人博客「实践」》

《10个Vue开发技巧「实践」》

《是什么导致尤大大选择放弃Webpack?【vite 原理解析】》

《带你了解 vue-next(Vue 3.0)之 小试牛刀【实践】》

《带你了解 vue-next(Vue 3.0)之 初入茅庐【实践】》

《实践Vue 3.0做JSX(TSX)风格的组件开发》

《一篇文章教你并列比较React.js和Vue.js的语法【实践】》

《手拉手带你开启Vue3世界的鬼斧神工【实践】》

《深入浅出通过vue-cli3构建一个SSR应用程序【实践】》

《怎样为你的 Vue.js 单页应用提速》

《聊聊昨晚尤雨溪现场针对Vue3.0 Beta版本新特性知识点汇总》

《【新消息】Vue 3.0 Beta 版本发布,你还学的动么?》

《Vue真是太好了 壹万多字的Vue知识点 超详细!》

《Vue + Koa从零打造一个H5页面可视化编辑器——Quark-h5》

《深入浅出Vue3 跟着尤雨溪学 TypeScript 之 Ref 【实践】》

《手把手教你深入浅出vue-cli3升级vue-cli4的方法》

《Vue 3.0 Beta 和React 开发者分别杠上了》

《手把手教你用vue drag chart 实现一个可以拖动 / 缩放的图表组件》

《Vue3 尝鲜》

《总结Vue组件的通信》

《Vue 开源项目 TOP45》

《2020 年,Vue 受欢迎程度是否会超过 React?》

《尤雨溪:Vue 3.0的设计原则》

《使用vue实现HTML页面生成图片》

《实现全栈收银系统(Node+Vue)(上)》

《实现全栈收银系统(Node+Vue)(下)》

《vue引入原生高德地图》

《Vue合理配置WebSocket并实现群聊》

《多年vue项目实战经验汇总》

《vue之将echart封装为组件》

《基于 Vue 的两层吸顶踩坑总结》

《Vue插件总结【前端开发必备】》

《Vue 开发必须知道的 36 个技巧【近1W字】》

《构建大型 Vue.js 项目的10条建议》

《深入理解vue中的slot与slot-scope》

《手把手教你Vue解析pdf(base64)转图片【实践】》

《使用vue+node搭建前端异常监控系统》

《推荐 8 个漂亮的 vue.js 进度条组件》

《基于Vue实现拖拽升级(九宫格拖拽)》

《手摸手,带你用vue撸后台 系列二(登录权限篇)》

《手摸手,带你用vue撸后台 系列三(实战篇)》

《前端框架用vue还是react?清晰对比两者差异》

《Vue组件间通信几种方式,你用哪种?【实践】》

《浅析 React / Vue 跨端渲染原理与实现》

《10个Vue开发技巧助力成为更好的工程师》

《手把手教你Vue之父子组件间通信实践讲解【props、$ref 、$emit】》

《1W字长文+多图,带你了解vue的双向数据绑定源码实现》

《深入浅出Vue3 的响应式和以前的区别到底在哪里?【实践】》

《干货满满!如何优雅简洁地实现时钟翻牌器(支持JS/Vue/React)》

《基于Vue/VueRouter/Vuex/Axios登录路由和接口级拦截原理与实现》

《手把手教你D3.js 实现数据可视化极速上手到Vue应用》

《吃透 Vue 项目开发实践|16个方面深入前端工程化开发技巧【上】》

《吃透 Vue 项目开发实践|16个方面深入前端工程化开发技巧【中】》

《吃透 Vue 项目开发实践|16个方面深入前端工程化开发技巧【下】》

《Vue3.0权限管理实现流程【实践】》

《后台管理系统,前端Vue根据角色动态设置菜单栏和路由》

作者:前端迷

转发链接:

标签: #jquerysubs