- 小程序调试新方案——使用WeConsole监控console/network/api/component/storage
[图片] 一、背景与简介 在传统的 PC Web 前端开发中,浏览器为开发者提供了体验良好、功能丰富且强大的开发调试工具,比如常见的 Chrome devtools 等,这些调试工具极大的方便了开发者,它们普遍提供查看页面结构、监听网络请求、管理本地数据存储、debugger 代码、使用 Console 快速显示数据等功能。 但是在近几年兴起的微信小程序的前端开发中,却少有类似的体验和功能对标的开发调试工具出现。当然微信小程序的官方也提供了类似的工具,那就是 vConsole,但是相比 PC 端提供的工具来说确实无论是功能和体验都有所欠缺,所以我们开发了 weconsole 来提供更加全面的功能和更好的体验。 基于上述背景,我们想开发一款运行在微信小程序环境上,无论在用户体验还是功能等方面都能媲美 PC 端的前端开发调试工具,当然某些(如 debugger 代码等)受限于技术在当前时期无法实现的功能我们暂且忽略。 我们将这款工具命名为[代码]Weimob Console[代码],简写为[代码]WeConsole[代码]。 项目主页:https://github.com/weimobGroup/WeConsole 二、安装与使用 1、通过 npm 安装 [代码]npm i weconsole -S [代码] 2、普通方式安装 可将 npm 包下载到本地,然后将其中的[代码]dist/full[代码]文件夹拷贝至项目目录中; 3、引用 WeConsole 分为[代码]核心[代码]和[代码]组件[代码]两部分,使用时需要全部引用后方可使用,[代码]核心[代码]负责重写系统变量或方法,以达到全局监控的目的;[代码]组件[代码]负责将监控的数据显示出来。 在[代码]app.js[代码]文件中引用[代码]核心[代码]: [代码]// NPM方式引用 import 'weconsole/init'; // 普通方式引用 import 'xxx/weconsole/init'; [代码] 引入[代码]weconsole/init[代码]后,就是默认将 App、Page、Component、Api、Console 全部重写监控!如果想按需重写,可以使用如下方式进行: [代码]import { replace, restore, showWeConsole, hideWeConsole } from 'weconsole'; // scope可选值:App/Page/Component/Console/Api // 按需替换系统变量或函数以达到监控 replace(scope); // 可还原 restore(scope); // 通过show/hide方法控制显示入口图标 showWeConsole(); [代码] 如果没有显式调用过[代码]showWeConsole/hideWeConsole[代码]方法,组件第一次初始化时,会根据小程序是否[代码]开启调试模式[代码]来决定入口图标的显示性。 在需要的地方引用[代码]组件[代码],需要先将组件注册进[代码]app/page/component.json[代码]中: [代码]// NPM方式引用 "usingComponents": { "weconsole": "weconsole/components/main/index" } // 普通方式引用 "usingComponents": { "weconsole": "xxx/weconsole/components/main/index" } [代码] 然后在[代码]wxml[代码]中使用[代码]<weconsole>[代码]标签进行初始化: [代码]<!-- page/component.wxml --> <weconsole /> [代码] [代码]<weconsole>[代码]标签支持传入以下属性: [代码]properties: { // 组件全屏化后,距离窗口顶部距离 fullTop: String, // 刘海屏机型(如iphone12等)下组件全屏化后,距离窗口顶部距离 adapFullTop: String, } [代码] 4、建议 如果不想将 weconsole 放置在主包中,建议将组件放在分包内使用,利用小程序的 分包异步化 的特性,减少主包大小 三、功能 1、Console 界面如图 1 实时显示[代码]console.log/info/warn/error[代码]记录; [代码]Filter[代码]框输入关键字已进行记录筛选; 使用分类标签[代码]All, Mark, Log, Errors, Warnings...[代码]等进行记录分类显示,分类列表中[代码]All, Mark, Log, Errors, Warnings[代码]为固定项,其他可由配置项[代码]consoleCategoryGetter[代码]产生 点击[代码]🚫[代码]按钮清空记录(不会清除[代码]留存[代码]的记录) [代码]长按[代码]记录可弹出操作项(如图 2): [代码]复制[代码]:将记录数据执行复制操作,具体形式可使用配置项[代码]copyPolicy[代码]指定,未指定时,将使用[代码]JSON.stringify[代码]序列化数据,将其复制到剪切板 [代码]取消置顶/置顶显示[代码]:将记录取消置顶/置顶显示,最多可置顶三条(置顶无非是想快速找到重要的数据,当重要的数据过多时,就不宜用置顶了,可以使用[代码]标记[代码]功能,然后在使用筛选栏中的[代码]Mark[代码]分类进行筛选显示) [代码]取消留存/留存[代码]:留存是指将记录保留下来,使其不受清除,即点击[代码]🚫[代码]按钮不被清除 [代码]取消全部留存[代码]:取消所有留存的记录 [代码]取消标记/标记[代码]:标记就是将数据添加一个[代码]Mark[代码]的分类,可以通过筛选栏快速分类显示 [代码]取消全部标记[代码]:取消所有标记的记录 [图片] 图 1 [图片] 图 2 2、Api 界面如图 3 实时显示[代码]wx[代码]对象下的相关 api 执行记录 [代码]Filter[代码]框输入关键字已进行记录筛选 使用分类标签[代码]All, Mark, Cloud, xhr...[代码]等进行记录分类显示,分类列表由配置项[代码]apiCategoryList[代码]与[代码]apiCategoryGetter[代码]产生 点击[代码]🚫[代码]按钮清空记录(不会清除[代码]留存[代码]的记录) [代码]长按[代码]记录可弹出操作项(如图 4): [代码]复制[代码]:将记录数据执行复制操作,具体形式可使用配置项[代码]copyPolicy[代码]置顶,未指定时,将使用系统默认方式序列化数据(具体看实际效果),将其复制到剪切板 其他操作项含义与[代码]Console[代码]功能类似 点击条目可展示详情,如图 5 [图片] 图 3 [图片] 图 4 [图片] 图 5 3、Component 界面如图 6 树结构显示组件实例列表 根是[代码]App[代码] 二级固定为[代码]getCurrentPages[代码]返回的页面实例 三级及更深通过[代码]this.selectOwnerComponent()[代码]进行父实例定位,进而确定层级 点击节点名称(带有下划虚线),可显示组件实例详情,以 JSON 树的方式查看组件的所有数据,如图 7 [图片] 图 6 [图片] 图 7 4、Storage 界面如图 8 显示 Storage 记录 [代码]Filter[代码]框输入关键字已进行记录筛选 点击[代码]🚫[代码]按钮清空记录(不会清除[代码]留存[代码]的记录) [代码]长按[代码]操作项含义与[代码]Console[代码]功能类似 点击条目后,再点击[代码]❌[代码]按钮可将其删除 点击[代码]Filter[代码]框左侧的[代码]刷新[代码]按钮可刷新全部数据 点击条目显示详情,如图 9 [图片] 图 8 [图片] 图 9 5、其他 界面如图 10 默认显示 系统信息 可通过[代码]customActions[代码]配置项进行界面功能快速定制,也可通过[代码]addCustomAction/removeCustomAction[代码]添加/删除定制项目 几个简单的定制案例如下,效果如图 11: [代码]import { setUIRunConfig } from 'xxx/weconsole/index.js'; setUIRunConfig({ customActions: [ { id: 'test1', title: '显示文本', autoCase: 'show', cases: [ { id: 'show', button: '查看', showMode: WcCustomActionShowMode.text, handler(): string { return '测试文本'; } }, { id: 'show2', button: '查看2', showMode: WcCustomActionShowMode.text, handler(): string { return '测试文本2'; } } ] }, { id: 'test2', title: '显示JSON', autoCase: 'show', cases: [ { id: 'show', button: '查看', showMode: WcCustomActionShowMode.json, handler() { return wx; } } ] }, { id: 'test3', title: '显示表格', autoCase: 'show', cases: [ { id: 'show', button: '查看', showMode: WcCustomActionShowMode.grid, handler(): WcCustomActionGrid { return { cols: [ { title: 'Id', field: 'id', width: 30 }, { title: 'Name', field: 'name', width: 70 } ], data: [ { id: 1, name: 'Tom' }, { id: 2, name: 'Alice' } ] }; } } ] } ] }); [代码] [图片] 图 10 [图片] 图 10 四、API 通过以下方式使用 API [代码]import { showWeConsole, ... } from 'weconsole'; showWeConsole(); [代码] replace(scope:‘App’|‘Page’|‘Component’|‘Api’|‘Console’) 替换系统变量或函数以达到监控,底层控制全局仅替换一次 restore(scope:‘App’|‘Page’|‘Component’|‘Api’|‘Console’) 还原被替换的系统变量或函数,还原后界面将不在显示相关数据 showWeConsole() 显示[代码]WeConsole[代码]入口图标 hideWeConsole() 隐藏[代码]WeConsole[代码]入口图标 setUIConfig(config: Partial<MpUIConfig>) 设置[代码]WeConsole[代码]组件内的相关配置,可接受的配置项及含义如下: [代码]interface MpUIConfig { /**监控小程序API数据后,使用该选项进行该数据的分类值计算,计算后的结果显示在界面上 */ apiCategoryGetter?: MpProductCategoryMap | MpProductCategoryGetter; /**监控Console数据后,使用该选项进行该数据的分类值计算,计算后的结果显示在界面上 */ consoleCategoryGetter?: MpProductCategoryMap | MpProductCategoryGetter; /**API选项卡下显示的数据分类列表,all、mark、other 分类固定存在 */ apiCategoryList?: Array<string | MpNameValue<string>>; /**复制策略,传入复制数据,可通过数据的type字段判断数据哪种类型,比如api/console */ copyPolicy?: MpProductCopyPolicy; /**定制化列表 */ customActions?: WcCustomAction[]; } /**取数据的category字段值对应的prop */ interface MpProductCategoryMap { [prop: string]: string | MpProductCategoryGetter; } interface MpProductCategoryGetter { (product: Partial<MpProduct>): string | string[]; } interface MpProductCopyPolicy { (product: Partial<MpProduct>); } /**定制化 */ interface WcCustomAction { /**标识,需要保持唯一 */ id: string; /**标题 */ title: string; /**默认执行哪个case? */ autoCase?: string; /**该定制化有哪些情况 */ cases: WcCustomActionCase[]; } const enum WcCustomActionShowMode { /**显示JSON树 */ json = 'json', /**显示数据表格 */ grid = 'grid', /** 固定显示<weconsole-customer>组件,该组件需要在app.json中注册,同时需要支持传入data属性,属性值就是case handler执行后的结果 */ component = 'component', /**显示一段文本 */ text = 'text', /**什么都不做 */ none = 'none' } interface WcCustomActionCase { id: string; /**按钮文案 */ button?: string; /**执行逻辑 */ handler: Function; /**显示方式 */ showMode?: WcCustomActionShowMode; } interface WcCustomActionGrid { cols: DataGridCol[]; data: any; } [代码] addCustomAction(action: WcCustomAction) 添加一个定制化项目;当你添加的项目中需要显示你自己的组件时: 请将 case 的[代码]showMode[代码]值设置为[代码]component[代码] 在[代码]app.json[代码]中注册名称为[代码]weconsole-customer[代码]的组件 定制化项目的 case 被执行时,会将执行结果传递给[代码]weconsole-customer[代码]的[代码]data[代码]属性 开发者根据[代码]data[代码]属性中的数据自行判断内部显示逻辑 removeCustomAction(actionId: string) 根据 ID 删除一个定制化项目 getWcControlMpViewInstances():any[] 获取小程序内 weconsole 已经监控到的所有的 App/Page/Component 实例 log(type = “log”, …args) 因为 console 被重写,当你想使用最原始的 console 方法时,可以通过该方式,type 就是 console 的方法名 on/once/off/emit 提供一个事件总线功能,全局事件及相关函数定义如下: [代码]const enum WeConsoleEvents { /**UIConfig对象发生变化时 */ WcUIConfigChange = 'WcUIConfigChange', /**入口图标显示性发生变化时 */ WcVisableChange = 'WcVisableChange', /**CanvasContext准备好时,CanvasContext用于JSON树组件的界面文字宽度计算 */ WcCanvasContextReady = 'WcCanvasContextReady', /**CanvasContext销毁时 */ WcCanvasContextDestory = 'WcCanvasContextDestory', /**主组件的宽高发生变化时 */ WcMainComponentSizeChange = 'WcMainComponentSizeChange' } interface IEventEmitter<T = any> { on(type: string, handler: EventHandler<T>); once(type: string, handler: EventHandler<T>); off(type: string, handler?: EventHandler<T>); emit(type: string, data?: T); } [代码] 五、后续规划 优化包大小 单元测试 体验优化 定制化升级 基于网络通信的界面化 weconsole 标准化 支持 H5 支持其他小程序平台(支付宝/百度/字节跳动) 六、License WeConsole 使用 MIT 协议. 七、声明 生产环境请谨慎使用。
2021-07-14 - 搭建一个https网站的全过程
概述:本着学习的目的,做了这个分享。自己切切实实的做完了整个流程,发现其中的坑也是蛮多的,当然自己的收获对应也是蛮多的。写下这个流程一方面为了加深自己的印象、可以在将来回顾一下,另一方面也是为了给有需要的人提供帮助~ 一、服务器准备 [代码]为了演示方便,我购买了一台腾讯云服务器 [代码] [图片] 安装的操作系统是centos 二、域名准备 1、域名注册 可以从万网上进行注册:https://wanwang.aliyun.com/ 2、域名备案 备案流程略复杂,这里只列了一个步骤简介 入口:https://beian.aliyun.com/ [图片] 域名的备案时间较长,建议大家提前准备起来。 3、域名解析 域名备案通过之后,为我们的网站准备一个子域名,入口:https://dns.console.aliyun.com/?spm=a2c1d.8251892.aliyun_sidebar.daliyun_sidebar_dns.37575b76kNuXEO#/dns/domainList [图片] 点击上图的解析设置 [图片] 将记录值填写我们刚刚买的服务器的公网ip 三、申请ssl证书 我是从腾讯提供的证书服务里申请的,腾讯申请入口 https://console.cloud.tencent.com/ssl 点击“申请免费证书” [图片] 这里选择了手动Dns验证 [图片] 申请完成后会有个表格,是说明如何Dns校验的,要求域名下添加一条解析记录 [图片] Dns校验 首先,在域名下添加一条txt记录 [图片] 然后,单机自助诊断旁边的“查询” [图片] 下载证书 [图片] 点击图中的下载即可 四、服务器安装软件 我用ssh连接服务器 登录服务器:ssh root@212.129.*.* , 然后输入密码(从腾讯云管理后台进行密码的设置和获取)进入服务器,然后安装软件,如下~ 1、git:用于代码管理 2、nvm:用于管理node版本 3、node:用于启动web服务 4、pm2:用于守护node进程 安装git [代码]yum install git -y [代码] 下载nvm [代码]git clone git://github.com/creationix/nvm.git ~/nvm [代码] 设置nvm 自动运行; [代码]echo "source ~/nvm/nvm.sh" >> ~/.bashrc source ~/.bashrc [代码] 查询node版本 [代码]nvm list-remote [代码] 安装node.js [代码]nvm install v10.16.3 [代码] 使用nodejs [代码]nvm use v10.16.3 [代码] 使用npm安装pm2 [代码]npm install -g pm2 [代码] 五、下载一个web项目 & 使用 pm2 启动 这里我使用了自己的一个github上的项目:https://github.com/myronliu/ssr-koa-react-redux.git 1、git clone https://github.com/myronliu/ssr-koa-react-redux.git 2、cd ssr-koa-react-redux 3、npm install 4、pm2 start server.js 服务启动之后如下图: [图片] 现在我们可以用IP(服务器的公网ip) + 端口号来进行访问了 [图片] 六、安装nginx 步骤 1: 添加 yum 源 Nginx 不在默认的 yum 源中,可以使用 epel 或者官网的 yum 源,本例使用官网的 yum 源。 sudo rpm -ivh http://nginx.org/packages/centos/7/noarch/RPMS/nginx-release-centos-7-0.el7.ngx.noarch.rpm 安装完 yum 源之后,可以查看一下。 sudo yum repolist 步骤 2: 安装 yum 安装 Nginx,非常简单,一条命令: sudo yum install nginx 常用nginx命令介绍 设置开机启动 $ sudo systemctl enable nginx 启动服务 $ sudo systemctl start nginx 停止服务 $ sudo systemctl restart nginx 重新加载,因为一般重新配置之后,不希望重启服务,这时可以使用重新加载。 $ sudo systemctl reload nginx 步骤3: 打开防火墙端口 sudo firewall-cmd --permanent --zone=public --add-service=http sudo firewall-cmd --permanent --zone=public --add-service=https sudo firewall-cmd --reload [图片] 步骤4: 配置nginx 找到并查看配置文件/etc/nginx/nginx.conf [图片] 步骤5: 配置我们自己的conf [图片] 编写为 [图片] 步骤6: 现在可以使用域名访问我们的网站了,目前是http协议的 [图片] 七、安装证书 将第三步下载的证书里选择Nginx下的两个文件上传到服务器的/etc/nginx/conf.d文件夹下 [图片] Mac上利用scp上传 scp /Users/xxx/Downloads/todo.xxx.com/Nginx/1_todo.xx.com_bundle.crt root@212.129.*.*:/etc/nginx/conf.d [图片] 八、创建https的conf文件 进入到/etc/nginx/conf.d下,执行命令:touch https.conf && vi https.conf [图片] 测试nginx配置 & 重启 [图片] 九、访问https协议的站点 [图片] 备注: 如有问题,欢迎指出! 如有侵权,联系删除~
2019-09-24