NodeJs从入门到实战
作为一名热爱学习的前端工程师,想要获得更大的成长,除了积累原生JavaScript的相关知识,还是有必要掌握后端开发的,这样是从一个全端开发工程师彻底转变成大前端的一个必经之路!
项目背景
由于我平时对前端领域比较感兴趣,所以也曾开发过属于自己的个人网站,从Hexo脚手架搭建的博客站,到前后端分离的个人网站,以及后面所接触到的unicloud云开发,这其中也渐渐对nodejs技术有了更进一步的了解。
目前负责公司的一个可视化平台的后台服务器项目,从最初的技术选型到一步一步的搭建,测试,到最终部署到Linux系统上,以及后期的迭代更新,也收获满满。
技术架构
因为是团队开发,我才用前后端分离的方式,具体技术栈如下:
服务端:NodeJs + Koa + sequelize + sqlite3
部署上线:pm2
代码管理: git
服务端技术架构图:
技术架构说明
- 这里我们采用node社区比较轻量的服务端框架Koa,然后服务端中间件有:
- koa-static 提供静态资源访问,具体用途在项目实现细节里面会详细介绍
- koa-body 处理请求报文,让koa可以方便的拿到post/put的数据
- koa2-cors 本地联调时通过cors方式处理跨域问题
- multer 用来处理文件上传
- koa-router 用来编写服务端路由和api
- koa-send 用于处理文件下载
- axios HttpAPI请求工具, 这里是辅助前端进行第三方跨域请求
- sequelize Node的ORM框架Sequelize来操作数据库,用于将关系数据库映射到对象上,然后进行的封装。
上面就是我们web服务端主要使用的中间件,对于每一块如何去组织和架构,包括自己实现错误校验中间件,我会在后面一一介绍,由于写服务端的过程中也查阅了很多资料,如有不足或需要优化的地方,欢迎交流。
目录
model-sequelize/
|
+- .vscode/无
| |
| +- launch.json <-- VSCode 配置文件
|
+- controller/接口函数
| +- applys.js <-- 应用接口函数
| +- node_util.js <-- 通用接口函数
| +- project.js <-- 项目管理接口函数
| ……
|
+- lib/请求响应处理封装
| +- return.js <-- 过滤响应
|
+- util/工具库
| +- init
| +- model
|
+- view/前端静态代码托管
| +-
|
+- models/ <-- 存放所有数据表映射关系
| +- project.js <-- 项目管理
| ……
|
+- db.js <-- 如何定义Model
|
+- model.js <-- 如何导入Model
|
+- database.js <-- 初始化数据库
|
+- database.sqlite <-- sqlite3数据库文件
|
+- server.js <-- 业务代码(总入口)
|
+- server.json <-- 业务配置项
|
+- package.json <-- 项目描述文件
|
+- node_modules/ <-- npm安装的所有依赖包
复制代码
常用功能精讲
sequelize
在没有sequelize之前,nodejs调用数据表,需要手写晦涩难懂的sql语句。
而sequelize采用底层封装的思路,将数据表抽象成为对象,然后通过API进行实现增删改查。
就如同vue解放了原生dom操作一般,有木有很方便。
// 连接数据库
const sequelize = new Sequelize({
host: 'localhost',
dialect: 'sqlite',
// timezone: '+08:00',
pool: {
max: 5,
min: 0,
acquire: 30000,
idle: 10000
},
storage: 'database.sqlite',
operatorsAliases: false
});
// 数据表建立 例子:
module.exports = db.defineModel("user", {
username: db.Sequelize.STRING,
password: db.Sequelize.STRING,
status: db.Sequelize.STRING,
token: db.Sequelize.STRING, // 保存至前端的加密信息 暂时由status+时间戳组成
wechat_sceneId:db.Sequelize.INTEGER, // 微信小程序所加载的场景id
}, {
// freezeTabelName 为 true 时不会在库中映射表时增加复数表名
// 该选项为 true 时,user 在映射时映射成 user,而为 false 时会映射成users
freezeTableName: true
})
// 多表关联建立 例子:
// 关联一对多表查询
applys.belongsTo(projects, {
foreignKey:
'projectId', targetKey: 'id'
});
// 数据表的查询操作(其中model是我对所有数据表对象的封装)
const userList=async ()=>{
let results = await model.user.findAll()
return results
}
复制代码
最后想了解更多关于sequelize的使用,可以前往廖雪峰大佬的个人网站学习。
##sequelize
supervisor
在开发过程中的一个热更新插件supervisor
复制代码
打包上线/打包成应用
进程常驻pm2
npm install -g pm2
$ pm2 start app.js # 启动app.js应用程序
$ pm2 start app.js -i 4 # cluster mode 模式启动4个app.js的应用实例
# 4个应用程序会自动进行负载均衡
$ pm2 start app.js --name="api" # 启动应用程序并命名为 "api"
$ pm2 start app.js --watch # 当文件变化时自动重启应用
$ pm2 start script.sh # 启动 bash 脚本
$ pm2 list # 列表 PM2 启动的所有的应用程序
$ pm2 monit # 显示每个应用程序的CPU和内存占用情况
$ pm2 show [app-name] # 显示应用程序的所有信息
$ pm2 logs # 显示所有应用程序的日志
$ pm2 logs [app-name] # 显示指定应用程序的日志
$ pm2 flush # 清空所有日志文件
$ pm2 stop all # 停止所有的应用程序
$ pm2 stop 0 # 停止 id为 0的指定应用程序
$ pm2 restart all # 重启所有应用
$ pm2 reload all # 重启 cluster mode下的所有应用
$ pm2 gracefulReload all # Graceful reload all apps in cluster mode
$ pm2 delete all # 关闭并删除所有应用
$ pm2 delete 0 # 删除指定应用 id 0
$ pm2 scale api 10 # 把名字叫api的应用扩展到10个实例
$ pm2 reset [app-name] # 重置重启数量
$ pm2 startup # 创建开机自启动命令
$ pm2 save # 保存当前应用列表
$ pm2 resurrect # 重新加载保存的应用列表
$ pm2 update # Save processes, kill PM2 and restore processes
$ pm2 generate # Generate a sample json configuration file
pm2文档地址:http://pm2.keymetrics.io/docs/usage/quick-start/
复制代码
mysql数据库连接功能相关知识
开启本地数据库局域网访问
1、更新root账户的权限。打开mysql命令行窗口,输入
grant all privileges on *.* to root@"%" identified by 'abc' with grant option; flush privileges;
上述语句的完整模板为:
grant all privileges on 库名.表名 to '用户名'@'IP地址' identified by '密码' with grant option;
flush privileges;
测试,没有问题。
2、创建一个新账户,如guest,并将可被访问的主机定义为%,即所有主机都可访问该账户。
测试,没有问题。
参考:
https://jingyan.baidu.com/article/6dad50755e3dd1a123e36ec4.html
复制代码
docker打包镜像
- window上要使用docker,可以使用docker desktop工具
安装和运行docker desktop
测试demo
执行步骤1-clone 克隆仓库镜像
执行步骤2-build 编译
执行步骤3-run
复制代码
-
创建配置项
- Dockerfile
FROM node:12.13.0 # Create app directory WORKDIR /usr/src/app # Install app dependencies # A wildcard is used to ensure both package.json AND package-lock.json are copied # where available (npm@5+) COPY package*.json ./ RUN yarn install #RUN npm install --registry=https://registry.npm.taobao.org # If you are building your code for production #RUN npm ci --only=production # Bundle app source COPY . . EXPOSE 3000 CMD [ "node", "server.js" ] 复制代码
- dockerignore
.git .svn node_modules public static/model database.sqlite npm-debug.log 复制代码
-
编译打包服务端项目
编译 docker build -t yanyufanchen/node-web-app . node-web-app为打包的镜像名称 可以用:用户名/镜像名 查看所有镜像docker images 修改标签 docker tag IMAGEID(镜像id) REPOSITORY:TAG(用户名/镜像名:标签) 运行镜像 docker run -p 3000:3000 -d 镜像名 映射端口49160:原有端口8080 推送远程仓库 docker push 镜像名称:标签 删除镜像 docker rmi -f 241c2cc33dde(镜像名称) 查看容器 docker ps 停止容器 docker stop 删除容器 docker rm -f 复制代码
- 遇到的问题
安装docker desktop工具后出现提示”wsl2 installation is incomplete“ 原因:是没有安装linux在windows的子系统,可以在window store上下载debian工具 解决方案:https://www.jiloc.com/45016.html 1、安装debian 2、启动debian 3、注册账号密码 依然没有解决,安装wsl更新包 https://www.cnblogs.com/xiluhua/p/14120713.html https://github.com/xiluhua/docker-desktop 复制代码
代码混淆 uglify-es混淆
安装
From NPM for use as a command line app:
npm install uglify-es -g
From NPM for programmatic use:
npm install uglify-es
使用
混用多个混淆属性选项:
uglifyjs example.js -c -m --mangle-props regex=/_$/,reserved=[bar_]
混淆并输出到指定目录下
uglifyjs text2.js -o out/text2.js -c -m --mangle-props regex=/_$/,reserved=[bar_]
复制代码
地址
uglify-js只能混淆es5以下
参考中文文档
http://www.suoniao.com/article/52
uglify-es可以混淆es6
https://github.com/mishoo/UglifyJS/tree/harmony
复制代码
参考资料
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END