全栈开发小项目
用到的技术栈:
nodejs+webpack+knockout+mongodb+PM2+rabbitmq
以下是一个综合指南,展示如何将 Node.js、Webpack、Knockout.js、MongoDB、PM2 和 RabbitMQ 集成到一个项目中。
我们将在这一项目中添加 RabbitMQ,用于处理消息队列。这对于任务分派、异步处理等场景非常有用。
第一步: 初始化项目
首先,创建一个新的项目目录并初始化一个 Node.js 项目:
Copy
mkdir my-app
cd my-app
npm init -y
这将在 my-app 目录下创建一个 package.json 文件。
第二步: 安装依赖
我们需要安装以下依赖库:
项目依赖
express: 用于创建服务器
mongoose: 用于连接和操作 MongoDB
knockout: 用于创建响应式 UI
amqplib: AMQP 0-9-1 客户端,用于与 RabbitMQ 交互
Copy
npm install express mongoose knockout amqplib
开发依赖
webpack: 用于打包前端代码
webpack-cli: 命令行工具,用于运行 Webpack
webpack-dev-server: 开发服务器,提供实时重新加载功能
Copy
npm install --save-dev webpack webpack-cli webpack-dev-server
安装 PM2
PM2 是一个进程管理器,用于长时间运行的 Node.js 应用程序:
Copy
npm install pm2 -g
如果希望本地安装 PM2,也可以用以下命令:
Copy
npm install pm2 --save-dev
第三步: 创建服务器文件
创建 server.js
在根目录下创建一个 server.js 文件,并添加以下代码:
Copy
const express = require(‘express’);
const mongoose = require(‘mongoose’);
const amqp = require(‘amqplib/callback_api’);
// 连接到本地 MongoDB 数据库 myapp
mongoose.connect(‘mongodb://localhost:27017/myapp’, {
useNewUrlParser: true,
useUnifiedTopology: true
});
const app = express();
app.use(express.json());
// 定义一个 Mongoose 模型
const ItemSchema = new mongoose.Schema({
name: String
});
const Item = mongoose.model(‘Item’, ItemSchema);
// API 路由
app.get(‘/items’, async (req, res) => {
const items = await Item.find();
res.json(items);
});
app.post(‘/items’, async (req, res) => {
const newItem = new Item(req.body);
await newItem.save();
// 发送消息到 RabbitMQ
sendToQueue(newItem);res.json(newItem);
});
// 启动服务器
app.listen(3000, () => {
console.log(‘Server is listening on port 3000’);
});
// 连接到 RabbitMQ 并发送消息
function sendToQueue(item) {
amqp.connect(‘amqp://localhost’, (error0, connection) => {
if (error0) {
throw error0;
}
connection.createChannel((error1, channel) => {if (error1) {throw error1;}const queue = 'itemQueue';const msg = JSON.stringify(item);channel.assertQueue(queue, {durable: false});channel.sendToQueue(queue, Buffer.from(msg));console.log(" [x] Sent %s", msg);});setTimeout(() => {connection.close();}, 500);
});
}
注意: 请确保你的 RabbitMQ 和 MongoDB 服务器正在运行。你可以使用以下命令启动它们:
Copy
启动 MongoDB
mongod
启动 RabbitMQ (RabbitMQ 必须已经安装)
rabbitmq-server
消费 RabbitMQ 队列中的消息
创建一个 consumer.js 文件,用于消费队列中的消息:
Copy
const amqp = require(‘amqplib/callback_api’);
amqp.connect(‘amqp://localhost’, (error0, connection) => {
if (error0) {
throw error0;
}
connection.createChannel((error1, channel) => {
if (error1) {
throw error1;
}
const queue = 'itemQueue';channel.assertQueue(queue, {durable: false});console.log(" [*] Waiting for messages in %s. To exit press CTRL+C", queue);channel.consume(queue, (msg) => {const item = JSON.parse(msg.content.toString());console.log(" [x] Received %s", item.name);// 在这里处理收到的消息}, {noAck: true});
});
});
启动 PM2 管理器
PM2 可以用于同时启动我们的 server.js 和 consumer.js 。
更新 package.json 脚本:
Copy
“scripts”: {
“start”: “webpack serve”,
“serve”: “webpack build && pm2 start ecosystem.config.js”
}
创建 ecosystem.config.js:
Copy
module.exports = {
apps: [{
name: ‘server’,
script: ‘server.js’,
instances: 1,
autorestart: true,
watch: false,
max_memory_restart: ‘1G’
}, {
name: ‘consumer’,
script: ‘consumer.js’,
instances: 1,
autorestart: true,
watch: false,
max_memory_restart: ‘1G’
}]
};
配置 Webpack
在根目录下创建一个 webpack.config.js 文件,并添加以下代码:
Copy
const path = require(‘path’);
module.exports = {
entry: ‘./src/main.js’,
output: {
filename: ‘bundle.js’,
path: path.resolve(__dirname, ‘dist’)
},
devServer: {
static: {
directory: path.join(__dirname, ‘dist’),
},
compress: true,
port: 9000
},
mode: ‘development’
};
创建前端代码
创建必要的目录和文件:
Copy
mkdir src
touch src/main.js
touch src/index.html
编辑 src/index.html
Copy
Webpack + Knockout.js + MongoDB + RabbitMQ
Copy
import ko from ‘knockout’;
class ViewModel {
constructor() {
this.newItem = ko.observable(‘’);
this.items = ko.observableArray([]);
this.loadItems();this.addItem = this.addItem.bind(this);
}async loadItems() {const response = await fetch('http://localhost:3000/items');const items = await response.json();this.items(items);
}async addItem() {const response = await fetch('http://localhost:3000/items', {method: 'POST',headers: {'Content-Type': 'application/json'},body: JSON.stringify({ name: this.newItem() })});const item = await response.json();this.items.push(item);this.newItem('');
}
}
ko.applyBindings(new ViewModel());
启动应用
用 Webpack Dev Server 开发
运行以下命令来启动开发服务器:
Copy
npm start
在生产环境中用 PM2 启动
运行以下命令来构建并使用 PM2 启动服务器:
Copy
npm run serve
PM2 管理
一些常用的 PM2 命令包括:
查看所有进程:pm2 list
停止某个进程:pm2 stop <process_id>
重启某个进程:pm2 restart <process_id>
删除某个进程:pm2 delete <process_id>
查看进程日志:pm2 logs <process_id>
通过这些步骤,您已经设置了一个使用 Node.js、Webpack、Knockout.js、MongoDB、PM2 和 RabbitMQ 的综合全栈应用。这种结构对于处理复杂任务和异步操作非常有效。
17:38
相关文章:
全栈开发小项目
用到的技术栈: nodejswebpackknockoutmongodbPM2rabbitmq 以下是一个综合指南,展示如何将 Node.js、Webpack、Knockout.js、MongoDB、PM2 和 RabbitMQ 集成到一个项目中。 我们将在这一项目中添加 RabbitMQ,用于处理消息队列。这对于任务分…...
批处理一键创建扫描仪桌面打开快捷方式图标 简单直接有效 扫描文档图片的应急策略
办公生活中,我们在安装完多功能一体机的打印驱动之后,找不到扫描文件的地方,如果驱动程序安装正确,我们可以用系统自带的扫描仪程序调用这种打印机或复印机的扫描程序即可,它在电脑系统中的位置一般是:C:\W…...
【服务器知识】Tomcat简单入门
文章目录 概述Apache Tomcat 介绍主要特性版本历史使用场景 核心架构Valve机制详细说明请求处理过程 Tomcat安装Windows系统下Tomcat的安装与配置:步骤1:安装JDK步骤2:下载Tomcat步骤3:解压Tomcat步骤4:配置环境变量&a…...
【前端】Matter:过滤与高级碰撞检测
在物理引擎中,控制物体的碰撞行为是物理模拟的核心之一。Matter.js 提供了强大的碰撞检测机制和碰撞过滤功能,让开发者可以控制哪些物体能够相互碰撞,如何处理复杂的碰撞情况。本文将详细介绍 碰撞过滤 (Collision Filtering) 与 高级碰撞检测…...
wps图标没有坐标轴标题怎么办?wps表格不能用enter下怎么办?
目录 wps图标没有坐标轴标题怎么办 一、在WPS PPT中添加坐标轴标题 二、在WPS Excel中添加坐标轴标题 wps表格不能用enter下怎么办 一、检查并修改设置 二、检查单元格保护状态 三、使用快捷键实现换行 wps图标没有坐标轴标题怎么办 一、在WPS PPT中添加坐标轴标题 插入…...
在ESP-IDF环境中如何进行多文件中的数据流转-FreeRTOS实时操作系统_流缓存区“xMessageBuffer”
一、建立三个源文件和对应的头文件 建立文件名,如图所示 图 1-1 二、包含相应的头文件 main.h 图 2-1 mess_send.h mess_rece.h和这个中类似,不明白的大家看我最后面的源码分享 图2-2 三、声明消息缓存区的句柄 大家注意,在main.c中定义的是全局变…...
ConcurrentLinkedQueue适合什么样的使用场景?
ConcurrentLinkedQueue 是 Java 中一种无界线程安全的队列,适合多线程环境中的高并发场景。以下是一些它特别适合的使用场景: 1. 高频读操作,低频写操作 ConcurrentLinkedQueue 对于实际应用中读操作相对频繁,写操作较少的场景非…...
C语言 | Leetcode C语言题解之第480题滑动窗口中位数
题目: 题解: struct Heap {int* heap;int heapSize;int realSize;bool (*cmp)(int, int); };void init(struct Heap* obj, int n, bool (*cmp)(int, int)) {obj->heap malloc(sizeof(int) * (n 1));obj->heapSize 0;obj->cmp cmp; }bool c…...
LabVIEW开发如何实现降维打击
在LabVIEW开发中实现“降维打击”可以理解为利用软件优势和高效工具来解决复杂的问题,将多维度、多层次的技术简化为容易操作和管理的单一维度,达到出其不意的效果。以下是几种关键策略: 1. 模块化设计与封装 将复杂系统分解为若干模块&…...
docker 文件目录迁移
文章参考 du -hs /var/lib/docker/ 命令查看磁盘使用情况。 du -hs /var/lib/docker/docker system df命令,类似于Linux上的df命令,用于查看Docker的磁盘使用情况: rootnn0:~$ docker system df TYPE TOTAL ACTIVE SIZE RECLAIMABLE Images 7 2 122.2…...
Markdown 标题
Markdown 标题 Markdown 是一种轻量级标记语言,它允许人们使用易读易写的纯文本格式编写文档,然后转换成格式化的HTML代码。Markdown 的语法简洁明了,广泛用于撰写文档、博客文章、笔记等。本文将详细介绍 Markdown 的标题语法及其在文档中的应用。 Markdown 标题语法 在…...
【动手学电机驱动】TI InstaSPIN-FOC(5)Lab04 力矩控制
TI InstaSPIN-FOC(1)电机驱动和控制测试平台 TI InstaSPIN-FOC(2)Lab01 闪灯实验 TI InstaSPIN-FOC(3)Lab03a 测量电压电流漂移量 TI InstaSPIN-FOC(4)Lab02b 电机参数辨识 TI Insta…...
Mysql的CommunicationsException
一、报错内容 com.mysql.cj.jdbc.exceptions.CommunicationsException: The last packet successfully received from the server was 1,500,378 milliseconds ago. The last packet sent successfully to the server was 1,500,378 milliseconds ago. is longer than the s…...
C++学习笔记----9、发现继承的技巧(二)---- 重用目的的继承
现在你对继承的基本语法已经比较熟悉了,是时候探索继承是c语言中重要属性的一个主要原因了。继承是一个装备允许你平衡既有代码。本节会举出基于代码重用目的的继承的例子。 1、WeatherPrediction类 假想你有一个任务,写一个程序来发出简单的天气预报&a…...
锐评 Nodejs 设计模式 - 创建与结构型
本系列文章的思想,都融入了 让 Java 再次伟大 这个全新设计的脚手架产品中,欢迎大家使用。 单例模式与模块系统 Node 的单例模式既特殊又简单——凡是从模块中导出的实例天生就是单例。 // database.js function Database(connect, account, password)…...
【RoadRunner】自动驾驶模拟3D场景构建 | 软件简介与视角控制
💯 欢迎光临清流君的博客小天地,这里是我分享技术与心得的温馨角落 💯 🔥 个人主页:【清流君】🔥 📚 系列专栏: 运动控制 | 决策规划 | 机器人数值优化 📚 🌟始终保持好奇心&…...
15分钟学Go 第4天:Go的基本语法
第4天:基本语法 在这一部分,将讨论Go语言的基本语法,了解其程序结构和基础语句。这将为我们后续的学习打下坚实的基础。 1. Go语言程序结构 Go语言程序的结构相对简单,主要包括: 包声明导入语句函数语句 1.1 包声…...
【Qt】Qt的介绍——Qt的概念、使用Qt Creator新建项目、运行Qt项目、纯代码方式、可视化操作、认识对象模型(对象树)
文章目录 Qt1. Qt的概念2. 使用Qt Creator新建项目3. 运行Qt项目3.1 纯代码方式实现3.2 可视化操作实现 4. 认识对象模型(对象树) Qt 1. Qt的概念 Qt 是一个跨平台的 C 图形用户界面应用程序开发框架。它是软件开发者提供的用于界面开发的程序框架&#…...
论文笔记:PTR: Prompt Tuning with Rules for Text Classification
Abstract 手动设计大量语言提示麻烦且易出错,而自动生成的提示,在非小样本场景下验证其有效性昂贵且耗时。因此,提示调优以处理多类别分类任务仍然具有挑战。为此,本文提出使用规则进行多类别文本分类提示调优(PTR&…...
服务器和中转机协同工作以提高网络安全
服务器和中转机(代理服务器)可以通过多种方式协同工作来提高网络安全。 常见的协同工作策略: 1. 使用代理服务器作为安全网关 访问控制:代理服务器可以作为网络的入口点,实施访问控制策略,如基于IP地址、…...
绍兴Geo优化,如何选对靠谱服务商?
在人工智能技术深度渗透商业推广领域的当下,GEO(地理定位)优化已不再是简单的本地搜索排名,而是演变为一场关于“空间精准度”与“AI语义理解”的双重竞赛。对于绍兴及周边区域的企业而言,如何从众多服务商中筛选出真正…...
C/C++核心语法与嵌入式开发实战解析
1. C/C核心语法深度解析与面试高频考点作为从事嵌入式开发十余年的老手,我见过太多候选人在C/C基础问题上折戟沉沙。本文将系统梳理那些面试官最爱问的核心语法点,结合工业级开发经验,带你掌握真正实用的编程精髓。1.1 const关键字的工程级应…...
AI开发-python-langchain框架(--AI 直接生成并执行 Python 代码 )友
指令替换 项目需求:将加法指令替换为减法 项目目录如下 /MyProject ├── CMakeLists.txt # CMake 配置文件 ├── build/ #构建目录 │ └── test.c #测试编译代码 └── mypass2.cpp # pass 项目代码 一,测试代码示例 test.c // test.c #includ…...
LAYONTHEGROUND沦
一、什么是requests? requests 是一个用于发送HTTP请求的 Python 库。 它可以帮助你: 轻松发送GET、POST、PUT、DELETE等请求 处理Cookie、会话等复杂性 自动解压缩内容 处理国际化域名和URL 二、应用场景 requests 广泛应用于以下实际场景: …...
超流体真空理论:光速本质、微观粒子结构与量子纠缠拓扑机制
摘要本文基于超流体真空理论框架,揭示狭义相对论洛伦兹变换的物理本源,诠释光速不变的底层形成机制,明确微观基本粒子的真空结构起源;同时提出原创性量子纠缠拓扑结构模型,定义纠缠传态的速度极限与物理机制࿰…...
【2026年阿里巴巴集团暑期实习- 4月8日-工程岗-第一题- 可删去的字符串】(题目+思路+JavaC++Python解析+在线测试)
题目内容 给你 $ n $ 个字符串。我们称某个字符串 $ s_i $ 是“可删去的”,当且仅当存在两个下标 $ j, k (j \neq k) $,满足 $ s_j + s_k = s_i $。换句话说,我们称某个字符串是“可删去的”,当且仅当它能由两个来自原字符串序列中不同位置的非空字符串拼接而成。 你的任…...
详细解析Spring如何解决循环依赖问题地
AI训练存储选型的演进路线 第一阶段:单机直连时代 早期的深度学习数据集较小,模型训练通常在单台服务器或单张GPU卡上完成。此时直接将数据存储在训练机器的本地NVMe SSD/HDD上。 其优势在于IO延迟最低,吞吐量极高,也就是“数据离…...
5分钟搞定万字提示词的底层方法论是什么?
最近有很多人想问六哥写提示词的方法论是什么?兄弟,你想学写提示词?说实话,大家赚钱都不容易,千万别走弯路去背什么“提示词语法”或“代码公式”。六哥写提示词的核心方法论就四个字:“借势喂养”。高质量…...
Agent Client Protocol 全景解析涛
1. 核心概念 在 Antigravity 中,技能系统分为两层: Skills (全局库):实际的代码、脚本和指南,存储在系统级目录(如 ~/.gemini/antigravity/skills)。它们是“能力”的本体。 Workflows (项目级):…...
7脚 LED数码屏的刷新显示,乱码请指正
我是新手近段时间的工作是点亮7脚LED数码屏,刷新时遇到了困惑请大家帮助指正,在此表示非常感谢。 下面是7脚LED数码屏结构图。 用了7个 case下面是刷新代码switch(ScanPinNum){// ---------------- CASE1: PIN1------------------------case 1: …...
