GithubHelp home page GithubHelp logo

weekly's Issues

那些入坑 React 前没有人会提醒你的事

聊了这么多严肃的话题,本周来聊聊部分开发者对 React 的吐槽以及 Facebook 官方是如何回应的吧。

本周文章

本周的文章事实上由两篇文章组成:

一篇是 Gianluca Guarini 写的 《Things nobody will tell you about React.js》,我将它译作 《那些入坑 React 前没有人会提醒你的事》,因为作者行文中明显带着对 React 的批判和失望。

另一篇则是 Facebook 员工,也是 Redux 作者的 Dan Abramov 针对上文的回复 《Hey, thanks for feedback!》。

文章摘要

Gianluca Guarini 着重吐槽的点在于:

  • React 项目文件组织规范不统一,社区中 Starter Kit 太多(100+),新手不知道该怎么组织文件
  • 由于 React 只关心 View 层,开发者就要面临选择 mobx 还是 redux 的纠结,无论选择哪种都会带来一系列的问题(重新配置构建脚本,更新 eslint 规则等)
  • 如果选了 mobx,会发现 mobx 无法保证自己的 store 不被外部更新(官方建议是加上特殊的前缀)
  • 如果选了 redux,会发现要实现同样的功能需要写很多的重复代码(这也是为什么社区中有海量的 redux helper 存在)
  • 路由用起来也很蛋疼,因为 React Router 几乎是社区中唯一的选择,但是这货版本更新太快,一不小心就用了废弃的 API

至于 Dan 怎么回复的,留给参与讨论的同学自行发现。

为什么选择这篇文章

我们团队最早在 2014 年中就确定了 React 作为未来的发展方向,那个时候很多人都还在感叹 Angular(那时候还是 Angular 1)是一个多么牛 x 的框架,很多人甚至听都没有听说过 React。

在不到三年的时间里,React 社区迅速的发展壮大,许多 Angular、Ember、Knockout 等框架的拥趸,或主动或被动的都逐渐开始向 React 看齐。

站在 React 已经繁荣昌盛、无需四处布道宣传的今天,我们不妨冷静下来问问自己,React 真的是一个完美的框架吗?无论是从 React 0.10 时期开始摸索,还是被 React Router 折磨的死去活来,再到 Flux、reflux 和 Redux 的革命,以及 redux-saga 及 mobx 的新兴。

这一路走来,我们到底解决了什么样的问题?React 又在其中扮演了什么样的角色?请大家开怀畅言,说出你与 React 之间的故事。

精读《架构设计 之 DCI》

随着前端ES6 ES7 的一路前行, 我们大前端借鉴和引进了各种其他编程语言中的概念、特性、模式; 我们可以使用函数式Functional编程设计,可以使用面向对象OOP的设计,可以使用面向接口的**,也可以使用AOP, 可以使用注解,代理、反射,各种设计模式; 在大前端辉煌发展、在数据时代的当下 我们来一起阅读一篇设计相关的老文:

《The DCI Architecture》

精读《2017前端性能优化备忘录》

文章地址:https://www.smashingmagazine.com/2016/12/front-end-performance-checklist-2017-pdf-pages/

现在随着web应用的复杂性日益增加,其性能优化就会显得尤为必要,同时会给性能指标分析带来新的挑战,因为性能指标之间的差异性非常大,这取决于使用的设备、浏览器、协议、网络类型以及其它能够对性能产生影响的潜在因素(如:CDN、ISP、cache、proxy、firewall、load balancer、server等)。

本文提供了解决类似如何让网站响应更加迅速、访问更加流畅等前端性能优化问题的方法,读者们可以提供一些在实际场景中的性能优化问题以及解决方案,可泛谈优化策略,亦可针对性深入讨论某个优化方法。

精读《 Designing The Perfect Date And Time Picker》

文章地址: https://www.smashingmagazine.com/2017/07/designing-perfect-date-time-picker/

time picker 作为基础UI组件的重要一员,可能面对什么样的场景?这些场景分别适合怎样的展现形式?

这篇文章中可以了解到国外各大网站time picker 的设计,不一定是通用型,但都是指定场景下的优秀设计。从这些设计中我们可以提取出哪些优秀的思考优化我们的组件呢~~

大家集思广益,说说你遇到过的最好的time picker (设计和组件都行)? 在实际业务中针对哪些场景做过优化?

谢谢~

精读《dob - 框架使用》

本系列分三部曲:《框架实现》 《框架使用》 与 《跳出框架看哲学》,这三篇是我对数据流阶段性的总结,正好补充之前过时的文章。

这次写第二部 《框架使用》。对 dob 的使用方式做介绍,同时对前端数据流工程实践做一些分类。

精读 《Nestjs 文档》

文档地址:https://docs.nestjs.com/

之所以读它,因为它是一个优雅的类库,基于 express,特别支持 typescript,拥有依赖注入、模块拆分,装饰路由等强大特性,对 async、await 处理也符合我的这篇文章**: Callback Promise Generator Async-Await 和异常处理的演进

再配置上 docker-compose,typeorm,一套精美绝伦的强类型 nodejs framework 就建成了,其开发体验丝毫不亚于基于 java 的框架。

精读《When You “Git” in Trouble: a Version Control Story》

精读《When You “Git” in Trouble: a Version Control Story》

本期我们看一篇比较轻松的文章,与 git 相关,大家可以讲讲自己与 git 的故事,如何通过 git 解决各式各样的冲突,以及多年使用 git 老司机们的心得和感悟。
精读不仅仅只关注于文章本身,文章只是个引子,更希望大家积极参与互动与讨论,才是精读的精髓之处。

本期精读文章地址:https://hackernoon.com/when-you-git-in-trouble-a-version-control-story-97e6421b5c0e

参与讨论地址:#49

精读《css-in-js 杀鸡用牛刀》

文章地址:https://codeburst.io/css-in-js-is-like-replacing-a-broken-screwdriver-with-your-favorite-hammer-c9765c9ee43b

文章提到,虽然 css 还有许多不足,但已经在改进中,并且提醒我们关注已经产生的 OOCSS, SMACSS, BEM, ITCSS, 和 ECSS 方案。同时 css-in-js 的模块化思维确实可取,但曲解了 css 本意,被抱怨的全局冲突问题,也是为了控制整站样式与切换主题。

也许 css-in-js 是一条误解 css 本意的道路,那么问题来了,显然 css 在初期(未来应该也是)被设计用来控制全局,那么就越来越复杂的 web 生态而言,是整体控制好呢,还是局部控制好?

精读《how we position and what we compare》

本篇文章以一个简单的例子,抽丝剥茧细数讲述如何面向用户可视化设计,化繁为简,化多为少,探索用户最终的目的,如何一张图中体现N张图的含义。具体内容,请和我一起走进 story telling data 系列 - how we position and what we compare http://www.storytellingwithdata.com/blog/2017/12/14/how-we-position-and-what-we-compare <---- 此处应该有 x 档案 bgm ....

提前剧透:

image

如何从左图变化到右图,难道作者是个拥有魔法棒的小仙女,还是可以点石成金的老神仙??一起详细看文章,魔法是如何修炼成功的。

image

哎哟,这里没有内容咯~~~ 评论区等你哦~

精读周刊反思

到今天,精读周刊一共发了 33 期,也就是坚持了 33 个星期,8 个多月。

我认为聚合周刊是一种知识的发散,可以提高知识“广度”,而精读每周只选一篇,尤其结合自身的思考,希望能提高知识的”深度“。

在这 8 个月中,所有文章都由我们内部同学完成,我承担了大部分,这与我的预期有所偏差,我希望精读能集思广益,防止成为我个人的笔记。因为业务繁忙,所以不少期的内容偏少,质量也不够高。

精读写作的流程分为 引言 - 内容概要 - 精读 - 总结

每周选择文章都很纠结,但最终为什么会选择那一篇,这就是引言的意义。

内容概要不是翻译,而是对文章的总结,我们每次抱着学习的态度去阅读选文,在学习到知识的同时,散发出一些感悟形成了精读。

总结很多时候也许是多余的,内容也比较含糊,甚至与文章标题相反。许多知识点都是发散的,精读没必要,也没有能力给每个文章、每个知识点一个结论。去享受 “读” 的过程,并养成读后思辨的习惯,应该是精读真正的作用。

精读《前端数据流哲学》

本系列分三部曲:《框架实现》 《框架使用》 与 《跳出框架看哲学》,这三篇是我对数据流阶段性的总结,正好补充之前过时的文章。

这次写第三部 《跳出框架看哲学》。对各种数据流模式做一个整体梳理。

精读《W3C发布加密媒体扩展(Encrypted Media Extensions,EME)正式推荐标准》

精读文章地址:

2017年9月18日, “ W3C 发布 EME 标准,EFF 退出 W3C” 。我们今天来聊聊,这个有争议的 EME 到底是什么?和 DRM 有什么关系?它会对 Web 未来产生什么样的影响?

owner 排期表

  • 2018.06.29
  • 2018.06.22
  • 2018.06.15
  • 2018.06.08
  • 2018.06.01 黄子毅📖
  • 2018.05.25 黄子毅📖
  • 2018.05.18 黄子毅📖
  • 2018.05.11 黄子毅📖
  • 2018.05.04 黄子毅📖
  • 2018.04.27 黄子毅📖
  • 2018.04.20 黄子毅📖
  • 2018.04.13 留影📖
  • 2018.04.06 君霖📖
  • 2018.03.30 evilucifero📖
  • 2018.03.23 宾彬📖
  • 2018.03.16 黄子毅📖
  • 2018.03.09 黄子毅 📖
  • 2018.03.02 黄子毅 📖
  • 2018.02.23 黄子毅📖
  • 2018.02.16 黄子毅📖
  • 2018.02.09 留影📖
  • 2018.02.02 evilucifero📖
  • 2018.01.26 黄子毅📖
  • 2018.01.19 陈屹📖
  • 2018.01.12 黄子毅📖
  • 2018.01.05 君霖📖
  • 2017.12.29 黄子毅📖
  • 2017.12.22 猫神📖
  • 2017.12.15 宾彬📖
  • 2017.12.08 黄子毅📖
  • 2017.12.01 黄子毅📖
  • 2017.11.24 丁玲📖
  • 2017.11.17 黄子毅📖
  • 2017.11.10 黄子毅📖
  • 2017.11.03 黄子毅📖
  • 2017.10.27 五灵📖
  • 2017.10.20 宾彬📖
  • 2017.10.13 黄子毅📖
  • 2017.09.29 北渔📖
  • 2017.09.22 黄子毅📖
  • 2017.09.15 五灵📖
  • 2017.09.08 黄子毅📖
  • 2017.09.01 黄子毅📖
  • 2017.08.25 evilucifero📖
  • 2017.08.18 黄子毅📖
  • 2017.08.11 留影📖
  • 2017.08.04 黄子毅📖
  • 2017.07.28 猫神📖
  • 2017.07.21 淡苍📖
  • 2017.07.14 留影📖
  • 2017.07.07 黄子毅📖
  • 2017.06.30 载天📖
  • 2017.06.23 黄子毅📖
  • 2017.06.16 淡苍📖
  • 2017.06.09 黄子毅📖
  • 2017.06.02 五灵 📖
  • 2017.05.26 黄子毅📖
  • 2017.05.19 jasonslyvia📖
  • 2017.05.12 Jason📖
  • 2017.05.05 黄子毅📖
  • 2017.04.28 留影 📖
  • 2017.04.21 jasonslyvia 📖
  • 2017.04.14 Camsong 📖
  • 2017.04.07 陈屹 📖
  • 2017.03.31 黄子毅 📖

排期专用,请勿回复。

  • 以上时间为发布日
  • 每周精选结束后关闭对应文章池的 Issue
  • 每周五发布本周文章,同时下一周的 owner 当天新建下周主题 issue
  • 在本仓库提交文章
  • 整理好的文章发到:前端精读评论专栏

精读《dob - 框架实现》

本系列分三部曲:《框架实现》 《框架使用》 与 《跳出框架看哲学》,这三篇是我对数据流阶段性的总结,正好补充之前过时的文章。

这次写第一部 《框架实现》。可以理解为对数据流:rxjs、redux、mobx,还有自创的 dob 做一个精读。

抽丝剥茧,锁定依赖追踪

做基于 React 的状态管理?先抽象出最小功能,依赖追踪是核心。

如何结合 React

observe 可以类比到 React 的 render,它们都具有相同的特征:是同步函数。聪明的你想到了吗?

限制一些功能,会更好用

为了使用起来具有更好的可维护性,需要限制依赖追踪的功能,使值不能再随意的修改。可见,强大的功能,不代表在数据流场景的高可用性,恰当的约束反而会更好。

如何有层次的做 Debug

调试功能,在依赖追踪、与 react 结合这一层都需要做,怎样分工配合才能保证功能不冗余,且具有良好的拓展性呢?

Debug UI 如何解耦

这种场景最佳解耦秘籍:事件机制。通过精心定义的一系列事件,制造出一个具有生命周期的工具库!

observe 嵌套如何解决

依赖收集由 getter、setter 完成,但触发时,却无法定位触发代码位于哪个函数中,所以为了依赖追踪(即变量与函数绑定),需要定义一个全局的变量标示当前执行函数。但是,当函数嵌套函数时,如何保证顺序?这看似小的问题,实现方式却几乎是整个源码中最复杂的:同步函数延迟执行。

精读 js 模块化发展

这次是前端精读期刊与大家第一次正式碰面,我们每周会精读并分析若干篇精品好文,试图讨论出结论性观点。没错,我们试图通过观点的碰撞,争做无主观精品好文的意见领袖。

本期精读的文章是:evolutionOfJsModularity

懒得看文章?没关系,稍后会附上文章内容概述,同时,更希望能通过阅读这一期的精读,穿插着深入阅读原文。

如今,Javascript 模块化规范非常方便、自然,但这个新规范仅执行了2年,就在 4 年前,js 的模块化还停留在运行时支持,10 年前,通过后端模版定义、注释定义模块依赖。对经历过来的人来说,历史的模块化方式还停留在脑海中,反而新上手的同学会更快接受现代的模块化规范。

但为什么要了解 Javascript 模块化发展的历史呢?因为凡事都有两面性,了解 Javascript 模块化规范,有利于我们思考出更好的模块化方案,纵观历史,从 1999 年开始,模块化方案最多维持两年,就出现了新的替代方案,比原有的模块化更清晰、强壮,我们不能被现代模块化方式限制住思维,因为现在的 ES2015 模块化方案距离发布也仅仅过了两年。

内容概要

直接定义依赖 (1999)

// file greeting.js
dojo.provide("app.helloWrold") // define module
app.helloWrold.say = function () {
  return 'hello'
};

// file hello.js
dojo.provide("app.hello") // define module
dojo.require('app.helloWrold') // import module

app.hello = function(x) {
  return app.helloWrold.say()
};

可以看出,由于当时 js 文件非常简单,模块化方式非常简单粗暴。

这种定义方式与现在的 commonjs 非常神似,区别是 commonjs 以文件作为模块,而这种方法可以在任何文件中定义模块,模块不与文件关联。

其实现在 Typescript 定义 namespace 的方式,和这种方法特别的像,因为我们可以在一个文件定义多个 namespace:

declare namespace app;
declare namespace user;

这种突兀的变量定义方式(app.hello)不利于项目维护,还需要手动维护模块定义,可用,但不优雅。

闭包模块化模式 (2003)

var helloWorld = (function() {
  return {
    say() {
      return 'hello'
    }
  }
}())

最后括号也可以放外部,这种闭包方式解决了变量污染问题,只需要影响一个全局变量。

但影响一个也是影响,多了还是容易乱套,这种方式没有解决文件引用顺序问题,不同加载顺序可能出现全局变量未赋值的情况(定义倒是提前了,但还是会报错)。

模版依赖定义 (2006)

/*borschik:include:../lib/main.js*/

这时候开始流行后端模版语法,通过后端语法聚合 js 文件,从而实现依赖加载,说实话,现在 go 语言等模版语法也很流行这种方式,写后端代码的时候不觉得,回头看看,还是挂在可维护性上。

注释依赖定义 (2006)

/*! lazy require scripts/hello.js */
hello.say()

几乎和模版依赖定义同时出现,与 1999 年方案不同的,不仅仅是模块定义方式,而是终于以文件为单位定义模块了,通过 lazyjs 加载文件,同时读取文件注释,继续递归加载剩下的文件。

这简直和最新标准 <script type=module> 如出一辙,如今仅仅将这个**标准化了,将注释定义依赖替换成了 import export 关键词罢了。

挺支持这种方式的,连打包都不需要了,现在终于得到标准的支持,非常激动人心。

外部依赖定义 (2007)

// file deps.json
{
    "files": {
        "main.js": ["helloWorld.js"],
    }
}

这种定义方式在 cocos2d-js 开发中普遍使用,其核心**是将依赖抽出单独文件定义,这种方式不利于项目管理,毕竟依赖抽到代码之外,我是不是得两头找呢?所以才有通过 webwpack 打包为一个文件的方式暴力替换为 commonjs 的方式出现。

Sandbox模式 (2009)

// file sandbox.js
function Sandbox(callback) {
    var modules = [];

    for (var i in Sandbox.modules) {
        modules.push(i);
    }

    for (var i = 0; i < modules.length; i++) {
        this[modules[i]] = Sandbox.modules[modules[i]]();
    }
    
    callback(this);
}

// file hello.js
Sandbox.modules = Sandbox.modules || {};

Sandbox.modules.helloWorld = function () {
    return 'hello'
};

// file app.js
new Sandbox(function(box) {
    var result = box.helloWorld()
});

这种模块化方式很简单,暴力,源码都能直接写到代码里。硬伤是无法解决明明冲突问题,毕竟都塞到一个 sandbox 对象里,而 Sandbox 对象也需要定义在全局,存在被覆盖的风险。模块化需要保证全局变量尽量干净,目前为止的模块化方案都没有很好的做到这一点。

依赖注入 (2009)

就是大家熟知的 angular1.0,依赖注入的**现在已广泛运用在 react、vue 等流行框架中。但依赖注入和解决模块化问题还差得远。

CommonJS (2009)

真正解决模块化问题,从 node 端逐渐发力到前端,前端需要使用构建工具模拟。

Amd (2009)

都是同一时期的产物,这个方案主要解决前端动态加载依赖,相比 commonJs,体积更小,按需加载。

Umd (2011)

兼容了 CommonJS 与 Amd,通过下面的代码:

(function(define) {
    define(function () {
        return {
            helloWorld: function () {
                return 'hello'
            }
        };
    });
}(
    typeof module === 'object' && module.exports && typeof define !== 'function' ?
    function (factory) { module.exports = factory(); } :
    define
));

其核心**是,如果在 commonjs 环境(存在 module.exports,不存在 define),将函数执行结果交给 module.exports 实现 Commonjs,否则用 Amd 环境的 define,实现 Amd。

Labeled Modules (2012)

// file hello.js
exports: var helloWorld = {
    hello: function (lang) {
        return 'hello'
    }
};

// file hello.js
require: './lib/hello';
var phrase = helloWorld.hello()

和 Commonjs 很像了,没什么硬伤,但生不逢时,碰上 Commonjs 与 Amd,那只有被人遗忘的份了。

YModules (2013)

// file hello.js
modules.define('helloWorld', function(provide) {
    provide({
        hello: function () {
            return 'hello'
        }
    });
});

// file app.js
modules.require(['helloWorld'], function(helloWorld) {
    var result = helloWorld.hello()
});

既然都出了 Commonjs Amd,文章还列出了此方案,一定有其独到之处。

其核心**在于使用 provide 取代 return,可以控制模块结束时机,处理异步结果;拿到第二个参数 module,修改其他模块的定义(虽然很有拓展性,但用在项目里是个搅屎棍)。

ES2015 Modules (2015)

就是我们现在的模块化方案,还没有被浏览器实现:

// file hello.js
export default const helloWorld = () => {
  return 'hello'
}

// file app.js
import helloWorld from './hello'
var result = helloWorld()

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.