[置顶] 记最近一次Nodejs全栈开发经历
背景:
前段时间大部门下新成立了一个推广百度OCR、文字识别、图像识别等科技能力在金融领域应用的子部门。因为部门刚成立,基础设施和人力都是欠缺的。当时分到我们部门的任务是抽调一个人做新部门主站前端开发工作。本来说的是只负责页面的开发工作。当我参加过需求品审会后,了解到新部门人力不足,而我今年主要任务又是在我们部门做基于Nodejs的前端后端分离的架构升级工作。
在这之前就是用Nodejs写了两个内部系统,并没有大型的线上Web开发经验,也想趁着这个机会锻炼下。然后就主动的跟老板商量了这件事,老板非常支持。之后又跟新部门的产品商量,本来就缺人手的他们也非常乐意我这边承担更多的开发任务。
这篇文章和自己之前的文章的风格会有很大的区别,不会再去写一些具体技术点和遇到问题的具体解决办法,主要谈的是我整个开发过程中遇到的一些问题和思考解决他们的方法。
内容列表
- 技术选型的思考
- 相关服务申请
- 前端工程
- 技术目标
- Web安全
- 内网机器访问外网
- 发送邮件
- 网络优化
- 收获
技术选型的思考
在文章的最开头背景介绍中大概说了网站后端采用Nodejs的开发。为了突出科技能力,网站要求了一些特效。因为我要用CSS3来写这些特效,跟产品PK后结果是浏览器兼容性是IE8.0以上,特效满足大多数主流浏览器即可。那么基于Nodejs的其它技术选型如下:
以下选择这些技术的原因:
- yog2(点击到达主页))是百度公司内部基于Express开发的比较成熟的Nodejs Web框架。提供的能力都是跟公司内部的基础服务(同机房访问、运维、日志等)接轨的,而且有一些部门已经在线上大规模使用,如果遇到问题可以有很多经验可以借鉴。
- swig是yog2默认支持的模板引擎。
- 因为Nodejs的语法是遵循CMD规范的。而且在百度内部提倡的也是使用FIS3和Mod.js。所以就选择了公司内部的FIS3(点击到达主页)和Mod.js(点击到达主页)。FIS3不仅有百度自己内部在用,也有很多的外部公司在用,比如滴滴等。
- 因为交互要求兼容一些低版本浏览器和一些奇葩的国产浏览器。为了保证开发时间的可控就选择了自己熟悉的jQuery;
相关服务的申请
确定了技术选型之后就是开始申请服务,主要包括以下相关内容:
- 域名申请
- 服务器申请
- Mysql数据库申请
- bos存储服务(使用的是百度云的bos存储)
以上都是走的公司的内部流程,具体的就不介绍了。主要介绍下一些服务的作用。一个在网络上运行的网站肯定是需要一个域名的,能让网站跑起来很定是需要线上服务器的。存储用户的注册数据需要数据库。因为使用OCR进行人脸识别,要满足识别一张图片上的多张脸。是需要对用户的图片裁切。因为网站是部署在多台机器上,肯定不能存储在网站运行的服务器上需要将裁切好的图片存储在专门的存储服务器上,并且返回给网站图片链接,
前端工程
使用Nodejs开发的话,前端的工程的概念可能还要广一些会涉及到Nodejs相关的工程化。这部分分两部分介绍:
1.前端
目标:
- 使用 SASS 来做css的模块化管理,并且实时编译成css,生成map文件便于本地调试;
- 将使用 CMD 规范编写的组件和模块化的代码打包编程供页面的业务代码引用;
- 给需要加厂商前缀的css属性自动加厂商前缀;
- 能够实时的将代码部署到测试环境,以方便QA测试;
以上的这些目标都可以使用 FIS3和相关插件来实现。
2.后端
因为我们线上大规模使用的Nodejs版本是6.x版本。但是开发过程中处理异步又是使用async
和await
。所以需要借助编译引擎将这些es7的语法编译成6.x支持的语法。
另外就是借助process.env.NODE_ENV
可以读取环境变量的特性,来区分配置一些线上和线下的配置,比如:
const YOG_DEBUG = process.env.YOG_DEBUG;
const PANSHI_DEBUG = process.env.PANSHI_DEBUG;
let mysqlConf;
if (PANSHI_DEBUG === 'true') {
mysqlConf = {
host: '10.00.00.00',
user: 'ppui',
password: 'ppui',
database: 'excel',
port: '5003'
};
} else if (YOG_DEBUG === 'true') {
mysqlConf = {
host: '127.0.0.1',
user: 'root',
password: '',
database: 'pass_panshi',
port: '3306'
};
}
技术目标
这里主要谈一些前端的技术目标
1.样式显示和dom操作分离
之前开发过程中经常遇到的情况是我需要该一个html节点的样式,不小心改了class
类名。而js又恰恰使用了这个class
操作了dom。这个时候页面运行的时候肯定会报错的,增加了项目的维护成本。
有两种方案可以有效的解决这种问题,第一就是添加自定义属性,比如<div class="section" node-type="pagesecond"></div>
当我需要操作dom的时候就通过jQuery的属性选择器来操作这个dom而不会去使用class。这样在我调整样式、需要修改class
名称的时候也不会影响js代码。第二种就是根据大家经常说的使用-
来做html 类名的连接符,而我们就规定一个规范就是使用下划线(_
)来标记我要操作dom节点的名称,比如<div class="section _pagesecond"></div>
。
这两种方式,如果是在开发多人维护的项目是都是需要提前预定规范,我在项目中是使用的前者。
2.业务代码和功能代码分离
在前面已经介绍过就是使用cmd规范来组织前端代码。比如为了能够满足我使用属性选择器来作为操作dom的需求。我特地自己封装了一些代码段,比如在base.js文件中有一段这样的代码:
/**
* 根据node-type获取节点信息
*
* @param {any} params 获取节点元素
* @param {any} context 上下文环境
* @returns
*/
exports.nodeTypeDom = function (params, context) {
if (context && context !== '') {
return $('[node-type="' + params + '"]', $('[node-type="' + context + '"]'));
} else {
return $('[node-type="' + params + '"]');
}
};
我在其他文件中需要使用这个代码段的时候,只需要像下面这样就可以了。
var baseJs = require('../libjs/base');
var node = baseJs.nodeTypeDom;
// 需要选择 dom 的地方,直接传入自定义属性的值
node('pagesecond').xxxx
除了一些常用的代码段这样封装,一些组件也按照这样的方式封装。比如:轮播图组件、文件上传组件、表单校验组件、tab滚动组件。
以上两种方式的好处都能够极大的提高代码的可维护性、阅读性。
Web安全
我在开发过程中关注的Web安全主要是
- sql注入
- 接口攻击
1.防范sql注入
sql注入简单些说就是指一些违法用户拼接一个特殊的用户名或者是密码,因为我们要把用户名和密码插入数据库,肯定会根据这个用户名和密码拼接一个sql语句。而违法用户的这个特殊用户名语句有可能删掉我们数据库的所有数据。
因为使用的是mysql
数据库。Nodejs模块使用的也是npm上使用最多的Mysql模块。本身这个模块已经提供了访问mysql集群的能力和防注入的能力。
具体方法可以参考官方文档点击这里直达
2.防范接口攻击
这里要做的就是有些违法用户拿到我们接口的时候,写一个循环频繁的访问我们的接口。为了防止有些违法用户就是给请求加token。就是在向服务端发起请求的时候返回给前端的一个token,前端请求后端的时候带上这个token。如果token在后端校验通过就销毁这个token 。还有比如验证请求的源IP,这里注意的是我们验证IP的时候应该获取的是HTTP协议header字段中的x-forwarded-for属性的值。(这两种方法可以一起使用)
不过后来从后端RD那边了解到公司有专门的服务可以用来做反作弊,而且策略更全面些。目前在研究准备接入。
内网机器访问外网
关于跨机房访问、同机房访问和内网访问外网,这些基本上都会涉及到运维的话题。百度内部有现成的服务接入文档。各个公司可能提供能力的方式不一样。这里不多介绍。
这里谈一些小的细节点。先看下面的一张图:
一句话总结:当一条请求到达接入层之前是不知道要访问内网环境下那个机房的服务器的。相反的内网的机器上如果有一条请求外网的链接,比如:http://weibo.com 。需要通过一个proxy访问外网服务器。
访问接口我使用request
模块。配合promise npm上有request-promise
由名字我们就知道他的每个方法或者是调用结果返回的是什么了。这个模块默认已经提供了代理参数的相关配置。具体的可以参考文档点击直达
这里涉及的知识比较多,比如代理隧道、https请求的代理。在阅读官方配置文档的时候搜索一些关键字了解一些其它相关知识即可。
如果有相关的需求,可以参考我的配置,如果我的配置不能解决你的问题,请仔细阅读官方文档哈。、
let options = {
'url': params.url,
'encoding': 'binary',
'rejectUnauthorized': false // 取消https证书的校验
};
// 解决代理https请求的行为 测试机需要配置环境变量 PANSHI_HTTPS_PROXY
if (process.env.PANSHI_DEBUG !== 'true' || PANSHI_HTTPS_PROXY) {
options.tunnel = false;
options.proxy = 'http://xxxx.proxy.com:8080';
}
发送邮件
到这里关于开发相关介绍已经完毕。这里介绍的就是运营和产品需求的一些功能开发。每天将注册的用户发送给相应的责任人。
如果要满足这个功能需要有邮件服务器。这个在公司内部有公用的可以很容易找到。其它就是配置服务的crontab
定时执行脚本查询数据库发送邮件。
这里主要使用了nodejs模块nodemailer
。具体的相关配置和发送邮件的方法可以参考官方文档配置点击直达
网络优化
- 静态文件cdn部署;
- 合并静态文件;
- 缓存静态文件;
- icon使用Base64
上面列举的是比较典型的几个点。比如像css放head标签头部,script标签放到body标签底部。这些应该属于一个前端工程师的常识吧。
静态文件部署CDN这个不多介绍,每个公司都会自己的一套方法。这里主要介绍下合并静态文件和缓存静态文件。
1.合并静态文件
默认FIS3是有插件支持合并静态文件的。因为我这次开发的页面较多(总共11个主站页面),且因为采用的分块开发加载模块和静态文件。如果不做合并的话,一个页面加载完需要有10-20条的静态文件的请求。会影响页面的加载速度。
当我准备使用FIS3的插件来合并静态文件的时候发现还是有些麻烦的需要一个页面一个页面去配置要打包合并的静态文件。最后请教了下其它部门的同事使用我们接入层服务器提供的comb功能,由服务器帮我们合并静态文件(其实就是Nginx 的concat模块提供的功能)。这里也不做过多的介绍,自行搜索文章了解就可以了。
2.缓存静态文件
先来看下一张图
上图中红色框出来的都是跟静态文件缓存有关的http协议的字段。如果对这些字段的概念比较模糊可以阅读这篇文章加深下印象《HTTP缓存》点击直达
不管使用express
还是koa
(koa可以使用koa-static-cache中间件)都用相应的静态文件服务的中间件提供配置这几个字段的能力。express可以通过一下方式配置(具体的可以阅读express文档)
const express = require('express')
// 配置与静态文件相关的参数
express.static('xxxxx')
收获
最后就是谈谈这次开发的收获
- 这个项目开发上线以后,刚好到了大部门的年中总结会,因为自己独立负责了前后端的开发工作,获得了大部门的“闪耀之星”奖励和一些物质奖励(虽然还没见到影
[置顶] 记最近一次Nodejs全栈开发经历的更多相关文章
- 一文读懂NodeJS全栈开发利器:CabloyJS(万字长文)
目录 0 修订 0.1 修订说明 0.2 修订历史 1 基本概念 1.1 CabloyJS是什么 1.2 CabloyJS核心解决什么问题 1.3 CabloyJS的开发历程 2 数据版本与开发流程 ...
- NodeJS全栈开发利器:CabloyJS究竟是什么
CabloyJS CabloyJS是一款顶级NodeJS全栈业务开发框架, 基于KoaJS + EggJS + VueJS + Framework7 文档 官网 && 文档 演示 PC ...
- CabloyJS带你轻松走进NodeJS全栈开发-免费课程 作者亲授
课程说明 B站直播 为回馈新老同学对开源框架CabloyJS的支持与厚爱,快速而轻松的开启NodeJS全栈开发之旅.2019年9月5日至9月11日在B站开启了一波免费直播培训课程 课程信息,请点击链接 ...
- CabloyJS全栈开发之旅(1):NodeJS后端编译打包全攻略
背景 毋庸置疑,NodeJS全栈开发包括NodeJS在前端的应用,也包括NodeJS在后端的应用.CabloyJS前端采用Vue+Framework7,采用Webpack进行打包.CabloyJS后端 ...
- [置顶] 创建GitHub技术博客全攻略
[置顶] 创建GitHub技术博客全攻略 分类: GitHub2014-07-12 13:10 19710人阅读 评论(21) 收藏 举报 githubio技术博客网站生成 说明: 首先,你需要注册一 ...
- 分享一款自带工作流引擎的NodeJS全栈框架,接单快手、创业神器
CabloyJS是什么 CabloyJS是一款自带工作流引擎的Node.js全栈框架, 接单快手.创业神器, 基于koa + egg + vue + framework7 + mysql 在线演示 场 ...
- Meteor全栈开发平台 - 不仅仅是前端
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,博客地址为http://www.cnblogs.com/jasonnode/ .网站上有对应每一 ...
- 全栈开发必备的10款Sublime Text 插件
Sublime Text 具有漂亮的用户界面和强大的功能,例如代码缩略图,多重选择,快捷命令等.Sublime Text 更妙的是它的可扩展性.所以,这里挑选了全栈开发必备的10款 Sublime T ...
- 全栈开发必备的10款 Sublime Text 插件
Sublime Text 具有漂亮的用户界面和强大的功能,例如代码缩略图,多重选择,快捷命令等.Sublime Text 更妙的是它的可扩展性.所以,这里挑选了全栈开发必备的10款 Sublime T ...
随机推荐
- Java基础东西(按位操作运算)
http://aokunsang.iteye.com/blog/615658 前奏: 昨天一哥们问我Java位移你会吗,我说不会,想想位移这么麻烦,一般有位移的Java代码一律不看,有几个人会啊, ...
- vi在行首插入注释符号#
1.ctrl+v 2.上下键选中要插入的位置 3.按下shift+i,接着输入#符号 4.按键ESC(稍等一下,就会自动插入了)
- This version of MySQL doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery' 解决办法
背景:mysql5.1.36,mybatis 前言:为了解决一对多,分页显示,但是前端主要是显示的一的一方的数据和(多方的某个字段拼接在一起),此时的limit不能直接跟在查询的后面,需要用子查询把需 ...
- linux 忘记登陆密码
声明:如果不是远程登陆,机器在自己身边还有救. 第一步:重启机器,进入brug界面(grub是一个引导管理程序,可以引导linux.winxp等系统,在/boot/grub/中的menu.lst中进行 ...
- linux centos7安装phpMyAdmin详解,以及解决各种bug问题
使用php和mysql开发网站的话,phpmyadmin和navicat是目前非常好的mysql管理工具,但是phpmyadmin最主要是免费开源,目前很多集成的开发环境都会自带phpmyadmin, ...
- Python学习札记(十三) Function3 函数参数二
参考:函数参数 Note A.关键字参数: 1.关键字参数:**kw 可变参数允许你传入0个或任意个参数,这些可变参数在函数调用时自动组装为一个tuple.而关键字参数允许你传入0个或任意个含参数名的 ...
- 面试代码基础(一)从strstr说起
对于写程序要注意:要能在面试官的提示下把代码写出来(把思想实现的能力)!还要注意边界检查!递归找到出口! 开场来个简单字符串匹配 int strstr(char* target,char* sourc ...
- zoom:1;
zoom:1;属性是IE浏览器的专有属性,可以设置或检索对象的缩放比例.触发ie的hasLayout属性.清除浮动.清除magin的重叠等. 注意:它未通过W3C验证.
- 织梦dedecms获取当前内容页栏目id号的方法
一,可在内容模板中直接这样写{dede:field.typeid/} 可显示本栏目的id 二,也可这样写 {dede:type}[field:ID /]{/dede:type} . 三, 如果是在{ ...
- spring mvc:内部资源视图解析器(注解实现)@Controller/@RequestMapping
spring mvc:内部资源视图解析器(注解实现)@Controller/@RequestMapping 项目访问地址: http://localhost:8080/guga2/hello/prin ...