场景是这样的,有一个自定义的tag,用到了_ctx.__require,代码片段如下:
var s = (ignore ? ' try {\n' : '') +
'var _compiler = _ctx.__require("' + normalize + '");' +
'_output += _compiler(' +
((onlyCtx && w) ? w : (!w ? '_ctx' : '_utils.extend({}, _ctx, ' + w + ')')) +
');\n' +
(ignore ? '} catch (e) {}\n' : '');
然后之前使用过设置模板内变量的方法:
swig.setDefaults({
locals: {
'xxx': '11'
}
});
一直相安无事,最近改了逻辑,去掉了setDefaults locals,结果一刷新页面(该页面使用了上述自定义tag),页面就报错:
TypeError: _ctx.__require is not a function
并且只是重启node服务后首次刷新页面才会出现,再次刷新就不会出现这个错误。。。搞得莫名其妙的,再次把locals set一下,就不会出现这种报错。 更奇特的是,locals不能是一个空对象{}, 必须至少有一对key:value。
暂时还不明确具体原因。
继续阅读~
参与评论~
nodejs中的错误处理还是比较麻烦的,尤其遇到异步回调之类,多层嵌套,简单的try…catch无法处理。
目前在用expressjs,拿此举例说说怎样实践。
第一种,从一介布衣那儿看到的方法,可行:
const domain = require('domain');
app.use((req, res, next) => {
const reqDomain = domain.create();
// next抛出的异常在这里被捕获,触发此事件
reqDomain.on('error', e => {
// ... 这里统一处理错误,比如渲染或跳转到404,500页面
});
return reqDomain.run(next);
});
通过在route定义之前添加如上的中间件,可以捕捉到大部分的错误。
第二种,上面说到是大部分的错误,因为我碰到了一个没成功捕捉到的,就是使用swig模板渲染时的变量报错。
// 设置模板引擎
app.engine('swig', swig.renderFile);
app.set('view engine', 'swig');
app.set('views', `${__dirname}/views`);
app.set('viewExt', '.swig');
// 在某处渲染输出:
res.render('template/filepath');
// 如果在filepath.swig文件中有变量报错,则第一种方法不能成功捕捉
这时在stackoverflow找到一个方法,
// 依然按第一种方法写错误捕捉
// 然后在route之后再写个中间件
// 最后的错误处理,比如发生在res.render中的错误
// 由于已经设置了响应,因此只能发送状态码,或跳转
// next不能去除,否则无法获取到错误
app.use((err, req, res, next) => {
// res.sendStatus(500);
log.error(err);
// res.redirect(301, '/'); // 跳转到首页
next();
});
ok,经过验证,上述方法已经能够处理目前所有遇到的问题。
第三种,为什么会有这一种方法呢,纯属个人思维发散,由于是express内部处理了模板引擎,导致res.render方法不能正常抛出错误被外围捕捉,那么我直接用swig方法渲染文件,并把渲染后的结果通过res.send方法响应是不是可以呢?
// 之前是这样渲染的
res.render('template/filepath');
// 改为
res.send(swig.renderFile('/...这里应该是物理绝对路径.../template/filepath.swig'));
经过上面改造,发现只用第一种方法也可以正常捕捉到错误,说明推论正确。
之所以在第二种还能解决的情况下还在寻找其他方案,是因为第二种的最终错误处理只能响应状态码,而不能再渲染页面了。终究不够完美,方法不够优雅。
像第三种方式,完全可以不必设置express的模板引擎了,用res.send + 模板自身的渲染方法即可,封装为一个方法,方便调用。
继续阅读~
参与评论~
需支持es5,兼容可以使用es5-shim
/**
* 封装模板使用方法
* @param {string} tplName 模板名
* @param {[type]} data 传入模板的数据
* @param {[type]} method dom操作方法,默认使用html()方法
* @return {[type]} 容器jQuery对象
*/
$.fn.tpl = function (tplName, data, method) {
data = data || {};
method = method || 'html';
return this[method](template(tplName, data));
};
['append', 'prepend', 'after', 'before'].map(function (method) {
(function (method) {
$.fn[method + 'Tpl'] = function (tplName, data) {
return this.tpl(tplName, data, method);
}
})(method);
});
继续阅读~
参与评论~
互联网环境安全性还是比较差的,尤其是官方运营商都不要脸的进行了内容劫持往页面插入广告之类的,更是无语。主要防范方法是CSP + HTTPS。HTTPS都了解,CSP,中文名为 内容安全策略,可以参见https://developer.mozilla.org/zh-CN/docs/Web/Security/CSP
继续阅读~
参与评论~
写了一个mixin方法:
var React = require('react');
module.exports = {
// 将属性传递给子级
// Element: 子级类型, propsMap: 属性对象
propsToChildren: function (Element, propsMap) {
return React.Children.map(this.props.children,function(child) {
if (child.type === Element) {
return React.cloneElement(child, propsMap)
} else {
return child;
}
}, this);
}
}
继续阅读~
参与评论~
一、概念上的用法:
1、同分支拉取使用:
git pull --rebase
2、不同分支衍合:
## local machine
(develop)$: git pull origin develop --rebase
## 切换到 feature 分支,衍合develop分支,如有冲突,解决冲突后continue,再次 commit
(develop)$: git checkout feature/user-extension
(feature/user-extension)$: git rebase develop
(feature/user-extension)$: ## ... 解决冲突
(feature/user-extension)$: git rebase --continue
(feature/user-extension)$: git commit origin feature/user-extension
二、本人实际用法:
同分支进行rebase,不同分支间进行merge。
其中同分支有两种情况:
1、本地分支无任何最新提交,远程有新提交。
执行 git pull 直接拉取即可。
2、本地分支有新提交,远程也有新提交。
执行 git pull –rebase 衍合远程分支。
参考:
http://blog.csdn.net/jackystudio/article/details/12309627
http://git-scm.com/book/zh/v1/Git-分支-分支的衍合
http://blog.isming.me/2014/09/26/git-rebase-merge/
http://blog.yorkxin.org/posts/2011/07/29/git-rebase/
http://hy2014.github.io/2014/07/25/git-rebase/
http://segmentfault.com/q/1010000000181403
继续阅读~
参与评论~
目的是防止新手乱操作,老手误操作。
在每个git项目根目录下有个隐藏文件夹.git, 该文件夹下有个hooks目录,复制hooks目录下的pre-push.smaple并更名为pre-push文件,即 项目根目录/.git/hooks/pre-push 文件,编辑粘贴以下代码:
#!/bin/sh
git diff-tree --no-commit-id --name-only HEAD -z -- |
xargs -0 sh -c '
for f; do
if git show :"$f" | grep "< <<<<<< HEAD"; then
echo "$f has some conflicts,can not push"
exit 1;
fi
if git show :"$f" |grep ">>>>>>>"; then
echo "$f has some conflicts,can not push"
exit 1;
fi
done
exit 0;
' -
然后保存即可。
来源于:http://blog.sina.com.cn/s/blog_61d8d9640102vaht.html
继续阅读~
参与评论~
修改了项目中的文件并且还未提交,如果想回退放弃当前的修改,可以用以下命令:
git checkout -- <filename>
如果想放弃当前所有的修改,使用:
git checkout -f
或者:
git reset --hard
参考: http://gitready.com/beginner/2009/01/11/reverting-files.html
继续阅读~
参与评论~
js的浮点数类型值在参与四则运算时,有时候会产生不正确数据,这是编程语言的通病,因为计算机是二进制的。
比如一个简单的加法:268.34 + 0.83,js得出的结果是269.16999999999996。类似的加减乘除有很多。
因此需要一个精确计算的方法,来保证精确度。Github上有几个Math库,一般项目使用未免太大。这里贴出一个从http://www.cnblogs.com/junjieok/p/3306155.html而来的轻量方法,已足够使用。
代码如下:
继续阅读~
参与评论~
IE9中,input输入框绑定的oninput事件,无法监听到键盘的backspace delete和右键菜单的剪切、撤销、删除对内容的改变。
虽然onkeyup可以解决键盘问题,但对右键还是无法解决。所以,有种解决方法如下:
<input id="myInput" type="text">
<script>
// Get the input and remember its last value:
var myInput = document.getElementById("myInput"),
lastValue = myInput.value;
// An oninput function to call:
var onInput = function() {
if (lastValue !== myInput.value) { // selectionchange fires more often than needed
lastValue = myInput.value;
console.log("New value: " + lastValue);
}
};
// Called by focus/blur events:
var onFocusChange = function(event) {
if (event.type === "focus") {
document.addEventListener("selectionchange", onInput, false);
} else {
document.removeEventListener("selectionchange", onInput, false);
}
};
// Add events to listen for input in IE9:
myInput.addEventListener("input", onInput, false);
myInput.addEventListener("focus", onFocusChange, false);
myInput.addEventListener("blur", onFocusChange, false);
</script>
参考:http://www.matts411.com/post/internet-explorer-9-oninput/
继续阅读~
参与评论~