hxl 发布于 07月23, 2018

你一定是闲得蛋疼才重构的吧

你一定是闲得蛋疼才重构的吧

随着“发布”进度条走到100%,重构的代码终于上线了。我露出了老母亲般的围笑……

最近看了一篇文章,叫《史上最烂的开发项目长啥样:苦撑12年,600多万行代码》,讲的是法国的一个软件项目,因为各种奇葩的原因,导致代码质量惨不忍睹,项目多年无法交付,最终还有公司领导入狱。里面有一些细节让人哭笑不得:一个右键响应事件需要花45分钟;读取700MB的数据,需要花7天时间。足见这个软件的性能有多糟心。

如果让笔者来接手这“坨”代码,内心早就飘过无数个敏感词。其实,笔者自己也维护着一套陈酿了将近7年的代码,随着后辈的添油加醋……哦不,添砖加瓦,功能逻辑日益复杂,代码也变得臃肿,维护起来步履维艰,性能也不尽如人意。终于有一天,我听见了内心的魔鬼在呼唤:“重构吧~~”

重构是一件磨人的事情,轻易使不得。好在兄弟们齐心协力,各方资源也配合到位。我们小步迭代了大半年,最后一鼓作气,终于完成了。今天跟大家分享一下这次重构的经验和收益。

挑战

此次重构的对象是一个大型单页应用。它实现了云端文件管理功能,共有10个路由页面,涉及文件上传、音视频播放、图片预览、套餐购买等几十个功能。前端使用QWrap、jQuery、RequireJS搭建,HTML使用PHP模板引擎Smarty编写。

阅读全文 »

hxl 发布于 06月12, 2018

同学,W3C了解一下?

虚拟人物A:“同学,W3C了解一下?”

我:“嗷,是那个Web标准化组织吗?这个组织里的人每天都做什么?平时写不写bug呀?”

你第一次看到W3C这个词的时候,内心是不是秒演上面这段戏?别慌,我们都一样~

直到4月份一个瘦瘦高高的小哥哥来访我数字公司,我才了解这个“神秘”的组织。这个小哥哥叫薛富侨,是W3C中国的北航总部团队成员。他的演讲解答了我心中的很多疑惑,并激发了我加入W3C工作组的兴趣。一周前小编加入Web性能工作组。想了解小编如何参加W3C工作组可以直接跳到最后一节查看~

阅读全文 »

公子 发布于 06月03, 2018

Animaris SVG LOGO 动画设计

前段时间我开源了一个叫 [Animaris][1] 的项目,这个项目是使用 ThinkJS + MongoDB + React + Antd 开发的移动端 WebView 接口文档系统。平常大家见到的接口文档无非就是 HTTP API 接口文档,要么就是框架/库提供的接口方法文档。对于这种 WebView 的接口提供文档基本上没有。借着业务的需求我做了这么一个项目,用来解决以下两个问题:

  1. 移动端接口编写并生成可视化文档
  2. 移动端接口前端开发环境模拟问题

如果有相关需求的同学也欢迎使用,感兴趣的同学也欢迎 [star][2]。咳咳,回到本文的重点,项目开发的差不多的时候我就准备给它设计一款 LOGO 了,以下是成品效果图。虽然我没有学过绘画没有很好的设计功底,但是我相信简单的形状也能发挥不错的效果,那么我就给大家讲讲我是如何设计这款 LOGO 的。

animaris

阅读全文 »

蔡斯杰 发布于 05月16, 2018

Web框架的架构模式探讨(JavaScript语言)

在写干货之前,我想先探(qiang)讨(diao)两个问题,模式的局限性?模式有什么用?

最近看到一篇文章对我启发很大,许来西在知乎的回答《哲学和科学有什么关联?》,全篇较长,这里摘录我要引出的一点:

科学作为一种经验主义的认识论,有着经验主义的巨大缺陷:它永远不能产生绝对正确的真理。这是归纳法的本质决定的。而且值得注意的是,归纳不具有唯一性。

举一个简单的例子,我们假设一个世界,如下图:

一个青蛙世界

科学家很快有了两种归纳方式:

  • 世界上所有的青蛙都戴眼镜
  • 世界上所有戴眼镜的都是青蛙

在没有更多的信息的时候,我们应该如何选择正确的理论呢?答案是无法选择。

阅读全文 »

公子 发布于 01月17, 2018

前端 WebView 指南之调试篇

原文: https://imnerd.org/webview-debug.html

WebView 是一个客户端浏览器控件,可以实现加载并渲染网页的逻辑。但是这个控件并不能完全同等于浏览器,而且我们页面的一些行为会依赖客户端的交互所以我们需要在 WebView 环境中进行调试。下面我就来说一说简单的 WebView 调试方法。

抓包

抓包即我们查看下 WebView 中的所有网络请求,在很多无法获取到机器的时候非常有用。通常页面行为不正常往往是接口请求的参数不正确,或者是接口返回的数据有异常。甚至于页面行为存在打点,根据打点请求来判断行为是否正常。通过这种“望闻问切”的方式,有些问题能够浮出水面。市面上抓包软件很多,Windows 上大家一般都是用 [Fiddler][1], Mac 上则使用 [Charles][2],还有其它的这里就不一一列举了。不过软件很多原理确实一样,简单的说来则是使用 HTTP 代理将所有的请求转发到软件记录本次 HTTP 请求的相关数据。

首先我们需要保证手机和电脑在同一个局域网中,软件中开启 Proxy 配置,这里以 Charles 为例,如图勾选"Enable transparent HTTP Proxying"即可。然后手机 WiFi 上配置 HTTP 代理 IP 为你的电脑 IP,端口为刚才软件中配置的端口(默认8888)。配置完后如无问题就可以在软件中看到请求流了。我们可以类似于 Chrome 开发者工具中的 Network 一样详细的查看请求的请求报文和响应报文。

![Charles Enable Proxy][3]

阅读全文 »

公子 发布于 01月16, 2018

前端 WebView 指南之 iOS 交互篇

原文:https://imnerd.org/ios-webview-and-js.html

前文我们介绍了 Android 的 WebView 交互方式,iOS 从原理上来说和 Android 还是非常类似的。在 iOS 中 WebView 需要分为UIWebView 和 iOS8 中新增的 WKWebView 两种类型。其中 WKWebView 相较于 UIWebView 优势在于能够直接使用系统 Safari 渲染引擎去渲染页面,支持更多的 HTML5 特性,渲染性能也会更好点。由于对 iOS 开发了解不太多,以下的代码大多是网络整理,没有 swift 的实现,如果有任何错误还请及时联系。

客户端调用 JS

两个 WebView 类型提供了不同的调用方式,但是基本上可以归类成以下两种:

evaluateScript

在 UIWebView 中,iOS7+ 提供了 JavascriptCore 让我们能够直接在 WebView 中获取到 JSContext,也就是当前执行环境的 JS 上下文。在这里我们就可以获取到对应的 JS 方法并执行,是非常高效的执行方式。同时这种方式的好处是能够拿到 JS 执行的结果,并转换成对应的 JS 类型。定义好 jsContext 之后就可以调用 evaluateScript 方法来执行 JS 了。

- (void)webViewDidFinishLoad:(UIWebView *)webView
{
    JSContext *jsContext = [self.webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
    //设置JS执行报错捕获
    [self.jsContext setExceptionHandler:^(JSContext *context, JSValue *exception){
        NSLog(@"%@", exception);
    }];

    JSValue *value = [self.jsContext evaluateScript:@"document.title"];
    self.navigationItem.title = value.toString;
}
Objective-C 数据类型 对应 JavaScript 数据类型
nil undefined
NSNull null
NSString string
NSNumber number, boolean
NSDictionary Object object
NSArray Array object
NSDate Date object
NSBlock Function object
id Wrapper object
Class Constructor object

阅读全文 »

公子 发布于 01月15, 2018

前端 WebView 指南之 Android 交互篇

原文:https://imnerd.org/android-webview-and-js.html

Webview 是移动端应用中的一个控件,提供了类似浏览器可以在 App 中加载网页的功能。现在市面上很多应用都会使用这种方式内嵌一些 h5 页面用来实现产品功能。使用这种方式带来的好处就是支持快速迭代更新,并且页面的功能是全网升级。当然目前 RN 和 Codorva 给我们带来的热更新方案也是可以的,只是目前 Apple 的态度很拒绝,这里我们略过不表。在 Webview 中的网页势必存在和客户端进行交互的动作,进行数据的共享。下面我们就来说说 Android Webview 中 JS 和 Native 的交互方式。

客户端调用 JS

loadUrl()

我们明白 Webview 其实就是在加载网页,所以客户端可以直接访问 javascript:console.log('hello') 这样的伪 URL 即可实现在页面注入需要执行的 JS 代码。调用方法如下:

Webview webview = (WebView) findViewById(R.id.webView);

webView.loadUrl("javascript:console.log('hello')");

这样我们就实现了调用 JS 的目的了。loadUrl() 的方案从另外一个角度来看可以算是 hack 方案了,对客户端来说,他们的 JS 交互本质上其实就是一个拼接 JS 字符串的过程。

evaluateJavascript()

刚才我们也说了 loadUrl() 不是 Android 的正经解决方法。好在官方也想到了这点,在 Android 4.4+ 之后,官方给提供了原生的方法支持调用,那就是 evaluateJavascript()。这个方法最大的好处就是能够直接在一次执行的时候获取到 JS 返回的结果。如果是使用 loadUrl() 的方式的话,执行完后对客户端来说这句话就结束了,如果想要拿到返回的结果的话另外需要 JS 调用客户端的方法返回。

阅读全文 »

公子 发布于 11月15, 2017

ThinkJS 3.0 如何实现对 TypeScript 的支持

ThinkJS 3.0 是一款面向未来开发的 Node.js 框架,内核基于 Koa 2.0。 3.0 相比 2.0 版本进行了模块化改造,使得内核本身只包含了最少量必须的代码,甚至还不足以构成一个完整的 Web MVC 框架,除了内核里面实现的 Controller, View 和 Model 被实现为扩展(Extend)模块 think-viewthink-model,这样实现的好处也是显而易见的,如果我的 Web 服务只是简单的 RESTful API,就不需要引入 View 层,让代码保持轻快。

think-cli 2.0 新版发布

在本文发布的同时 ThinkJS 团队发布了新版的脚手架 think-cli 2.0,新版脚手架最大的特点是脚手架和模板分离,可以在不修改脚手架的基础上添加各种项目启动模板,如果老司机想跳过下面实现细节,快速开始尝试 TypeScript 下的 ThinkJS 3.0, 可以用 think-cli 2.0 和 TypeScript 的官方模板:

npm install -g thinkjs-cli@2
thinkjs new project-name typescript

阅读全文 »

公子 发布于 11月14, 2017

75CDN 增加 SRI 支持

[75CDN][75cdn] 是一个由奇舞团维护的静态资源托管平台,创立至今已经稳定运行了一年多的时间。近期我们增加了 SRI 的支持,作为国内首个提供 SRI 服务的静态资源库了,也算是为 [75CDN][75cdn] 一周年庆生吧。

SRI 全称是 Subresource Integrity,是用来解决由于 CDN 资源被污染而导致的 XSS 漏洞的方案。当浏览器检测加载脚本签名与给定的签名不一致时,会拒绝执行该脚本。目前浏览器的支持情况如下:

浏览器 支持版本
Chrome 以及 Chrome for Android 45+
Firefox 以及 Firefox Mobile 43+
Safari 以及 iOS Safari 11+
IE 以及 Edge 不支持
UC 浏览器 不支持

注: 数据来源于 [CanIUse][caniuse] 和 [MDN][mdn]

阅读全文 »