292020.6

Creating custom JavaScript syntax with Babel

212020.6

Does DDD Belong on the Frontend? - Domain-Driven Design w/ TypeScript

172020.6

NPM 依赖包版本范围控制

基本概念就不多说了,主要是想在项目中,使用“范围”控制的优势,写了一个依赖版本号之后,未来依赖包升级可以不需要手动升级该版本号,可自动安装最新兼容版本。

常规兼容

常规情况下,需要掌握 ^, ~, x, - 这几个版本控制符即可。例如 ^1.0.0 相当于 1.x,~1.1.0 相当于 1.1.x。

实验阶段的包

版本号以 0 开头的包都是实验阶段的。例如 0.0.1, 0.1.0 这种包都是处于实验阶段,还为发布正式版本,因此,在正式环境使用时要小心。基于这种情况,我建议直接写死版本号,而不要采用 ^ 或 ~,因为你怎么知道新加的实验功能是否符合你的预期。

当然,纯理论探讨,实验阶段的包也可以 ^ 或 ~,但是相对而言,全部降一位。例如 ^0.1.0 可以兼容 0.1.1 版本,但不兼容 0.2.0 版本。如果 ~0.0.1,相当于没写 ~。

Prerelease

和实验阶段包又不同,它处于预发布阶段。比如在发布 3.0.0 之前,可能需要公测一段时间,各种修 bug。但理论上,prerelease 相当于正式版的实验阶段。

对于 prerelease 版本而言,前面的常规方案和实验阶段常规方案,都不包含 prerelease 版本,也就是说 ^3.0.0 并不包含 3.1.0-alpha.1。但是反过来,3.1.0-alpha.1 属于 3.1.0 的一部分,用一个比喻来类比:A-, A, A+ 都属于 A 等。但是 ~A, ^A 都只包含 A, A+ 而不包含 A-,类比数学上的概念,就是复数中虚数部分。

那么怎么控制 prerelease 的范围呢?

^3.0.0-alpha 将包含 3.0.0-alpha.0, 3.0.0-beta.0, 3.0.0-rc, 3.0.0, 3.1.0...,但不包含 3.1.0-alpha.x。也就是说,^ 或 ~ 可以包含所指示的版本的 prerelease 版本,以及兼容该版本的高版本(不含高版本的 prerelease 版本)。

升级 prerelease 可以使用 npm version prerelease 进行升级。

两个 prerelease 版本号谁的版本更高呢?prerelease 末尾版本号部分纯粹以字母顺序进行排序,因此 rc > beta > alpha,而且,由于纯粹按字母排序,所以没有 alpha.x 这种使用 x 的表示方法。因此,如果要控制为只包含 prerelease 的版本,没有直接的办法,只能使用 >=3.0.0-alpha <3.0.0-beta 这种表示方法。

12:07:28 已有0条回复
112020.6

纯CSS实现Table固定表头和首列

Table固定表头和首列这种需求应该比较常见。以往的做法,需要写一大堆脚本,而现在,可以使用position:sticky轻松实现这个效果。

.table-container {
width: 100%;
height: 100%;
overflow: auto;
}

/* 首列固定 */
.table-container thead tr > th:first-child,
.table-container tbody tr > td:first-child {
position: sticky;
left: 0;
z-index: 1;
}

/* 表头固定 */
.table-container thead tr > th {
position: sticky;
top: 0;
z-index: 2;
}

/* 表头首列强制最顶层 */
.table-container thead tr > th:first-child {
z-index: 3;
}

HTML结构上,必须将 <table> 放在 <div class="table-container"> 子节点,且内部不要有其他 position 设置。

14:48:16 已有0条回复
102020.6

NPM 版本范围控制

092020.6

angularjs有什么点可以碾压vue, react之流

这里所指的angularjs是只angular早期的1.x版本。虽然vue, react在热度上已经碾压angularjs几条街,但是在面对web开发(以DOM为中心的开发)中,某些场景下面,angularjs可能比任何框架或库都做得好。这里,主要举例两个点。

Modal弹窗的隐现

现在是单向数据流和immutable的天下,其目的是为了数据流所蕴含的业务流清晰,但代价是代码编写变得复杂。举一个例子,用react写一个弹出框modal,按照单向数据流的范式,必须将modal的隐现通过一个prop来控制,而这个prop必须由外部组件传入,为了控制这个prop,就必须再配合一个回调函数来触发prop的改变。这是对modal组件而言,而对于外层调用modal组件而言,必须自建一个state传给对应的prop,同时,必须自建一个方法作为回调函数传给modal。这里面编程出错的几率远远大于保证业务流正确的几率,也就是成本的提升。因为,你必须在回调函数中,正确处理state的变化值。

而双向数据绑定则完全不需要,传入prop之后,不需要再在回调函数中修改state,双向绑定逻辑会自动修改state。(当然,这基于不同的数据思想,一个是immutable,一个是mutable,各自不同。)虽然基于的范式不同,但是一个modal的显示和隐藏在双向数据绑定范式下,更有利。

表格固定列

Web表格(grid table)是前端交互领域及其复杂的一个场景。其中的一个需求是,固定表格的前n列,剩下的可以左右滑动来查看。在基于 virtual dom 的 vue, react 编程中,自己手写是及其麻烦的,你需要手动在模板中拆分块,在脚本中拆分数据。总之,由于virtual dom的编程范式如此,本身就是要隔绝dom的操作。但是实际上,在前端领域,grid table的操作往往是virtual dom最早提出来的,基于数据变化,只修改小部分dom的需求。但是,实际上最终,virtual dom类编程,在这个点上,反而是最辣鸡的。辣鸡之点不在于性能,而在于编程的复杂。

而使用angularjs则太过便利。首先,angularjs也是基于数据响应更新界面的。其次,angularjs是基于DOM操作进行渲染的。所以,在angularjs中,如果要实现表格固定列的需求,只需要写一个directive,使用 template() 函数来动态返回模板,返回的模板是字符串,于是可以各种骚操作修改字符串来控制html结构,这比vue、react的结构编程快上10倍不止。接下来是对DOM的重新调整,当按照模板结构和样式完成渲染之后,你可能还需要调整列宽度、位置、滚动条是否显示、左右两边每行的点击联动、左右都可滚动(pointer-events: none;)等等操作,在不修改任何数据的情况下,瞬间通过DOM操作完成。而如果这些东西依赖virtual dom去做,可以说极其麻烦,代码量上翻10倍很正常。

除了上述这两个例子外,我在开发中还会碰到其他的一些场景,发现有的时候恨angular是垃圾,有的时候又觉得它diao。总之,在不同的场景下,不同的编程范式所带来的收益是不同的,但是问题点在于,我们无法真正的完全在同一套代码中享受不同范式的好处。这也是前端框架的一个不足之处吧。

13:26:17 已有0条回复