- 📫 Blog:https://github.com/paper/blog
- 🔭 当前主要在更新的是:
- 🐢 delay
paper / blog Goto Github PK
View Code? Open in Web Editor NEWwrite something
write something
项目是在 git 上是单项目,src 里面的每个目录是单个小项目,可单独构建。
比如项目名称叫:project
,里面有个目录 src
,然后里面是多个独立项目 activity
,share
,login
等等50多项目(每个项目可单独构建调试与部署)。
由于项目不是一个 npm run build
命令就可以全部构建,那么提交到远程分支 release/dev
时,触发 JK
想自动部署内网环境,就不知道运行哪个项目
有个思路是:在提交时的 commit 命令加上一些关键字,进行钩子解析。
或者使用一个 sh 文件,每次提交时,你可以修改这个文件并运行这个 sh 文件,sh 里面写 npm 命令(比如写 npm run share-build
等一个或多个)。这个想法可以,但有个问题,多人的话,每个人的事情不同,那么每次可能都会冲突或覆盖,有沟通成本。如果合并的话又会重复构建,浪费了部署时间。
所以我们根据这个思路,想了个法子
jk-build
目录建个 jk-build
目录,里面放上每个同学 git 上提交的的名字,比如 zhangsan.sh
, lisi.sh
等等。
environment {
PROJECT_NAME = sh(script: 'basename -s .git `git config --get remote.origin.url`', returnStdout: true).trim()
PATH = "/root/.nvm/versions/node/v12.13.1/bin/:$PATH"
GIT_NAME = sh(script: "git --no-pager show -s --format='%an' $GIT_COMMIT", returnStdout: true).trim()
GIT_EMAIL= sh(script: "git --no-pager show -s --format='%ae' $GIT_COMMIT", returnStdout: true).trim()
GIT_FILES= sh(script: "git diff --name-only HEAD~ HEAD", returnStdout: true).trim()
GIT_AUTHOR_LIST_ONE_MINUTE= sh(script: "git log --since=1.minute.ago --merges | grep '^Author: ' | sort | uniq -c | awk '{print \$3}'", returnStdout: true).trim()
GIT_LATEST_LOGS_LIST= sh(script: "git log --pretty=format:'%h - %an, %ar : %s @#@' --since=15.minute.ago", returnStdout: true).trim()
}
这样在 JK
运行的 sh 里面可以获取对于的变量值 ${GIT_NAME}
等值
有个细节大家可以注意到:GIT_AUTHOR_LIST_ONE_MINUTE
是取最近1分钟提交提交的作者的名字,这是因为出现过比较边界的情况,就是当2个同学几乎同时提交后,JK
只会运行最后一次提交,那么前一个同学的构建就没有触发,所以我们把提交记录1分钟内的同学都进行构建。(你也可以改为2分钟)
dingDingLog
,dingDingLogText
,dingDingError
都是另外一个 sh 提供的钉钉通知的功能
# =================================================================
# 下面的代码不要动!!!!下面的代码不要动!!!!下面的代码不要动!!!!
# =================================================================
CURRENTDIR=`pwd`
source ${CURRENTDIR}/deploy_ecs/t.sh
echo "【日志】正在部署 张三 的脚本......"
dingDingLog 正在部署张三的脚本
# ==================== 从这个下面开始修改 ==============================
# 这里写各自的 npmCheckRun 命令
# Example: npmCheckRun master-invitation-build
# 可构建1个或多个任务
npmCheckRun master-invitation-build
npmCheckRun master-invitation-v2-build
npmCheckRun master-invitation-v3-build
npmCheckRun
是一个 npm run
的校验版本
npmCheckRun() {
name=$1
npm run ${name}
dingDingLogText "正在编译的项目是-->${name}"
if [ $? -ne 0 ]
then
dingDingError "npm-build-failed-->${name}"
exit 1
fi
}
CURRENTDIR=`pwd`
branch=${GIT_BRANCH} # 分支名称
gitName=${GIT_NAME} # 提交人的全拼
gitNameShPath=${CURRENTDIR}/jk-build/${gitName}.sh
# https://www.cnblogs.com/emanlee/p/3583769.html
# 如果文件存在
if [[ -f "${gitNameShPath}" ]]
then
# 先触发第一个提交的人的sh
source ${gitNameShPath}
else
echo "[日志] GIT_NAME=${gitName}.sh 不存在"
dingDingError "${gitName}.sh不存在"
fi
# 再判断 GIT_AUTHOR_LIST_ONE_MINUTE 的提交人列表
for user in ${GIT_AUTHOR_LIST_ONE_MINUTE}
do
userShPath=${CURRENTDIR}/jk-build/${user}.sh
echo "[日志] userShPath=${userShPath}"
# 如果文件存在
if [[ -f "${userShPath}" ]]
then
# 因为前面已经执行了 GIT_NAME 的脚本,所有如果 user 相同就不再执行
if [ "${user}" != "${GIT_NAME}" ]
then
echo "[日志] 正在执行--${user}.sh"
source ${userShPath}
fi
else
echo "[日志] ${user}.sh 不存在"
dingDingError "${user}.sh不存在"
fi
done
接下来的事情,就是和大家一样,同步代码等等
当前用户提交到 release/dev
时,要解决一下自己 sh 的可能会出现小冲突问题,
不过这个也很好解
当多人并发构建时,jk
机器为了并发构建,会根据你设置的并发构建数量(通常是机器的内核数),生成多个目录
CURRENTDIR=`pwd`
branch=${GIT_BRANCH} # 分支名称
if [[ "${branch}" = "release/dev-ecs" ]]
then
# 只在测试环境做实验,因为测试环境提交的人多,并发的可能性很高
# 先清空 workspace/fe_nodeproject_release_dev-ecs/dist 或 workspace/fe_nodeproject_release_dev-ecs@2/dist 目录
# 这样做的目的是,当发生并发构建时,谁完成的顺序是未知的,如果 @2 先完成,把最新的代码copy到 f2e_very_important_dev_dist,再把 f2e_very_important_dev_dist拷贝回来。
# 再最初的完成后,又会把 @2的旧项目copy到f2e_very_important_dev_dist,导致代码未更新。
# 所以尝试,每次构建之前,先清空 dist 目录,构建完成后,只有当前人构建的项目,避免旧项目也一同copy
rm -rf ${CURRENTDIR}/dist/*
fi
# ======================================================================
# 说明为什么这么做:因为如果 jk 并发构建时,会触发生成 @2,@3 这一类的目录,而这些目录里面的 dist 是空的或者是不全的。所以需要从外面的备份的完整的 dist 拷贝进来
# 方案:
# 1)先当项目里面一个或多个 npmCheckRun 构建都成功后,把项目的 dist 目录 copy 到对应分支的公共 dist 目录。(即更新公共目录的dist文件)
# 2)然后,把最新的公共 dist 目录里面的文件,拷贝回当前构建项目的 dist 目录。
# 3)这样,就保证了在打 docker 镜像时,dist 会是一个最新并且完整的。
# 4)很明显,这是一个增量的方式,所以外面 dist 目录的文件会越来越多,当大到一定程度时,我会写一个脚本,来移除文件时间老旧的文件,保留最新文件。
# 外面的目标目录名称
distName=""
if [[ "${branch}" = "release/dev-ecs" ]]
then
distName="f2e_very_important_dev_dist"
fi
if [[ "${distName}" != "" ]]
then
# 把整个 dist 目录放到 distName 目录里面
cp -fpr ${CURRENTDIR}/dist /data/jenkins/${distName}/
# 把 distName 里面的 dist 所有文件,复制到 CURRENTDIR/dist 里面
cp -fpr /data/jenkins/${distName}/dist/* ${CURRENTDIR}/dist/
fi
目前这套方案运行还是蛮顺利的,职责也非常清晰明了。
如果是发线上,那么就根据 master
分支,运行专属的 jk-build/master.sh
即可。
线上是全量部署,因为是打一个 Docker
镜像的方式部署的,所以要把所有代码全部打包进去。但 Docker
本身是有缓存的,利用缓存,推送镜像的速度也不会太慢。
cmd /k cd "$(CURRENT_DIRECTORY)" & javac "$(FILE_NAME)" & java "$(NAME_PART)"
http://www.isaced.com/post-247.html
#!/bin/sh
filename="logo.png"
dirname="cutimg"
name_array=("Icon-29.png" "Icon-40.png" "Icon-58.png" "Icon-76.png" "Icon-80.png" "Icon-87.png" "Icon-120.png" "Icon-152.png" "Icon-180.png")
size_array=("29" "40" "58" "76" "80" "87" "120" "152" "180")
mkdir $dirname
for ((i=0;i<${#name_array[@]};++i)); do
m_dir=$dirname/${name_array[i]}
cp $filename $m_dir
sips -Z ${size_array[i]} $m_dir
done
Markdown 利器 Haroopad 下载:
下载地址:http://pan.baidu.com/s/1eQj97CA
提取密码:flu4
👻
http://pad.haroopress.com/user.html
more:
http://mouapp.com
https://stackedit.io
https://www.zybuluo.com
Math.trunc() 方法会将数字的小数部分去掉,只留整数部分。
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Math/trunc
Math.trunc = Math.trunc || function(value) {
return value < 0 ? Math.ceil(value) : Math.floor(value);
}
// 【注意】这个比 parseInt 靠谱
parseInt(-2.22233413431e-15, 10) // -2 error
Math.trunc(-2.22233413431e-15) // -0 right
今天同事群里发了个这个: http://weibo.com/3229125510/C44Cl8kwC
挺有意思,就 “收藏” 了一下。
我 “犹豫” 了一小会,虽然我知道微博想表达的含义,但还是“犹豫”了一会~~
后来经过在部门群内部讨论一下,改成下面这样是不是会更好?
看来我眼皮跳,果然是有先兆的!~
职业病好难受啊!摔!(╯‵□′)╯︵┴─┴
以前写的一个游戏,用 node-webkit 封装了一下
下载地址:http://pan.baidu.com/s/1qWAZHwg
提取密码:4xf5
我觉得我喜欢上 nodeWebkit 了 😄
more:
https://github.com/rogerwang/node-webkit
http://paperagain.diandian.com/post/2012-01-03/14289152
http://stackoverflow.com/questions/8911247/hide-iphone-html5-video-play-button
A look at the shadow DOM in Safari iOS tells me that what you want (hidding only the big central play button) is:
video::-webkit-media-controls-start-playback-button {
display: none !important;
-webkit-appearance: none;
}
The answer from Ian hides everything including text tracks (closed captions ...)
stackoverflow真是好地方!
有个需求,需要在手机端做个“彩蛋”:
在手机端,利用某种特殊手势操作,把代码里面所有的console过的东西,都打出来,放到页面上。
var debug = (function(){
var consoleData = [];
var oldConsole = console;
return {
init: function(){
window.console = {};
// 重写
for(var i in oldConsole) {
if ( typeof oldConsole[i] == 'function' ) {
window.console[i] = (function(cfn){
return function(){
var data = Array.prototype.slice.call(arguments);
consoleData.push(data);
cfn.apply(oldConsole, arguments);
}
})(oldConsole[i]);
} else {
console[i] = oldConsole[i];
}
}
},
getConsoleData: function(){
return consoleData;
}
}
})();
debug.init();
这样当代码里面使用 console
时,就会把数据记录下来。怎么使用,就简单多了~
这有个问题就是:正常的console的数据的定位会发生错误。。。
有没有这种情况:
肿么办~ 妥协之后,还是码字吧...Orz
目前的微信版本(5.2)是支持语音转文字的,
长按对方发的声音就会出现这个选项。
只要普通话不是很差,还是蛮不错的。
不过,还是有:
这个很难避免。
但我们可以利用这个:
解释一下第一条,为什么这个“图标”要这么隐蔽?
我个人是挺需要这个功能的 ... 希望以后版本会有
就酱
http://paperagain.diandian.com
现在移步到 github 了,diandian 不再更新文章。
font-family: Calibri;
2021年
这里记录下带实习生的路线
红宝书作为前面个看不懂时,可以去当做深入理解去查询的“字典”。
因为这本书有点厚,内容多而丰富,容易劝退和不容易记忆。所以放在最后,权先当做“字典”。
以后要看的进阶书:
再后续:
因为不是https,项目被联通运营商(移动网络)劫持。
听朋友建议使用CSP(Content-Security-Policy)
相关文章:
http://caniuse.com/#feat=contentsecuritypolicy
http://www.html5rocks.com/en/tutorials/security/content-security-policy/
目前是通过添加白名单的方式解决联通的js注入问题。
<!--脚本加载白名单 【临时解决方案,后续还是要使用https来解决这个问题】-->
<meta http-equiv="Content-Security-Policy" content="script-src 'unsafe-inline' 'unsafe-eval' *.sjzhushou.com *.xunlei.com">
后续还是最好使用https协议。
目前在公司正在推广项目的readme模板,代码之所以很难维护,或者说变成“屎山”,很大原因是项目交接时,没有把事情说清楚。而项目的 readme.md 本就应该承担起一大部分这个任务。(结合内部 wiki 可补充说明)
我曾经和同事说过:就好比你失忆了,然后第2天来公司开发这个项目,你觉得昨天的你需要告诉你哪些信息 ??
下面一些模板“填空题”,如果详细和完整的话,即使一个新招聘同学让他上手的话,会给他非常好的第一印象。
https://gitlab.company.cn/xxxx
云盘是.....
如果可以的话,放到项目脚手架上也是最好的。
2016年年底时,Android 和 iOS 短视频使用的是r.js 进行打包合并的。故在这里做一下简要说明。
短视频Android和iOS的地址分别是:
\web_common_h5\src\page\video
和 \web_ios_h5\src\page\video
页面需要引入的必须代码:
//m.sjzhushou.com/h5/thirdlib/zepto/1.1.6/zepto.all.min.js
//m.sjzhushou.com/h5/thirdlib/vue/1.0.10/vue.min.js
(因为短视频使用了vue)//m.sjzhushou.com/h5/thirdlib/requirejs/2.1.20/require.min.js
再引入:index.js
这里主要说明一下index.js
index.js
不仅是 requirejs 配置和执行的脚本,又是r.js的配置文件。这样做的好处就是,只需要维护一份代码,就可以同时使用开发模式和线上模式
// 这是 iOS短视频 的index.js
(function(){
// 调试开关
var debug = false;
// 版本时间戳,如果是调试模式,那么就是无缓存模式
// 每次上线时,压缩合并后的代码都具有自定义时间戳(而不使用md5)。这样方便回归代码,出问题方便回退。
var t = debug ? (+new Date) + '' : '20160203_1727';
var urlArgs = 't=' + t;
var shortVideo_requirejs_config = {
baseUrl: '../../',
paths: {
'text': 'lib/textjs/text.min',
// 引用线上的代码,是无法合并打包的
'md5':'http://m.sjzhushou.com/h5/lib/md5',
'client':'http://m.sjzhushou.com/h5/lib/client',
'ready':'http://m.sjzhushou.com/h5/lib/ready',
'util':'http://m.sjzhushou.com/h5/lib/util',
'video_source' : 'http://m.sjzhushou.com/h5/page/common/video_source',
'video': 'component/video/video',
'share': 'component/share/share',
'recommend': 'component/recommend/recommend',
'comment': 'component/comment/comment',
'main': 'page/video/main',
'main-build': 'page/video/dist/main-build-min-' + t
}
};
// 这个是页面使用的代码,不是为了r.js构建的。
// 故延迟1ms,是为了防止使用r.js 构建时报错
setTimeout(function(){
try{
require.config({
baseUrl : shortVideo_requirejs_config.baseUrl,
paths : shortVideo_requirejs_config.paths,
urlArgs : urlArgs
});
if (debug) {
// 测试环境
require(['main']);
} else {
// 正式环境,打包后的
require(['main-build']);
}
}catch (e) {}
}, 1);
// for rjs build
// 这样只要写一份shortVideo_requirejs_config配置文件,就可以完成开发和上线时同步,不必担心遗漏
return {
baseUrl : shortVideo_requirejs_config.baseUrl,
paths : shortVideo_requirejs_config.paths,
name : shortVideo_requirejs_config.paths.main,
out : 'dist/main-build-min-'+ t +'.js'
// 如果不压缩,就取消这个注释(一般都合并压缩)
//optimize: "none",
};
})();
配置 gulpfile.js
// 这是 iOS短视频 的gulp任务
var gulp = require('gulp');
var exec = require('child_process').exec;
var rjsPath = 'node_modules/requirejs/bin/r.js';
// 短视频rjs构建
gulp.task('shortVideoBuild', function(cb) {
var buildPath = 'src/page/video/index.js'
exec('node ' + rjsPath + ' -o ' + buildPath, function(err){
if (err) return cb(err); // 返回 error
cb(); // 完成 task
});
});
上线之前,运行一次 gulp shortVideoBuild
,然后上传对应的代码即可。
建议:除了上传压缩版本的main-build,还要上传其他用来被合并的单独的文件哦。(这里吐槽一下rz -y 的上传方式)
【注意点】
1,index.js
: t = 上线时的时间点
2,index.js
: debug = false
3,页面引入的 index.js
也要加时间戳哦,为了清缓存
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.