Zong
南方的冬天

以前觉得杭州的冬天,也就这样过去了,今年春节去了下北京,感受了一下北方的冬天,回来后发现南方的冬天是真的冷……

北京的冷是由外而内的,虽然我已经穿的很厚了,但是风一刮,就觉得格外的冷

杭州的冷是由内而外的,不刮风你也觉得冻 jio ,冷就完事了

熬过这个冬天,又是下一个冬天呀……

吃 UIWebView 一记亏

我司 React 移动端项目,运行在宇宙大行 APP 内,上预发环境后,发现在路由切换进入有 <input> 标签的页面时,键盘会自动唤起。这就很难受,那么开始寻找问题之路,先确认问题出现的场景,查看生产环境未存在此现象,其他环境(Chrome, Safari, WeChat…)也未存在此现象, Android 并未存在此现象,仅 iOS 存在此现象,确认后,尝试将生产环境代码移至预发环境发现此现象已消失,开始查找自身代码问题,因这个项目做过库升级和 Webpack 升级,所以尝试恢复之前版本确认,并非升级所导致问题。因考虑到此问题必须得解决,所以下手从代码角度去解决此问题,尝试使用 document.activeElement.blur 解决此问题,但是 activeElement 并非能完全解决此问题,仍然会出现之前情况,只能解决在用户手动激活 <input> 标签后,用这段代码去缩回键盘的场景。之后联系我司 iOS 开发者配合调试发现,此问题仅出现于 UIWebView ,而 WKWebView 并不会存在此问题,查阅相关资料后,也实践修改 keyboardDisplayRequiresUserAction 参数并无效果,从逻辑上讲 keyboardDisplayRequiresUserAction - UIWebView | Apple Developer Documentation 的默认值是符合业务的,所以无需修改。最后开始仔细检查自身代码后发现是之前同事使用 react-fastclick 所致,将其替换成 fastclick 解决问题。比较坑的是,我接手代码后,并不知情线上版本未使用到 react-fastclick ,使问题找了半天。在 react-fastclick 上也开有相关 issues :Cannot disable fastclick on a particular element #54,当然在替换为 fastclick 也遇到了新的问题,在 UIWebView 下 <input> 标签需要双击才能获得焦点。为此,重写其 focus 方法。

FastClick.prototype.focus = function (targetElement) {
  // 抢先逻辑,当 tagName 为 INPUT,直接 focus
  if (targetElement.tagName === 'INPUT') {
    return targetElement.focus();
  }
  //...
};

Next To Do List

以学习 Next.js 来实践 SSR ,从此起直接换用 Yarn , Yarn 的优点这里也不再提了,下面来介绍下我的学习过程,在阅读完文档后,按照文档教程进行项目初始化,涉及到的 Antd 库的问题成为了首先要解决的事情,那么参照蚂蚁金服官方给出的解决方案 《Next.js 配合使用antd、less (Integration with Antd)》 解决即可,需要个性化修改的是,我这个 Demo 并没有使用到 CSS Modules 而只是使用普通的 CSS 罢了,所以呢我单独修改了他的配置文件,与解决方案有些出入,手动添加规则。

// 其余代码在此省略
config.module.rules.push({
  test: /\.css/,
  exclude: /node_modules/,
  use: cssLoaderConfig(config, {
    extensions: ['css'],
    cssModules: false,
    cssLoaderOptions,
    postcssLoaderOptions,
    dev,
    isServer
  })
})

最后呢,将 React To Do List 项目源码全部移入即可,在这之后我想到将服务端代码也一同移入,比较好的是官方也给出了例子,也感谢社区的强大 with-sitemap-and-robots-express-server-typescript 。参照此,我将 Express Mongo To Do List Server 项目移入,将 tsconfig.*.jsontslint.*.json 分开处理,仍然是依照原先项目,并且对 package.json 中的 "dependencies""devDependencies" 进行了合理的分配。

那么 SSR 项目算是得到了初步的实践,从此 Demo 中很明显的感受到, SSR 项目适合去做什么,不适合去做什么,比如这个 Demo 其实并不适合做 SSR 。所以公司中项目是否需要使用 SSR 得按照实际情况考虑,满足要求再使用即可。

在这之后,想着借势学习 GraphQL ,用来替换本身服务端代码的 RESTful API ,来感受下 GraphQL 之潮。起初因为想避开使用 .graphql 的文件形式,使用 GraphQLSchema 来编写,使用这样的形式编写时,我遇到了些问题,若两个兄弟字段查询的过程都一致,只是分别返回不同的内容的情况下,我暂且不知道如何节省查询,而是将此类兄弟字段塞入一个对象中,由对象去操作 resolve 方法,而非 fields 本身,但是我后来还是选择了使用 buildSchema 来编写,虽然这样无法使用 Lint 来检查代码书写格式,但是我可以直接使用 rootValue 实现查询,对于约定的操作规则或者流程,我自然使用 operationName 来控制,用 switch 来辨别进哪个分支进行处理,当然这样会操作这个函数非常之庞大,逻辑之复杂。现在想起来,感觉 GraphQLSchema 是不是也可以使用这样的形式来编写,虽然当时使用 rootValue 是用来返回 variablesoperationName 的,(我是这样猜想)不过没关系,若后续还有机会的话,再去实践也不是什么问题。

学习 GraphQL 后认为,GraphQL 存在于 RESTful API 之上会更好,底层多数业务仍然需要 RESTful API ,根据业务需求调整 RESTful API 查询数据为全量查询,通过 GraphQL 再来定制更细化的查询结果为更佳。

整个实践过程中,为了将 debug 对象保存(利用 fs 模块)至本地文件进行查看,而非终端查看(很繁琐,不能搜索),将数据使用 JSON.stringify 转换后存入,但是过程中会报错,提示对象中有循环引用 JSON.stringify, avoid TypeError: Converting circular structure to JSON ,最终借用 circular-json 库来解决此问题。 Node.js 上的调试之路,我还是没了解多少。

用 Parcel 感受零配置

Parcel 是以零配置出现的,那么来学习一下吧,体验了一把 Parcel 来构建 React 项目,确实比起 Webpack 配置少了许多,但是当我阅读到 API 这章时,我笑了。零配置的概念选用的是社区最佳,但是在个性化上,这个问题上还是 Webpack 更胜一筹,在开发项目时,有多少项目时开箱即用不需要个性化配置的,我想这是少之又少的,你要真比起这,回想一下 create-react-app 构建出来的项目,隐藏了所有配置。这么说来 Vue CLI 3.x 做的也不错,他提供了一套 GUI 图形化界面,让开发者省去学习文档时间,这才是真正的开箱即用吧。所以工程化这件事上,该学的还是得学,一样不能少。

源码阅读计划

这个月简单的阅读了 Immutable.js 和 Lodash ,这两个库。来简单说说,我学到的东西吧,虽然没有完完整整的阅读。

  • Immutable.js 中非常有用的方法: mergeDeep, getIn, setIn, updateInwithMutations 方法用来解决多次克隆的性能问题。
  • Lodash 可以让数组的操作更简单。

重点来了!!! 计划阅读 React 源码,查看 GitHub 仓库发现最早期版本是 0.3-stable ,那么就决定从这个版本开始阅读,同时开始模仿写轮子。