引言

去年这个时候,大概的把git的官方英文文档看过一遍,但也只是理解了整个命令体系的原理。
对于具体的命令使用形式,却还是存在一些不全面的地方。

git修改fetch默认行为

1
2
git config --get remote.origin.fetch
git config remote.origin.fetch "+refs/heads/*:refs/remotes/origin/*"

gulp4研究

今天正好写了个自动化打包、编译、上传的gulp脚本,采用的是最新的gulp4。
借写完代码有点成就感的劲,稍微总结下gulp4和gulp3.X系列的使用区别

gulp4 vs gulp 3.X

gulp本身的定位就是stream building system,典型的pipe代码风格。

gulp4相比于gulp3.X系列在流式规范上更加的严格。

gulp4的api点

1
2
3
4
5
6
7
8
9
gulp.src   - Emit files matching one or more globs
gulp.dest - Write files to directories
gulp.symlink - Write files to symlinks
gulp.task - Define tasks
gulp.parallel - Run tasks in parallel
gulp.series - Run tasks in series
gulp.watch - Run tasks in series
gulp.tree - Get the tree of tasks
gulp.registry - Get or set the task registry

光看api名字,可以看到多了symlink,lastRun,parallel,series,tree,registry

这几个API一看,就知道用了nodeJS的child_process,eventEmitter来处理并发、订阅等

gulp4 vs gulp 3.X区别细节

  • gulp3.x系列.

gulp.task('name',[,taskArr],fn)fn回调函数处理链式调用

这里有个比较纠结的点,fn/taskArr等处理并发任务、序列化任务,在gulp3系列,必须包一层task,
才能保证按照你想设定的顺序来执行,最后即使把项目写完了,后期看代码也会非常痛苦。

  • gulp4系列

心得API点parallel,series允许你以树状结构安排并发、同步、异步任务,
它们的实现原理也很简单,就是通常意义上的高阶函数,把任务作为参数,在函数体内重新组织即可。

gulp4中gulp.src的严格要求,必须return promise,return stream,callback()等
才能通知下个流执行

gulp4中gulp.tree可以打印整个gulp4工作流中由内部算法生成的树状图,也比gulp3系列好很多。

总结

redux引入高阶函数API开始,这种API设计在各个主流库中的应用真是无处不在
gulp4尤甚

资料

gulp插件集合
gulp任务管理父类

前言

之前捣腾angular2和typescript发现一些用的少,但是蛮犀利的webpack插件

html-webpack-plugin

它可以将webpackConfig的数据,作为元数据渲染进html模板,借助这一点,可以做一些开发、生产环境的配置

definePlugin

在全局环境中配置,自定义变量。一般在写框架或者组件的时候用的比较多

providePlugin

提供动态require组件的便利性,也是神器

webpack配置容易踩坑点

resolve.alias记住要用path.resolve写成绝对路径啊,不然引用的时候加上一些莫名其妙的__dirname就纠结了。
entry对象中,不要存在循环嵌套,不然webpack编译的时候,分分钟死循环啊

process.cwd()

这个是个神器,用好了node的启动目录,就不必放心思在文件路径上了

引言

path模块在nodejs中属于核心模块,目前状态是stable。
path模块提供了文件、目录等的使用机制。

Windows vs POSIX

在Windows和posix[例如*nix等的可移植操作系统接口实现平台]中可以轻松使用同一套API来操作文件和目录。
由于windows和POSIX使用不同的系统文件分隔符[一个是\,一个是/]。
因此nodejs提供了path.win32[方法名称]和path.posix[方法名称]来处理不同开发环境对任何操作系统的路径兼容

方法名列举

  • basename[path[,ext]] ===> 返回路径中的最后一块【和*nix系统中的basename命令基本保持一致】
  • delimiter====> 返回不同操作系统中对于环境变量process.env.PATH的分隔符
  • dirname(path) ===> 返回目录名称【和*nix系统的dirname命令基本一致】
  • extname(path) ===> 返回参数的basename从末尾到最后一个.出现的值
  • format(pathObject) ===> 参数是一个对象,就是将路径拆解了而已
  • isAbsolute(path) ===> 返回一个boolean值,来表示是否参数为绝对路径形式
  • join([path[,…]]) ===> 用系统路径分隔符来连接所有的参数,然后normalize返回的结果
  • normalize(path) ===> 处理路径中存在的\/...等,和cd命令基本一致
  • parse(path) ===> 处理路径为format的形式
  • relative(from,to) ===> 返回从from到to需要resolve的相对路径
  • resolve([path[,…]]) ===> 处理路径命令【类似cd】
  • sep ==> 返回系统路径分隔符

1
2
3
4
5
6
7
8
9
10
11
12
13
function enqueueUpdate(component) {
ensureInjected();
// Various parts of our code (such as ReactCompositeComponent's
// _renderValidatedComponent) assume that calls to render aren't nested;
// verify that that's the case. (This is called by each top-level update
// function, like setProps, setState, forceUpdate, etc.; creation and
// destruction of top-level components is guarded in ReactMount.)
if (!batchingStrategy.isBatchingUpdates) {
batchingStrategy.batchedUpdates(enqueueUpdate, component);
return;
}
dirtyComponents.push(component);
}

源码的结论

  • react在执行top-level事件的时候,在整个冒泡及生命周期中会有个更新策略,等到所有的脏元素准备就绪的时候(在settimeout之前,在冒泡结束节点),统一执行setState。
  • react在执行非top-level事件的时候,会执行batchUpdate,进行局部的state的更新。完成dom树的patch

引言

前端开发主要分为前后端分离,以及服务端渲染两块。
对于前者直接Ajax交互数据即可,对于后者却存在一些开发配置上的麻烦。
正好借鉴爱屋吉屋的一些做法总结下

开发搭建

  • 配置本地host
  • 本地起nginx服务做静态资源的反向代理,指向本地的开发目录
  • 下载后端项目,配置access control allow origin,启动服务

关于nginx的优点

  • 负载均衡: 主流的cdn静态资源负载分发
  • 缓存配置: buffer住request和response,使得后端服务更加专注于服务逻辑,减少并发压力
  • 灵活配置: nginx 的location结合正则表达式可以灵活的实现本地调试各个开发环境。经过调试,正则依赖完整的路径,而非目录

引言

模板引擎是现在前端框架必须处理的一部分,无论是DOM层面还是V-dom层面,各有各的实现。
最近正想尝试下自己写套模板引擎,也在借鉴一些主流的库的写法。
这篇博客将会针对模板引擎持续更新研究结果。

dom层面的模板引擎

1.基本功能规划

1.支持数据填充
2.支持简单的JS表达式

2.功能实现规划

1.利用正则匹配特定的标示,比如<%%>等
2.对于简单的JS表达式,转化为函数形式
3.采用 new Function(‘identifier’,functionString)生成函数

代码地址:

  1. domString层面的模板引擎处理,点击如下链接
    github开源地址

夜深了,不能搞太晚,后续文档之后补上。mark下代码时间 [16.6.9 01:25]

引言

jsbride在hybrid中是应用非常广泛的,它的实现机理也很简单
===> 调用native提供的可以阅读到window对象的UI类,按照协议规范进行发出请求。
===> 在window对象利用sub/pub设计模式,代理随机callbackId对象来承载回调函数,
===> 发出请求【具体的有iframe方法】(ios中用的多),或者通用事件【window.prompt劫持】来实现通信。
===> 当然各家有各家的方式。

1、安卓java中的实现

native调用js: WebView.loadUrl(“JavaScript:function()”)
js调用native: WebView有一个方法,叫setWebChromeClient。它的
onJsAlert,onJsConfirm,onJsPrompt方法将会在js调用window对象的对应的方法alert、confirm、prompt时候被触发。

看码分析

1、h5代码

1
2
3
4
5
<button onclick="JSBridge._call('bridge','showToast',
{'msg':'Hello JSBridge'},
function(res){alert(JSON.stringify(res))})">
测试showToast
</button>

2、js代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
 var Util = {
getUri:function(obj, method, params, port){
params = this.getParam(params);
var uri = 'JSBridge' + '://' + obj + ':' + port + '/' + method + '?' + params;
return uri;
},
getParam:function(obj){
if (obj && typeof obj === 'object') {
return JSON.stringify(obj);
} else {
return obj || '';
}
}
};
var JSBridge={};
JSBridge.callbacks={};
JSBridge._call=function (obj, method, params, callback) {
var port = Math.random();
this.callbacks[port] = callback;
var uri=Util.getUri(obj,method,params,port);
window.prompt(uri, "");
};

至此,前端层面层面代码结束,下面开始native层面的代码。

3、native部分将js传来的uri获取到[编写一个WebChromeClient子类]
1
2
3
4
5
6
7
public class JSBridgeWebChromeClient extends WebChromeClient {
@Override
public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, JsPromptResult result) {
result.confirm(JSBridge.callJava(view, message));
return true;
}
}
4、native部分将该对象设置给WebView
1
2
3
4
5
WebView mWebView = (WebView) findViewById(R.id.webview);
WebSettings settings = mWebView.getSettings();
settings.setJavaScriptEnabled(true);
mWebView.setWebChromeClient(new JSBridgeWebChromeClient());
mWebView.loadUrl("file:///android_asset/index.html");
5、native部分创建事件映射池
1
2
3
public class JSBridge {/*创建映射池,具体实现不写出来了*/}
JSBridge.register("jsName",javaClass.class); //注册方法
JSBridge.trigger(view,message);//执行方法
6、webview和前端参数整合起来,传入要唤醒的native组件

IOS部分其实也差不多

1、native调用js: stringByEvaluatingJavaScriptFromString
2、js调用native代码: 在UIWebView内发起的所有网络请求,通过delegate函数在Native层得到通知。

结尾

JSbridge是个hybrid应用开发中非常常见的话题,其实也没有什么神秘的。
一个好的JSbridge是需要很好的设计模式的,yeap!

引言

关于性能问题一直是现代前端工程必须讨论的话题,这是一篇小总结和资源收集的博客.

淘宝、百度、大众点评的方案对比

  • 百度: 采用前端架构工具fis,采用hash算法进行文件级别的版本控制,典型的资源URL:http://xxx.a_1232.js
  • 淘宝: [虽然我没去过阿里],采用开发版本号进行代码管理,典型的资源URL:http://g.alicdn.com/tb-page/taobao-home/0.0.62/index.css
  • 大众点评: 和淘宝方案类似,采用架构工具cortex进行开发版本层面的代码控制,依赖于cortex.json进行代码发布.url形式和淘宝类似。

cache-control

当然,对比下来,百度的方案是最优的,技术含量上面也可以说最高。
主流的大公司都会设置cache-control很长的时间,尽量优化网络请求。
淘宝采用了dns-prefetch进行TCP优化[对流量大的电商网站来说,这确实能节约不少时间]

总结

  • 配置超长时间的本地缓存 —— 节省带宽,提高性能
  • 采用内容摘要作为缓存更新依据 —— 精确的缓存控制
  • 静态资源CDN部署 —— 优化网络请求
  • 更资源发布路径实现非覆盖式发布 —— 平滑升级

参考资料

百度前端工具架构师
百度fis官方网站