0%

引入的模块

var ReactElement = require('ReactElement');

var emptyFunction = require('fbjs/lib/emptyFunction');
var invariant = require('fbjs/lib/invariant');

我们来看一下 ReactElement 模块,其他两个都是工具函数,不用关心。

Export 的对象

var ReactChildren = {
forEach: forEachChildren,
map: mapChildren,
count: countChildren,
toArray: toArray,
};

module.exports = ReactChildren;

依次来看一下这个四个 API

forEach

function forEachChildren(children, forEachFunc, forEachContext) {
if (children == null) {
return children;
}
var traverseContext = getPooledTraverseContext(
null,
null,
forEachFunc,
forEachContext,
);
traverseAllChildren(children, forEachSingleChild, traverseContext);
releaseTraverseContext(traverseContext);
}

入参: children, forEachFunc, forEachContext.
首先通过 getPooledTraverseContext 拿到一个遍历的上下文对象 traverseContext,然后调用 traverseAllChildren 方法来遍历所有传入 children 的后代节点。
最后释放当前的 traverseContext.

阅读全文 »

引入的模块

var ReactNoopUpdateQueue = require('ReactNoopUpdateQueue');

var emptyObject = require('fbjs/lib/emptyObject');
var invariant = require('fbjs/lib/invariant');
var lowPriorityWarning = require('lowPriorityWarning');

其中, ReactNoopUpdateQueue 是默认的 updater ,用来提供 update, replaceState, setState 的入队操作,但可能是由于是默认 updater 的原因,只提供了 API 和对入参的校验,但没有提供实际的功能。比如:

阅读全文 »

本系列文章以 react 最新的版本: 16.0.0-beta.5 为准。
首先我们入口文件 ReactEntry.js 来看,

var ReactBaseClasses = require('ReactBaseClasses');
var ReactChildren = require('ReactChildren');
var ReactElement = require('ReactElement');
var ReactVersion = require('ReactVersion');

var onlyChild = require('onlyChild');

依赖模块:
• ReactBaseClasses
• ReactChildren
• ReactElement
• onlyChild
• ReactElementValidator
接着:

阅读全文 »

Redux 的源码非常的精炼,短短几百行代码,确提供了强大的功能。今天,我们就来一探究竟。

看源码最简单的方式,就是从入口文件来看,看它依赖哪些模块,然后在依次看这些模块的内容,最后也就对整个代码有个清晰的认识了。

所以我们就从入口文件开始来看:

import createStore from './createStore'
import combineReducers from './combineReducers'
import bindActionCreators from './bindActionCreators'
import applyMiddleware from './applyMiddleware'
import compose from './compose'
import warning from './utils/warning'

/*
* This is a dummy function to check if the function name has been altered by minification.
* If the function has been minified and NODE_ENV !== 'production', warn the user.
*/
function isCrushed() {}
// 就是根据 isCrushed 是否被压缩了,来警告开发者正在非生产环境使用一个压缩过的代码。
if (
process.env.NODE_ENV !== 'production' &&
typeof isCrushed.name === 'string' &&
isCrushed.name !== 'isCrushed'
) {
warning(
'You are currently using minified code outside of NODE_ENV === \'production\'. ' +
'This means that you are running a slower development build of Redux. ' +
'You can use looseenvify (https://github.com/zertosh/looseenvify) for browserify ' +
'or DefinePlugin for webpack (http://stackoverflow.com/questions/30030031) ' +
'to ensure you have the correct code for your production build.'
)
}

export {
createStore,
combineReducers,
bindActionCreators,
applyMiddleware,
compose
}

可以看到它依赖了下面这几个模块:

  • createStore
  • combineReducers
  • bindActionCreators
  • applyMiddleware
  • compose
  • warning

其他没什么说的,就是把一些 API 暴露出去。那我们就先按照这个模块依赖顺序,依次进行解读。

createStore

阅读全文 »

做了哪些事情

说是一年,其实也一年多了,不过这倒不重要。主要看看做了哪些事吧:

1. 改造发布流程

刚来公司的时候,白领贷的前端是基于 Riot 框架开发的系统。语言层面,使用 ES6 和 Less 开发,发布到线上是需要一个构建打包和编译的过程,不能直接部署到线上服务器。

所以项目的开发流程就是,功能开发,提交代码,本地打包,打包后的代码跟源代码一起提交测试,而后合并代码到 master 然后再在本地打包,然后上线。

这个流程非常的不合理,因为源代码和编译打包后的代码放到一块管理,本身就不合理。经常会出现,你一打包测试,我这边代码推上去就一堆冲突。所以我就想怎么来改进这个流程。

改进方案一

网易内部是有一个 omad 系统(自动部署平台)的,想着说看能不能借助这个平台干点事情。因为初来乍到,对这个部署平台不是很熟悉,就问了和这个平台接触最多的测试同学,测试同学告诉我说 omad 没有提供任何对外的接口,所以我想的可能没法实现。

这样就尴尬了,没法做线上打包发布,那么打包这个过程就必然得放在本地来做。所以我就搞了一套现在看来很蠢的方案。那就是,用两个仓库来分别管理源代码和打包后的代码。

那么,如果需要发布的话,就需要在源代码仓库先进行打包编译,然后把打包编译的结果复制到管理要发布的代码的仓库。

一张示意图:

很明显,上面这种方式也只是临时解决方案,需要两个仓库来管理一份代码。每次提交代码都需要额外执行一个 run build 命令。

改进方案二:

由于上面的方案太蠢了,所以有了改进方案二,也是我们现在一直在用的方案:那就是直接线上打包。具体如下:

阅读全文 »