# 胖模式开发环境及公共组件优化
# 背景
由于胖模式是使用的backbone.js
框架,且代码历史悠久,缺失了很多现代化的功能,极大地影响了我们的开发效率,于是对胖模式做了很多优化,下面详细列出:
# 开发环境优化
# 支持mock数据
之前已有创新《模拟胖模式设备cgi程序+前端mock数据》
通过点击页面手动收集接口数据,并上传到服务器提供mock api。
但是由于年久失修,服务器已经挂了,且模拟数据都在服务器不方便实时更新(特别是新接口),所以基于该创新,将mock数据功能本地化:
在build\env.js
中提供:
// 开启mock
exports.mock = true;
// mock地址前缀
const mockVersion = 'wns_sw_ipv6';
只需要开启mock,并配置mock接口的版本,即可跑起胖模式环境,无需依赖后台环境。
# 支持热更新
之前胖模式已经支持本地开启代理服务器,但是使用的是express做服务器,无法监听本地文件的改动,无法做到热更新。
这里引入gulp-webserver
插件,开启livereload
后可实现代码变动后自动刷新页面。
gulp.src('./')
.pipe(webserver({
host,
port,
livereload: true,
open: './index.html',
directoryListing: {
enable: true,
path: './'
},
https: {
key: './build/ca/server-key.key',
cert: './build/ca/server-cert.crt'
},
}))
但是这里有个问题,由于backbone.js
框架没使用前端路由,导致刷新后会回到首页。
这里我们通过在菜单的点击事件记录页面路径,存入localStorage
中,在热更新时,如果存在该页面记录,则直接打开该页面。
通过以上两种方式,达到类似热更新的效果。
# 接口易于区分
之前接口的url
都是https://localhost:8080/cgi-bin/fat_ap.cgi?_t=1715678640549
的形式,不同接口完全看不出来哪个是哪个
这里通过拼接上option和opr参数,可以一眼看出接口类型。
# 点击页面跳转至源代码
参考《在页面中快速定位vue组件文件功能》
基本思路是一致的,需要注意的是胖模式都是通过模板渲染,我们只需要解析.tpl
文件,给每行拼上代码位置即可。
在gulp-webserver
中,通过中间件的形式,拦截请求
gulp.src('./')
.pipe(webserver({
middleware: [
codeServer,
addCodeLocation,
],
}))
如果是.tpl
则拼上代码位置并返回
function addCodeLocation(req, res, next) {
// 只处理tpl文件
if (req.url.includes(".tpl")) {
const filePath = path.join(rootDir, req.url);
fs.readFile(filePath, "utf-8", function (err, data) {
const code = data ? codeLineTrack(data, filePath) : data;
res.end(code);
});
} else {
next();
}
}
# 增加commit限制
之前胖模式并没有做任何的提交限制,现在换成git后,如果不限制则会导致commit信息杂乱。
安装commitlint
、husky
增加commit提交前的钩子,达到校验的效果(例:feat: xxx)。
# 添加eslint
之前的代码也没做任何格式、语法的校验
这里安装eslint
并根据项目适配规则,达到统一代码风格、检查代码错误的效果。
module.exports = {
root: true,
env: {
browser: true,
node: true,
},
extends: ["eslint:recommended"],
parserOptions: {
parser: "@babel/eslint-parser",
ecmaVersion: 6,
},
"overrides": [
{
"files": ["js/**/*.js"],
"rules": {
indent: ["error", 4, { SwitchCase: 1 }],
},
parserOptions: {
ecmaVersion: 5,
},
}
],
globals: {
__: true, // 可以读取,可以修改
APF: true,
App: true,
$: false, // 可以读取,不能修改
define: false,
_: false,
Marionette: false,
RSAKey: false,
requirejs: false,
jQuery: false,
},
};
# 公共组件优化
# 弹窗层级
之前的弹窗需要在创建时手动指定zIndex。
APF.createDialog(settingForm.$el, {
zIndex: 302,
})
弊端就是人为去控制,肯定会产生冲突的场景。
这里改成自动生成zIndex,使用弹窗时无需再关心层级问题了。
原理就是记录一个全局变量,每次打开弹窗时就累加,关闭弹窗时就-1
var zIndex = 300;
var getZIndex = function () {
return zIndex++;
};
var setZIndex = function (_zIndex) {
zIndex = _zIndex;
};
# 支持插槽渲染组件
backbone
没有插槽的概念,小组件复用起来困难,这里我们手动实现一个类似插槽的功能:
在utils
中提供渲染插槽函数:
/**
* 动态渲染组件
* @param {*} context 父级组件的this
* @param {*} viewObj 组件配置
*/
utils.renderComponent = function (context, viewObj) {
var $renderTo = context.$el.find(viewObj.renderTo);
var view = new viewObj.View($.extend(
{
parentView: context,
},
viewObj.options || {}
));
$renderTo.empty().append(view.$el);
context[viewObj.viewName] = view;
};
组件配置:
function getIpAddressView (options) {
return {
View: Form,
renderTo: '#ip-address-wrapper',
options: options,
viewName: 'ipAddressView',
}
}
View:backbone框架的一个组件文件,
renderTo:渲染的插槽位置
options: 自定义参数
viewName: 组件实例的变量名
模板:
在模板中预留div,当做插槽
<div id="ip-address-wrapper"></div>
通过以上方法,就可实现类型vue的插槽渲染组件了。
# 表格列文案默认格式化
之前没给列默认的格式化函数,导致无数据时会出现很多空白列
这里统一给上无数据时显示为“-”
# 总结
通过这些优化措施,我们不仅提高了胖模式开发环境的效率和代码质量,还改善了公共组件的复用性和用户体验。