前端必须的服务端项目,node + express (这篇文章就够用)包含源代码

作为一个前端程序员,刚开始入门的时候,你觉得只要学习前端代码(js + css + html)就行了,实际上,到后面很多知识都涉及到服务端,在我们学习的过程中难免需要写一些 demo。比如在浏览器的缓存、或者跨域的知识中,我们需要手动写服务端的代码给响应头增加一些字段才能实现,只有我们自己写出来的代码才能彻底理解。

所以在我们继续学习前端工程化的知识之前,需要学习搭建一个基本的服务端项目,我们前端常用的服务端工具是 express 或者 koa。

一、koa vs express

koa 使用基于 promise的中间件机制,express 使用基于回调函数的中间件机制。但是 express 的社区比较活跃,我们还是使用express 吧,基本上可以实现所有我们想要的功能。

不过无论是koa 还是express 都是基于 node 原生的 http 模块封装的 npm 包,node 中有一个 核心模块 http,是node 网络的关键模块,也是一个很重要的模块。官网文档地址在这里

二、node vs 浏览器

2.1 node 到底是啥

遥想在刚入行的时候,我曾经无数次搜索这个问题,无数次的打开node 的官网,就是搞不通node 到底是啥,我不信只有我一个人这样,不过现在我悟了。如果你还不知道node 到底是个啥?那看看这篇文章

总之一句话, node 可以运行js代码,node 里面有的东西浏览器中不一定有,浏览器中有的东西 node 也不一定有。

2.2 网络请求

作为一个菜鸟,一提到网络请求,你肯定会想到 ajax,怎么实现 ajax?你肯定会想到那必然是使用 XMLHttpRequest 或者 fetch 或者用 axios

你不会又去搜索 ajax 是啥了吧?

我已经为你准备好了,看这里

你还需要知道,axios 就是基于 XMLHttpRequest  封装的。

没错,你想的一点都没错,但是你要注意到,无论是 XMLHttpRequest,还是fetch,都是前端的网络请求方式,也就是浏览器的功能。

node 中是不支持 XMLHttpRequest 和 fetch 的,不信你可以测试一下

  1. 首先你安装了 node ,打开 vscode,随便新建一个 test.js 文件,然后输入下面的内容
    const a = new XMLHttpRequest()
    console.log(a)
  2. 然后点击这个按钮运行,会报错

  3. 这就是在 node 中运行 js 代码,然后结果是 XMLHttpRequest 不存在

  4. 如果在浏览器中就不同了,你可以随便打开一个网页的开发者工具试一下

总之,我们要学会区分前端和服务端,前端代码运行在浏览器中,使用浏览器支持的请求方式(如 XMLHttpRequest)发起网络请求;node 的网络请求是用于服务端的,node 使用自己的核心模块 http 完成网络请求。

2.3 应用

不少人觉得前端学习写服务端代码没啥用,其实不然,除了我之前说的在学习新知识写 demo 的时候会用到之外,还有应用的场景。

比如开发 electron 应用,electron 基于 chromium【就是chrome的基础】 和 node,是开发桌面端应用的好工具,要实现一个完整的桌面端应用,就需要写 node 相关的服务端代码,比如用来操作本地数据库之类的敏感操作,肯定是不能前端完成了。

所以学习写服务端代码也是很重要的。

三、构建 express 

3.1 新建仓库

我的仓库地址是 learn-express

3.2 初始化

3.2.1 增加 .nvmrc

没错,牢记!所有的项目,只要和node 有关,我们都要增加这个文件为了锁定node版本。

3.2.2 增加 package.json

node 项目需要使用 npm init 初始化项目,运行之后会增加一个 package.json 文件。

npm init

3.2.3 提交代码

3.3 安装express

pnpm i express

3.4 增加 .gitignore

初始化的时候不增加 .gitignore 还好,但是如果增加了任何 npm 包,安装之后必定会有一个 node_modules 文件夹,里面文件内容极多,所以必须要增加 .gitingore 文件。

3.5 新建 index.js

从 express 官网复制代码到 index.js 中

3.6 运行 index.js

接下来,就是需要运行这个 index.js, 我们可以点击编辑器的运行功能运行,但是既然我们都用了node 了,自然是要用 node 的命令运行代码更方便了。

在 package.json 中增加运行脚本

然后我们运行 npm run dev 即可。

此时我们在浏览器中打开 localhost:3000,我们已经成功启动了一个服务器。

 

虽然我们没有新建 html 文件,但是页面上会渲染 res.send 返回的结果,这是浏览器的功能

你在浏览器的输入栏输入任意一个 get 请求,返回的结果都会在页面上展示。

所以其实我们可以在 res.send 的时候返回一些更复杂的html代码,比如 

res.send(`<h1>你好你好</h1> `)

这样的话,页面就会展示出一个 h1 标签,在服务端拼接完整的 html 代码,这就是服务端渲染的原理。

服务端渲染 server-side rendering 简称 ssr。是一种在服务端生成并直接返回已经拼接好了的页面给客户端的方式。 ssr 有利于 seo,你又该问seo是啥了?

  • seo 是搜索引擎(百度、谷歌等)优化,seo 是一系列的技术和策略,旨在提高网站在搜索引擎中的排名。

我们常用的非服务端渲染的框架,比如普通的vite项目 vue + vite,可以关注我的《前端工程化专栏中的系列教程》之 手把手搭建 vite + ts +vue3项目

服务端渲染的框架有 nuxt,可以关注我的《前端工程化专栏中的系列教程》之 完整的nuxt3 + vue + ts 项目教程

如果你用的是 react 那么就可以用next框架

nuxt  next 傻傻分不清~学习之路,任重道远

3.7 提交代码

四、增加index.html

现在我们有了一个服务器,还缺一个客户端,也就说少一个 html 文件写前端的代码。然后访问服务端的地址,就展示我们自己写的 html 页面。

4.1 增加 index.html

4.2 更改 index.js

我们的目的是访问根目录,返回自定义的 index.html 的内容,所以需要修改服务端代码即可。

现在,我们再运行 npm run dev ,访问 localhost:3000 页面就会访问我们自定义的 html 了。

4.3 提交代码

五、增加各种请求

5.1 get 请求

5.1.1 修改 index.js

const express = require('express')
const path = require('path')const app = express()app.get('/', function (req, res) {res.sendFile(path.resolve('index.html'), )
})app.get('/userInfo', function (req, res) {res.status(200).end(JSON.stringify({uid: 1,name: 'test'}))
})app.listen(3000)

5.1.2 修改 index.html

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><h1>这是自定义的html页面</h1><button onclick="getUserInfo()">获取userInfo</button><script>function getUserInfo() {fetch('/userInfo').then((res) => {return res.json()}).then(data => {console.log('用户信息', data)})}</script>
</body>
</html>

5.1.3 运行 

npm run dev

注意这里面前端代码,有 fetch API 的知识点,如果你不会用那就需要学习一下了,具体请看官网

在这个例子中,服务端返回了 json 类型的数据,fetch API 接收到数据后,首先需要使用 res.json() 进行解析,然后下一个 then 的回调中才能获取 json 真实的数据,并且是已经解析过的,请看 response.json()

其他的请求方式,比如 post 、put 等都是大同小异,可以自己在 express 的官网看如何使用。

5.1.4 提交代码

5.2 ejs 模版引擎

5.2.1 模版引擎是啥

模版引擎是一种用于在网页、应用程序或者其他文档中嵌入动态数据的工具或框架,他们允许开发人员将静态模版与动态数据结合,以生成最终的输出,模版引擎通常用于将数据与模版进行结合,生成最终的HTML、XML、JSON 等输出。

首先要明确一件事情,浏览器最终渲染的页面都是 html,这也是为什么我们小白入门要先学习 html + css,因为 html 是本质,也最简单。 所以我们在写 vue 项目的时候,在 .vue 文件中的 template 里面写的代码,最终都会被 vue 的模版引擎编译成 html 文件,然后再渲染。

5.2.2 模版引擎的原理

模板引擎的原理基本上是通过将模板中的标记(markup)和逻辑与数据结合起来,生成最终的输出。下面是一个简化的模板引擎的工作原理:

  1. 解析: 模板引擎首先对输入的模板进行解析,识别模板中的标记和逻辑结构。这可能涉及到词法分析和语法分析,以将模板转换为内部的数据结构或语法树。

  2. 编译: 解析完成后,模板引擎会将解析得到的数据结构编译成可执行的代码。这些代码通常是目标语言(如JavaScript、Python等)的代码,用于动态地生成最终的输出。

  3. 数据绑定: 模板引擎将编译后的代码与数据进行绑定。这意味着模板中的变量或表达式会与特定的数据源关联,以便在最终输出时能够动态地替换这些部分。

  4. 输出生成: 当需要生成最终输出时,模板引擎执行编译后的代码,根据数据生成最终的文本输出。这可能包括HTML、XML、JSON等格式,具体取决于模板引擎的用途和设计。

  5. 缓存: 为了提高性能,一些模板引擎可能会对已经编译过的模板进行缓存,以避免重复的解析和编译过程。

不同的模板引擎在实现上可能存在一些差异,但上述步骤基本涵盖了模板引擎的通用原理。关键在于将模板中的标记和逻辑与数据进行有效地组合,以生成最终的动态输出。

在前端开发中,例如在Vue.js中,模板引擎的原理也涉及到虚拟DOM的概念,以便更高效地进行DOM更新。虚拟DOM是一个内存中的表示,通过比较虚拟DOM和实际DOM的差异,最小化DOM操作,提高性能。这在响应式框架中尤为重要,因为它允许框架更有效地追踪数据变化并更新视图。

5.2.3 安装 ejs

pnpm i ejs

关于 express 使用 ejs 的方法可以再 express 的官方 demo 中找到例子也可以去看 ejs 的官方例子。

没错,如果你想学习一个新的 npm 包如何使用,最好是去 npm 官网上搜

点击 homepage 主页或者 github 仓库

一个成熟的 npm 项目中一般有一个实例(examples)文件夹,里面有详细的代码

5.2.4 修改 index.js

5.2.5 新建 template.html

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><h1><%= name %></h1>
</body>
</html>

5.2.6  运行并访问 

运行 npm run dev 可以访问 localhost:3000/template

5.2.7 提交代码

这种使用模版引擎的方式,可以直接在服务端设置变量名,然后渲染在页面上,很方便。相比于第四章的使用的 index.html 的方式,如果 index.html 文件要渲染某一个服务端的变量,那么就只能先用请求获取,再用js设置了,比较麻烦。

不过,在以后的教程中我还是会用第四章的index.html的形式,因为逻辑比较简单。

六、整理项目结构

好了,现在我们有了一个简单的服务器的项目,可以供我们后续学习使用,我们整理一下项目结构,让他具有可扩展性,以后新增一个功能就新建一个文件夹。

6.1 新建 ejs 文件夹

在根目录新建 ejs 文件夹,并把 template.html 文件夹移到 ejs 文件夹中,做适当修改

6.2 新建 ejs/index.js

新建 ejs/index.js 并且把之前的index.js中关于模版引擎的代码复制进去,做适当的修改

const express = require('express')
const path = require('path')const app = express()app.engine('.html', require('ejs').__express);
// 设置默认路径 在 ejs 文件夹下
app.set('views', path.join(path.resolve(), 'ejs'));
// 设置引擎文件后缀名是 .html
app.set('view engine', 'html');// 访问路径 改成 /ejs
app.get('/ejs', function (req, res) {res.render('template', {ejsName: 'ejs 你好你好'})
})app.listen(3000)

6.3 运行

想要运行 ejs 文件夹里面的 index.js 已经不能直接运行npm run dev,因为在package.json中我们是这样写的

 我们要改一下

然后运行 npm run dev 就可以了

6.3 提交代码

七、增加通用运行脚本

在第六章我们成功的运行了 ejs 目录下的 index.js ,但是好麻烦哦,如果后面我们又加了别的功能,那还得改 package.json,累死了,所以下面我们下一个通用的方法。

7.1 修改 package.json

7.2 新增 start.js

在根目录新增 start.js ,用于 npm run dev 的时候执行,在这个文件文件里面执行 node 命令

const { exec } = require('child_process')// 获取运行命令的参数
// 假设运行 npm run dev ejs ,那么就得到 process.argv[2] === ejs
// 为什么是第2个参数,因为在package.json中已经有两个了,
// 我们可以打印出来看看
console.log('node 参数', process.argv)// 获取当前运行的服务
const funDir = process.argv[2] || '.'// 实际执行的米娜领
const command = `node ${funDir}/index.js`
// child_process 是 node 的子进程, exe c可以执行node 命令
exec(command)

7.2 运行脚本

npm run dev ejs

可以完美的运行!如果不加参数,哪就是运行根目录的 index.js。

7.3 提交代码

总结

好了,现在我们有一个完美的服务端项目了,以后我们可以用这个项目写很多服务端的代码。本篇文章的全部流程如下:

我的仓库地址如下

yangjihong2113/learn-express

内容比较多,难免疏漏,有不对的地方欢迎评论区指出。

这是一个系列的教程,正在持续更新中,欢迎大家关注我的专栏《前端工程化系统教程》

我还有另外一个正在更新的专栏《一网打尽面试题》会总结所有的面试题。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/582844.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

公司防泄密软件监控员工哪些行为?

公司防泄密软件通常监控员工在使用电脑和其他存储设备时的一系列行为&#xff0c;以确保数据安全和防止敏感信息泄露。以下是一些公司防泄密软件可能监控的员工行为&#xff1a; 文件访问和操作&#xff1a; 软件可能会监控员工对文件的访问、打开、编辑、复制和移动操作。异常…

基于鸿蒙OS开发一个前端应用

创建JS工程&#xff1a;做鸿蒙应用开发到底学习些啥&#xff1f; 若首次打开DevEco Studio&#xff0c;请点击Create Project创建工程。如果已经打开了一个工程&#xff0c;请在菜单栏选择File > New > Create Project来创建一个新工程。选择HarmonyOS模板库&#xff0c…

【MYSQL】-表的约束

&#x1f496;作者&#xff1a;小树苗渴望变成参天大树&#x1f388; &#x1f389;作者宣言&#xff1a;认真写好每一篇博客&#x1f4a4; &#x1f38a;作者gitee:gitee✨ &#x1f49e;作者专栏&#xff1a;C语言,数据结构初阶,Linux,C 动态规划算法&#x1f384; 如 果 你 …

Redis管道

问题引出 Redis是一种基于客户端-服务端模型以及请求/响应协议的TCP服务。一个请求会遵循以下步骤&#xff1a; 1 客户端向服务端发送命令分四步(发送命令→命令排队→命令执行→返回结果)&#xff0c;并监听Socket返回&#xff0c;通常以阻塞模式等待服务端响应。 2 服务端…

B (1038) : DS哈希查找—二次探测再散列

文章目录 一、题目描述二、输入与输出1.输入2.输出 三、参考代码 一、题目描述 定义哈希函数为H(key) key%11。输入表长&#xff08;大于、等于11&#xff09;&#xff0c;输入关键字集合&#xff0c;用二次探测再散列构建哈希表&#xff0c;并查找给定关键字。 二、输入与输…

用户规模破亿!基于文心一言的创新应用已超4000个

&#x1f935;‍♂️ 个人主页&#xff1a;艾派森的个人主页 ✍&#x1f3fb;作者简介&#xff1a;Python学习者 &#x1f40b; 希望大家多多支持&#xff0c;我们一起进步&#xff01;&#x1f604; 如果文章对你有帮助的话&#xff0c; 欢迎评论 &#x1f4ac;点赞&#x1f4…

1.3MySQL中的自连接

自己的表和自己连接&#xff0c;核心&#xff1a;一张表拆为两张一样的表。 语法&#xff1a;select 字段列表 from 表 [as] 表别名1,表 [as] 表别名2 where 条件...; 关于怎样把一个表拆分成一个表&#xff0c;只要给它们分别取别名就行 categoryidpidcategoryname21信息…

Analytify Pro Google Analytics Goals Addon谷歌分析目标插件

Analytify Pro Google Analytics Goals Addon谷歌分析目标插件是一款极其巧妙且具有开创性的工具&#xff0c;它赋予用户细致跟踪和全面分析其网站性能的卓越能力。有了这个非凡的插件&#xff0c;个人可以毫不费力地建立并认真监控他们的Google Analytics目标&#xff0c;从而…

conda环境下Could not build wheels for dlib解决方法

1 问题描述 在安装模型运行的conda环境时&#xff0c;出现如下问题&#xff1a; Building wheels for collected packages: basicsr, face-alignment, dlib, ffmpy, filterpy, futureBuilding wheel for basicsr (setup.py) ... doneCreated wheel for basicsr: filenamebasi…

记录一下亿级别数据入库clickhouse

需求背景 公司的业务主要是广告数据归因的&#xff0c;每天的pv数据和加粉数据粗粗算一下&#xff0c;一天几千万上亿是有的。由于数据量大&#xff0c;客户在后台查询时间跨度比较大的数据时&#xff0c;查询效率就堪忧。因而将数据聚合后导到clickhouse进行存储&#xff0c;…

32阵元 MVDR和DREC DOA估计波束方向图对比

32阵元 MVDR和DREC DOA估计波束方向图对比 一、原理 MVDR原理&#xff1a;https://zhuanlan.zhihu.com/p/457528114 DREC原理&#xff08;无失真响应特征干扰相消器&#xff09;&#xff1a;http://radarst.ijournal.cn/html/2019/3/201903018.html 主要参数&#xff1a; 阵…

完全适配各类中小医院专科医院和诊所的云HIS系统源码【前端:Angular+Nginx ,后台:SpringBoot】

云HIS系统采用SaaS软件应用服务模式&#xff0c;提供软件应用服务多租户机制&#xff0c;实现一中心部署多机构使用。相对传统HIS单机构应用模式&#xff0c;它可灵活应对区域医疗、医疗集团、医联体、连锁诊所、单体医院等应用场景&#xff0c;并提升区域内应用的标准化与规范…

Java技术栈 —— Nginx的使用

Java技术栈 —— Nginx的使用 一、认识Nginx二、搭建Nginx环境2.1 在Ubuntu上安装Nginx 三、使用Nginx3.1 配置负载均衡(HTTP) 一、认识Nginx 企业需要运行多个相同的副本&#xff0c;并将负载分散在整个系统集群上&#xff0c;为了高性能的负载均衡&#xff0c;引入了Nginx代…

通过C++程序实现光驱的自动化刻录和读取

文章目录 ISO文件格式光盘的基本概念光盘种类特点DVDR光盘使用windows调用Linux调用Linux平台下用到的C库:读取设备驱动列表向光驱中写文件 数字存储媒体快速发展的今天&#xff0c;光驱的使用已经不像以前那样普及了。但是在数据备份、安装软件和操作系统、旧设备兼容等领域还…

PiflowX大数据流水线系统

PiflowX大数据流水线系统。支持分布式计算引擎flink和spark。以所见即所得的方式&#xff0c;实现大数据采集、处理、存储与分析流程化配置、运行与智能监控。 PiflowX基于Piflow&#xff08;PiFlow: 混合型科学大数据流水线系统&#xff0c;包含丰富的处理器组件&#xff0c;…

算法导论复习(七) 动态规划

动态规划一般用来求解最优化问题 设计一个动态规划算法一般有以下四步&#xff1a; 描述一个最优解的结构特征。递归地定义最优解的值。计算最优解的值&#xff0c;通常采用自底向上的方法。利用计算出的信息构造出一个最优解。 钢条切割问题 体现了动态规划的一个重要性质&a…

k8s 网络

还没有部署网络。 k8s的网络类型&#xff1a; k8s中的通信模式&#xff1a; 1&#xff0c;pod内部之间容器和容器之间的通信。 在同一个pod中的容器共享资源和网络&#xff0c;使用同一个网络命名空间。可以直接通信的。 2&#xff0c;同一个node节点之内不同pod之间的通信。…

大创项目推荐 深度学习YOLO抽烟行为检测 - python opencv

文章目录 1 前言1 课题背景2 实现效果3 Yolov5算法3.1 简介3.2 相关技术 4 数据集处理及实验5 部分核心代码6 最后 1 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; 基于深度学习YOLO抽烟行为检测 该项目较为新颖&#xff0c;适合作为竞赛课…

BAQ压缩MATLAB仿真

本专栏目录: ​​​​​​​全球SAR卫星大盘点与回波数据处理专栏目录-CSDN博客 我们按照上一期文章的BAQ原理编写MATLAB代码,进行baq压缩与解压缩的全流程验证,并分析BAQ压缩对信号指标造成的影响。 生成3个点目标回波数据,加入高斯噪声,对回波进行BAQ压缩和解BAQ压缩,…

具有出色的数据速率、SI8642BA-AUR、SI8642BB-AS1R、SI8641BB-B-IUR、SI8635BD-B-ISR低功耗数字隔离器

一、简介 Si86xx 超低功耗数字隔离器系列是CMOS器件&#xff0c;与传统隔离技术相比&#xff0c;具有出色的数据速率、传播延迟、功耗、尺寸、可靠性和外部BOM优势。这些产品的工作参数在宽温度范围内和整个设备使用寿命内保持稳定&#xff0c;便于设计和高度统一的性能。所有…