聊聊这个维护了三年的博客
简介: 具代表性的项目之一
前言
时间过得好快,距离博客第一天上线到现在,不知不觉三年了,期间经历了无数的维护、优化以及重构,博客的功能渐渐的完善,用户以及开发体验也不断提升,但是好像从来没有详细的介绍过这个博客,因此,准备好好写一篇文章详细的介绍一下这个博客的所有内容~
经历的变迁
技术栈
- 前台技术栈重大变化:vue2 + vuecli + elementui —> nuxt2 + elementui
- 后台技术栈重大变化:vue2 + vuecli + vue-element-template —> vue2 + vuecli + iview —> vue2 + webpack5 + iview —> vue3 + webpack5/vite2 + naiveui + typescript
- 后端技术栈重大变化:node + express + mysql —> node + koa2 + mysql + redis + typescript
- ci/cd重大变化:本地构建 —> jenkins构建部署
细节
- 首先最明显的变化是域名变了,博客最初的域名是:zhengbeining.com(如果有老用户的话应该知道),后面域名过期了,就换成了现在的:hsslive.cn
- 其次是服务器配置变了,最初是用的阿里云的学生机,配置好像是
1核1g内存
,博客最初的时候仅仅打包成是静态页面,而且也只有这一个博客项目,因此学生机也没啥问题;后面随着博客的重构改版,以及部署其他项目的增加,就跟着域名一起统一换成了腾讯云,配置升级成1核2g内存
,后面活动免费升级成了2核4g内存带宽8m
,支撑起了目前线上的所有项目。 - 然后这博客也见证了我从学生到社畜hhh
博客简介
线上地址
后端接口:apifox
github仓库
前台:https://github.com/galaxy-s10/nuxt-blog-client
后台:https://github.com/galaxy-s10/vue3-blog-admin
后端:https://github.com/galaxy-s10/vue3-blog-server
项目截图
前台
主页
后台
登录(支持qq、github以及邮箱验证码登录)
主页(基本所有的前台的数据都可在后台配置)
后端
启动初始化信息打印:
启动成功:
完善的错误捕获:
学到了什么
大致总结
前台:基于nuxt2
业务层
常量提取
同一个变量,在超过两处地方使用了,就提取成一个常量。更准确的说,同一个变量,在两个以上的文件使用了,就提取成一个常量,统一的放在一个常量文件进行管理,这样不仅方便进行统一修改,而且还方便了代码的可阅读性。
如果上面的变量没有提取成常量,一旦要修改,那么将是噩梦!
组件复用/二次封装
只要是重复性的代码,都根据业务抽离成组件,好处就不用多说了,不仅能打磨自己抽取组件的能力,还能提高后续的开发(搬砖)效率!
博客后台的表单二次封装:
添加文章表单:
二次封装表单,再配合表单配置项抽离,就可以使业务代码的结构更加清晰,而且复用到其他业务的表单也非常方便。
待定?
基建层
给项目添加git信息
如何确定线上的代码是哪个版本?如果是静态页面,你如何能保证你构建部署上线后,线上的页面就是最新的,可能你会在每次构建都在控制台打印一个特殊的东西,你部署上线后,在线上看控制台的打印是不是你最新的打印,根据这个来确定版本,虽然这个方法可行,但是在欠缺优雅,
当下很多项目基本都是基于git做的版本管理,我们可以在每次部署上线的时候,将当前提交的git信息打印到控制台,这样就可以非常优雅的解决这个问题!
以我当前的博客后台为例,我的博客后台是基于webpack搭建的,因此我们可以在webpack构建的时候,借助node的能力读取当前的git信息:
然后利用webpack.DefinePlugin将读取到的git信息写入到全局变量里:
然后将打印git信息封装成一个方法,在入口文件引入改方法即可,这样每次在构建的时候,都会读取并且写入git信息为全局变量,我们就可以将他们打印到控制台:
后台控制台打印效果:
后台控制台打印效果:
CDN加载
如果项目对页面加载速度有要求,可以将项目的所有静态资源全部打包上传到cdn,这样可以加速用户的访问站点速度,缺点就是cdn要钱,如果用户是内部的人用的,对稳定性要求不是第一位的,可以将一些常用的库使用类似:unpkg,jsdelivr 这些免费的cdn,这样既不用cdn,也不用部署到自己的服务器占用带宽。
压缩图片
具体看这里:https://github.com/galaxy-s10/mini-img
脚手架
具体看这里:https://github.com/galaxy-s10/billd-cli
项目模板
具体看这里:https://github.com/galaxy-s10/vue3-webpack5-template
monorepo
具体看这里:https://github.com/galaxy-s10/billd-monorepo
代码规范
首先当然是eslint,个人认为eslint比绝大部分人更懂写代码哈哈哈,个人推荐一个对导入导出排序的eslint插件:eslint-plugin-import,他最实用的就是对你的import进行排序,让你的import更加的美观。
另外附上我自己收集的通用的eslint规则:
// rules优先级最高,会覆盖上面的
rules: {
/**
* 0 => off
* 1 => warn
* 2 => error
*/
camelcase: 1, // 强制执行驼峰命名约定
'no-console': 0, // 此规则不允许调用console对象的方法。
'spaced-comment': ['error', 'always', { exceptions: ['-', '+'] }], // 该规则强制注释中 // 或 /* 后空格的一致性
'no-var': 2, // 要求let或const代替var
'no-shadow': 2, // 禁止变量声明与外层作用域的变量同名
'no-param-reassign': 2, // 禁止对 function 的参数进行重新赋值
'no-nested-ternary': 2, // 禁止嵌套三元
'no-plusplus': 2, // 禁用一元操作符 ++ 和 --
'no-unused-vars': 2, // 禁止出现未使用过的变量
'vars-on-top': 2, // 要求所有的 var 声明出现在它们所在的作用域顶部
'prefer-const': 2, // 要求使用 const 声明那些声明后不再被修改的变量
'prefer-template': 2, // 要求使用模板字符串代替字符串连接
'new-cap': 2, // 要求构造函数名称以大写字母开头
'no-restricted-syntax': [
// 禁用一些语法
'error',
// 'ForInStatement',
// 'ForOfStatement',
{
selector: 'ForInStatement',
/**
* 用 map() / every() / filter() / find() / findIndex() / reduce() / some() / ... 遍历数组,
* 和使用 Object.keys() / Object.values() / Object.entries() 迭代你的对象生成数组。
* 拥有返回值得纯函数比这个更容易解释
*/
message:
'for in会迭代遍历原型链(__proto__),建议使用map/every/filter等遍历数组,使用Object.{keys,values,entries}等遍历对象',
},
{
selector: 'ForOfStatement',
message:
'建议使用map/every/filter等遍历数组,使用Object.{keys,values,entries}等遍历对象',
},
], // https://github.com/BingKui/javascript-zh#%E8%BF%AD%E4%BB%A3%E5%99%A8%E5%92%8C%E5%8F%91%E7%94%9F%E5%99%A8
'no-iterator': 2, // 禁止使用__iterator__迭代器
'require-await': 2, // 禁止使用不带 await 表达式的 async 函数
'no-empty': 2, // 禁止空块语句
'guard-for-in': 2, // 要求for-in循环包含if语句
'global-require': 2, // 此规则要求所有调用require()都在模块的顶层,此规则在 ESLint v7.0.0中已弃用。请使用 中的相应规则eslint-plugin-node:https://github.com/mysticatea/eslint-plugin-node
'no-underscore-dangle': 1, // 此规则不允许在标识符中使用悬空下划线。
'class-methods-use-this': 0, // 类方法如果不使用this的话会报错
'no-unused-expressions': [
2,
{
allowShortCircuit: true, // 允许短路
allowTernary: true, // 允许三元
},
], // 禁止未使用的表达式,即let a = true && console.log(1)允许,但是true && console.log(1)不行
'object-shorthand': ['error', 'always'], // (默认)希望尽可能使用速记。var foo = {x:x};替换为var foo = {x};
// eslint-plugin-import插件
'import/order': [
'error',
{
groups: [
'builtin',
'external',
'internal',
['sibling', 'parent'],
'index',
'object',
'type',
],
'newlines-between': 'always', // 强制或禁止导入组之间的新行:
// 根据导入路径按字母顺序对每个组内的顺序进行排序
alphabetize: {
order: 'asc' /* 按升序排序。选项:['ignore', 'asc', 'desc'] */,
caseInsensitive: false /* 忽略大小写。选项:[true, false] */,
},
},
],
'import/newline-after-import': 2, // 强制在最后一个顶级导入语句或 require 调用之后有一个或多个空行
'import/no-extraneous-dependencies': 2, // 禁止导入未在package.json中声明的外部模块。
'import/prefer-default-export': 0, // 当模块只有一个导出时,更喜欢使用默认导出而不是命名导出。
'import/extensions': 0, // 确保在导入路径中一致使用文件扩展名。在js/ts等文件里引其他文件都不能带后缀,这样的话就没办法引其他类型文件,因此关掉
'import/no-unresolved': 0, // 不能解析带别名的路径的模块,但实际上是不影响代码运行的。找不到解决办法,暂时关掉。
'import/no-named-as-default-member': 1, // import vue from 'vue';console.log(vue.version),如果vue有导出version,会提示替换为import { version } from 'vue';
'import/named': 2, // 如:import { version } from 'vuex',会验证vuex有没有具名导出version
},
服务器操作
具体可以看我的这篇文章:https://hsslive.cn/article/102
未完待补充!
最后更新于:2022-09-20 01:27:08
vscode 是什么主题啊,求回复呀
One Dark Pro