Express进阶升级🆙

445 阅读10分钟

本篇文章,学习记录于:尚硅谷🎢 文章简单学习总结:如有错误 大佬 👉点.

前置知识:需要掌握了解: JavaScript基础语法Node.JS环境API前端工程\模块化ExpressMongoDB

好久没更新了,焦虑、迷茫、一瞬间又到了四月,重温了《四月是你的谎言》😭 又一次被二刺螈感动,有点想换个方向了 …

Express 模板引擎:EJS

image-20240414035036323.png

EJS -- 嵌入式 JavaScript 模板引擎 | EJS 中文文档 (bootcss.com)

模板引擎: 是一种分离用户界面和业务数据的技术,在许多语言中都有应用

随着,前后端分离导致该技术使用减少,但它仍然存在于许多网站中:Java的JSP\Thymeleaf

<%= EJS %>模板引擎: Embedded JavaScript Templates是一种简单而灵活的模板引擎,用于将数据动态渲染到网页上

EJS的核心特性: 嵌入JavaScript代码、支持变量、自定义过滤器和函数、条件判断和循环、模板复用和组合,本章简单了解即可

EJS 初体验:

初始化项目结构:

 npm i -y    #npm构建项目
 npm i ejs   #npm安装EJS库

01EJS初体验.JS: EJS本质是对模板字符串的拼接,提供比原始操作具有更高效的方式👇

使用 ejs.render(str, data, options) 直接渲染模板字符串、<%= %>:输出数据到模板响应;

 /**原始字符拼接: */
 let str = "wsm";
 let str2 = `我叫${str}`;
 console.log("原始模板字符拼接: "+str2); //我叫wsm
 ​
 /**EJS render拼接数据|模板: */
 //1.安装EJS包
 //2.导入EJS模块
 const ejs = require('ejs');
 //3.使用EJS render进行渲染
 let result = ejs.render("我叫<%= str %>", {str});
 console.log("使用EJS render函数拼接渲染结果: "+str2); //我叫wsm

EJS文件模板:

EJSEmbedded JavaScript 是一款高效的嵌入式 JavaScript 模板引擎,用于生成 HTML 页面:

  • 使用 <% %> 标签来包裹 JavaScript 代码,输出结果或执行逻辑:if-elsefor 等;
  • <%= 变量 %>:输出指定变量数据到模板;

02EJS文件模板.js:

 //EJS文件模板
 //1.安装EJS包
 //2.导入EJS模块
 const ejs = require('ejs');     //ejs模板模块;
 const fs = require('fs');       //fs文件模块;
 ​
 //声明变量
 let isl = true;
 let sejs = "Hello EJS";
 let title = "ejsDemo";
 const xiyou = ['唐僧','孙悟空','猪八戒','沙僧'];
 let templateFile = fs.readFileSync('./views/index.ejs').toString();
 ​
 //3.使用EJS render进行渲染
 let result = ejs.render(templateFile, {sejs, isl, title, xiyou});
 console.log(result);

/views/index.ejs: 文件后缀 .ejs 用于标识这是一个 EJS模板文件,开发者在项目中可以轻松识别和区分模板文件

 <!DOCTYPE html>
 <html lang="en">
 <head>
     <title><%= title %></title>
 </head>
 <body>
     <h1><%= sejs %></h1>
     <% if(isl){ %> 
         <span>登录成功: 输出遍历西游数组:</span>
         <ul>
             <% xiyou.forEach(item => { %>
             <li><%= item %></li>
             <% }) %>
         </ul>
     <% }else{ %> 
         <span>登录失败</span>
     <% } %>
 </body>
 </html>

Express结合EJS:

🆗,经过上述代码,我们可以看到通过 ejs 可以完美的生成一个前端页面数据;

那么使用,Express+EJS 就像早期Java+JSP快速创建单体项目结构; ⚙️项目构建:

 npm i -y        #npm构建项目
 npm i ejs       #npm安装EJS库
 npm i express   #npm安装Express库
 /** Express结合EJS */
 const express = require('express');     //导入 express
 const path = require('path');           //导入 path
 //创建应用对象
 const app = express();
 ​
 //1.设置 EJS 作为视图引擎
 app.set('view engine', 'ejs');
 //2.设置模板文件存放位置,模板文件: 具有模板语法内容的文件
 app.set('views', path.resolve(__dirname, './views'));
 ​
 //创建文件路由
 app.get('/index', (req, res) => {
     //声明变量
     let isl = true;
     let sejs = "Hello EJS";
     let title = "ejsDemo";
     const xiyou = ['唐僧','孙悟空','猪八戒','沙僧'];
     //3.render渲染.ejs视图并响应结果:
     res.render('index', {sejs, isl, title, xiyou});
 });
 ​
 //监听端口, 启动服务
 app.listen(5400, () => {console.log('服务已经启动, 端口 5400 正在监听中....')});

image-20240414034757073.png

Express—generator构造器:

Express 应用程序生成器

Express Generator 是一个用于快速创建 Express 应用程序骨架的工具:

帮助开发者快速创建Express应用程序的基本结构,包括目录结构、基本配置等,使开发者能够更专注于程序的业务逻辑

Express—Generator安装:

 #方式一: npx命令来运行 Express 应用程序生成器,包含在 Node.js 8.2.0 及更高版本中)
 npx express-generator   
 ​
 #方式二: 对于较老的 Node 版本,请通过 npm 将 Express 应用程序生成器安装到全局环境中并使用
 npm install -g express-generator

安装成功:常用的命令配置、使用Express—Generator构建Express项目:

  • express -h 参数可以列出所有可用的命令行参数
  • express -e 目录名 在指定目录下快速构建express项目结构,目录不存在则创建;
 #Express Generator 创建的应用程序通常具有以下目录结构:
 ├── app.js                  #app.js 是 Express 应用的主要文件,支持设置中间件、路由等配置;
 ├── bin                     #bin/www 文件是用于启动应用的脚本
 │   └── www                 #它会创建一个 HTTP 服务器并监听指定的端口
 ├── package.json            #package.json 文件包含应用的依赖和其他配置信息
 ├── public                  #public 目录用于存放静态资源
 │   ├── images              #如图像、JavaScript文件和样式表: 这些资源可以直接通过 URL 访问;
 │   ├── javascripts
 │   └── stylesheets
 │       └── style.css
 ├── routes                  #routes 目录包含路由文件
 │   ├── index.js            #这里,你可以定义应用的不同路由和对应的处理函数
 │   └── users.js
 └── views                   #views 目录用于存放视图模板文件
     ├── error.pug           #视图模板可以使用模板引擎(如 Pug、EJS 等)渲染动态内容
     ├── index.pug
     └── layout.pug

小技巧tisp🔖: 学习一个陌生项目,无从下手情况可以查看它的:package.JSON=》scripts 查看它的启动配置;

从而定位到主配置文件: bin/www 进而分析内部的功能配置、端口、文件作用;

Generator项目构建:

image-20240414144809128.png

Generator_路由配置:

🆗,到此已经完美的构建了一个Express项目,那么接下来如何使用呢?还是有点无从下手📻

image-20240414163254328.png

经过上述文件分析,我们大致了解如何定义自己的路由规则了:

  • /routes 中定义路由文件——>并配置在app.JS中进行引用、暴漏
  • /views 中定义ejs等模板资源——>app.JS中已经配置完毕

Generator_静态资源:

Express Generator 创建应用程序骨架时,Public目录负责托管静态资源(例如图像、样式表、脚本等)

 ├── public                  #public 目录用于存放静态资源
 │   ├── images              #如图像、JavaScript文件和样式表: 框架启动后可以直接通过URL访问:
 │   ├──     ├──01.png       #即可通过: http://127.0.0.1:3000/images/01.png 进行直接访问;
 │   ├── javascripts
 │   └── stylesheets
 │       └── style.css       #即可通过: http://127.0.0.1:3000/stylesheets/style.css 进行直接访问;

涉及到页面资源引用404问题:可以参考:邂逅Node.JS的那一夜

如果是在:HTML、EJS文件中引用则直接: /images/01.png/stylesheets/style.css 即可;

因为: 路径在浏览器中会自动拼接全局路径:/xxx/xx; =自动拼接IP+端口=> http://xxx:xxx/xxx/xx;

lowdb JSON本地库:

lowdb - npm (npmjs.com) NPM官网:不过多介绍了解即可;

Lowdb 是一个轻量级、简单易用的本地 JSON 数据库,适用于 Node.js、Electron 和浏览器环境

它的设计理念是使用一个 JSON 文件作为数据库,实现基本的增删改查操作,以下是关于 Lowdb 的一些重要信息:

 ├── lowdbTest               #lowdbTest 临时学习lowbd测试文件夹
 │   ├── db.json             #db.json 临时存储数据目录
 │   ├── lowdbDemo.js        #lowdb学习DemoJS
 #安装lowdb包依赖
 npm i lowdb@1.0.0   #因为不同版本有改变,所以选择了一个最常见的版本;
 //导入lowdb、FileSync模块
 const low = require('lowdb')
 const FileSync = require('lowdb/adapters/FileSync')
 ​
 //获取db对象
 const adapter = new FileSync('db.json');    //FileSync模块获取|创建文件对象,不存在则创建;
 const db = low(adapter);                    //low模块根据文件对象,创建文件的操作对象;
 ​
 //初始化|定义JSON数据结构: 
 db.defaults({ key1: [], key2: {} }).write();
 ​
 //写入数据: 给指定的的key属性中写入数据
 //因为key1是一个数组,所以以 push添加元素、unshift追加元素
 db.get('key1').push({id: 1, title: '今天天气还不错~~'}).write();        
 db.get('key1').unshift({id: 2, title: '今天天气还不错~~'}).write();
 ​
 //获取数据: 
 console.log(db.get('key1').value());
 ​
 //获取单条数据: 
 console.log(db.get('key1').find({id: 1}).value());
 ​
 //更新数据: 仅更新匹配的第一条数据;
 db.get('key1').find({id: 1}).assign({title: '今天下雨啦!!!'}).write();  
 ​
 //删除数据: 并返回删除的数据;
 // console.log(db.get('key1').remove({id: 2}).write(););
描述示例代码
初始化数据db.defaults( {posts:[]} ).write()
插入一条或多条数据db.get('posts').push({ id: 1, title: 'lowdb is awesome' }).write()
更新数据,仅匹配的第一条db.get('posts').find({ id: 1 }).assign({ title: 'lowdb is great' }).write()
删除一条或多条数据,同上db.get('posts').remove({ id: 1 }).write()
获取数据,可以链式调用查询db.get('posts').value()
查找满足条件的多条数据db.get('posts').filter({ published: true }).value()
查找特定条件的单条数据db.get('posts').find({ id: 1 }).value()
结束链式调用并返回结果db.get('posts').value()
检查是否存在某条数据db.has('posts').value()
获取数据的条数db.get('posts').size().value()
设置属性的值db.set('user.name', 'typicode').write()
对数据进行升序排序db.get('posts').sortBy('title').value()
对数据进行降序或自定义排序db.get('posts').orderBy('views', 'desc').value()

ExpressGenerator➕lowdb

🙂🆗,上述已经了解到了,ExpressGenerator+lowdb 那么就可以简单的开发一套API了:

  • ExpressGenerator 支持快速构建一个,Node的Express环境便于快速开发
  • lowdb可以用于简单的数据存储,以JSON形式进行保存|读取记录数据

不同是人对框架有不同的使用方式,此处是本人记录的一个使用Demo:

image-20240420161810576.png

  • 首先:定义一个data 用户存放管理自己的数据文件
  • 其次:在routes中 定义配置自己的路由规则,并定义自己的代码、操作lowdb存取数据
  • 最后:通过app.JS 文件管理配置路由封装暴漏路由请求API,如下是核心的routes中的文件📃:
 //01_lowdbAPI:
 //导入Express配置
 var express = require('express');
 var router = express.Router();
 //导入lowdb操作数据配置
 const low = require('lowdb')
 const FileSync = require('lowdb/adapters/FileSync')     //指定定义的db.JSON数据文件路径;
 const adapter = new FileSync(__dirname+'/../data/db.json'); //FileSync模块获取|创建文件对象,不存在则创建;
 ​
 //获取db文件的操作对象;
 const db = low(adapter);
 //初始化|定义db.JSON数据结构: 
 db.defaults({shopGoods: []}).write();  //这个是一个记录超市商品的数据.JSON
 ​
 /* Post 新增商品记录 */
 //此处ExpressGenerator构造的框架是不是很熟悉;
 router.post('/addGoods', function(req, res, next) {
     //req: 请求对象信息
     //res: 响应对象信息
     //next: 指向下一个中间件、路由函数;
     db.get('shopGoods').unshift(req.body).write();
     res.send('添加记录成功!!!');
 });
 ​
 /* GET 获取所有的商品 */
 router.get('/goods', function(req, res, next) {
     const goods =  db.get('shopGoods').value();
     res.send(goods);
 });
 ​
 module.exports = router;

image-20240420162833534.png

🥳Perfect🎉很完美,如此我们就可以快速的开始我们的CRUD编码✍

shortid 优化ID

优化: 上述,新增商品,还需要手动添加ID:我们都知道世纪情况下ID一般都是自动生成的;

而: lowdb 本身其实是一个快速操作JSON的包,并没有默认ID的功能;

so: 万能的NPM仓库,就有一款ID生成包:shiortid 🆔

🆗 welcome let's go 让我们开始吧!🪶 npm i shortid 安装包依赖!!!

 //优化: /addGoods shortid设置默认ID
 const shortid = require("shortid");
 router.post('/addGoods', function(req, res) {
     //生成ID
     let id = shortid.generate();
     //ES6语法: 解构赋值、...扩展运算符 真好用<^^>
     db.get('shopGoods').unshift({ id,...req.body }).write();
     res.send('添加记录成功!!!');
 });

ExpressGenerator➕MongoDB

关于MongoDB的整合,前置知识: 前端工程\模块化Node携手MongoDB探险旅行⛏️当然如大佬直接跳过

介绍一下 Node携手MongoDB探险旅行 这篇文章中:mongoose模块化 的目录结构;

image-20240421012205835.png

  • config.JS 数据库连接配置文件

  • /db/dbutil.JS Mongodb的配置文件:

    暴漏函数function(成功,失败),函数内进行mongodb 数据库连接,连接成功调用success,失败调用error

  • index.JS 主文件: Node项目启动的主文件,内部导入dbutil.JSuserModel.JS 声明MB的数据结构模型

    调用dbutil模块函数数据库连接成功调用,success(){ 中使用userModel操作对应MB数据 }


🆗,了解了核心代码就开始构建整合自己的项目结构了: 别忘了启动Mongodb服务...

image-20240421031711006.png

  • 导入:db、models、config.JS 文件模块:

  • bin/www 是该框架的启动类型: 为了保证mongodb连接成功 使用,

    将整个 www 启动类代码包装在 dbutil模块函数的success中进行启动配置,

  • 接下来就是正常的路由代码编写,app.JS路由配置 好像也不是很复杂,这里就简单介绍一下拉~