LinkedIn Reddit icon

简单其实不简单

Actually, simplicity is not simple.

RegExp正则操作

String to RegExp 转义 // 将字符串安全格式化为正则表达式的源码 // https://github.com/slevithan/xregexp /** * Escapes any regular expression metacharacters, for use when matching literal strings. The result can safely be used at any point within a regex that uses any flags. * * @memberOf XRegExp * @param {String} str String to escape. * @returns {String} String with regex metacharacters escaped. * * @example * XRegExp.escape('Escaped? <.>'); * // -> 'Escaped\?\ <\.>' */ var escape = function(str) { return String(str).

Random随机

Math.random指定随机范围 function random(start, end){ return Math.floor(Math.random() * (end - start + 1) + start); }  随机生成CSS颜色值 function getColor(){ return '#' + ('00000' + (Math.random()*0x1000000<<0).toString(16)).slice(-6) } // 颜色翻转取反 function colorReverse(oldColor){ var oldColor = '0x' + oldColor.replace(/#/g, ''); var str = '000000' + (0xFFFFFF - oldColor).toString(16); return str.slice(-6); } 千万级别不重复随机数生成 Mrg32k3a方式 // From http://baagoe.com/en/RandomMusings/javascript/ function MRG32k3a() { return (function(args) { // Copyright (c) 1998, 2002 Pierre L'Ecuyer, DIRO, Université de Montréal. // http://www.

promise

新建Promise实例 function deferPromise() { const deferred = {}; const promise = new Promise(function(resolve, reject) { deferred.resolve = resolve; deferred.reject = reject; }); deferred.promise = promise; return deferred; } // 使用时 function getLocalXXX() { const defer = deferPromise() sync((err, data) => { if(err) { defer.reject(err); } else { defer.resolve(data); } }); return defer.promise; }

Openwork加DnsPod DDNS

Openwork 加 DnsPod DDNS 首先登陆到你的路由器,安装 wget,因为 OpenWrt 默认自带的基于 busybox 的 wget 无法处理 HTTPS 请求,而 DnsPod 的 API 处于安全考虑,强制使用 HTTPS 连接。下面的例子中 192.168.1.1 是路由器的 IP 地址,请根据实际情况调整。 $ ssh root@192.168.1.1 opkg update opkg install wget 接着来获得我已经写好的 DDNS 脚本,你可以在 GitHub Gist 上找到最新的版本:https://gist.github.com/TommyLau/21089ac976ef5fdfc39c 把新下载回来的文件设置为可执行 chmod +x ddns.sh # 修改 crontab crontab -e 增加如下的内容 */5 * * * * /root/ddns.sh token test.com www >> /home/pi/ddns/ddns.log 2>&1 2>&1 | tee ${cur_dir}/install_bbr.log 上述的命令表示每 5 分钟检查一次域名更新,如果发现 IP 有变化的话,就自动更新相应的域名(www.test.com)。 token DnsPod 中创建的值,需要这里的值是 DnsPod 中 id,token 的组合 test.

Number操作

JS Number操作 数字三位分隔 '11222333444555'.match(/\d+?(?=(\d{3})*$)/g); // ["11", " 222", "333 ", "444", "555"] '12345.123'.replace(/(\d)(?=(\d{3})+($|\.))/g, '$1,'); // "12,345.123" // 12345.123 => 12,345.123 export function numberSplit(num: string | number, separator: string = ',') { return String(num).replace(/(\d)(?=(\d{3})+($|\.))/g, '$1' + separator); } 超int型的最大值相加 function add(a, b){ var SPLITE_LENGTH = 3; var aL = String(a), bL = String(b); var resout = '', c = 0; while(aL !== '0' || bL !== '0'){ var aR = aL.slice(-SPLITE_LENGTH), bR = bL.

npm作为构建工具

上个月,我在这篇文章《为什么要停止使用 Grunt 和 Gulp》中建议大家使用 npm 作为替代方案,npm 的 scripts 配置可以实现这些构建工具的所有功能,而且更简洁、更优雅和较少的模块依赖和维护开销。本文第一稿大概有 6000 字,深入讲解了如何将 npm 作为替代方案,但那篇文章主要在表达我的观点,而不是作为一篇教程。然而,读者的反馈却很强烈,许多读者告诉我 npm 并不能完全实现这些构建工具提供的特性,甚至有的读者直接给我一个 Gruntfile,然后反问我:“怎么用 npm 来实现这样的构建方案”?所以我决定进一步更新本文,将其作为一个新手入门教程,主要分享如何使用 npm 来完成一些常见的构建任务。 npm 是一个很好的工具,提供了一些奇特的功能,也是 NodeJS 的核心,包括我在内的很多人每天都在使用 npm,事实上在我的 Bash 历史记录中,npm 的使用频率仅次于 git。npm 更新也很快,旨在使 npm 成为一个强大的模块管理工具。而且,npm 有一个功能子集,可以通过运行一些任务来维护模块的生命周期,换句话说,它也是一个强大的构建工具。 scripts 配置 首先,我们需要搞清楚如何使用 npm 来管理构建脚本。作为核心命令之一的 npm run-script命令(简称 npm run )可以从 package.json 中解析出 scripts 对象,然后将该对象的键作为 npm run 的第一个参数,它会在操作系统的默认终端中执行该键对应的命令,请看下面的 package.json 文件: { "name": "myproject", "devDependencies": { "jshint": "latest", "browserify": "latest", "mocha": "latest" }, "scripts": { "lint": "jshint **.js", "test": "mocha test/" } } 如果运行 npm run lint,npm 将在终端中执行 jshint **.

npm scripts 使用指南

npm scripts 使用指南 Node 开发离不开 npm,而脚本功能是 npm 最强大、最常用的功能之一。本文介绍如何使用 npm 脚本(npm scripts)。 一、什么是 npm 脚本? npm 允许在package.json文件里面,使用scripts字段定义脚本命令。 { // ... "scripts": { "build": "node build.js" } } 上面代码是package.json文件的一个片段,里面的scripts字段是一个对象。它的每一个属性,对应一段脚本。比如,build命令对应的脚本是node build.js。 命令行下使用npm run命令,就可以执行这段脚本。 $ npm run build # 等同于执行 $ node build.js 这些定义在package.json里面的脚本,就称为 npm 脚本。它的优点很多。 项目的相关脚本,可以集中在一个地方。 不同项目的脚本命令,只要功能相同,就可以有同样的对外接口。用户不需要知道怎么测试你的项目,只要运行npm run test即可。 可以利用 npm 提供的很多辅助功能。 查看当前项目的所有 npm 脚本命令,可以使用不带任何参数的npm run命令。 $ npm run 二、原理 npm 脚本的原理非常简单。每当执行npm run,就会自动新建一个 Shell,在这个 Shell 里面执行指定的脚本命令。因此,只要是 Shell(一般是 Bash)可以运行的命令,就可以写在 npm 脚本里面。

Math使用

随机指定范围数字 function rnd(start, end){ return Math.floor(Math.random() * (end - start) + start); }

Mac系统自带截屏快捷键

在 Mac 上截图其实很简单,但很多人只知道 Command-Shift-3 和 Command-Shift-4,却不知道 Mac 的截图快捷键其实还有很多增强,具体如下: Command-Shift-3: 将整个屏幕拍下并保存到桌面。 Command-Shift-Control-3: 将整个屏幕拍下并保存到剪贴板 (Clipboard),你可以 Command+V 直接粘贴到如 Photoshop 等软件中编辑。 Command-Shift-4: 将屏幕的一部分拍下并保存到桌面。按下这个组合键后,光标会变为一个十字,你可以拖拉来选取拍摄区域。 Command-Shift-Control-4: 将屏幕的一部分拍下并保存到剪贴板。 Command-Shift-4- 空格: 这时光标会变为一个照相机图标,点击可拍下当前窗口或菜单或 Dock 以及图标等,只要将照相机图标移动到不同区域(有效区域会显示为浅蓝色)点击。 Command-Shift-Control-4- 空格: 将选取的窗口或其他区域的快照保存到剪贴板。

Mac系统查看端口战胜和杀死进程

Mac 系统查看端口占用和杀死进程 查看进程占用 方式一,使用lsof查询,显示的结果觉得不是太好查找 lsof -i tcp:8080 方式二:使用nettop,很容易看到结果,但不能结合 grep 是个遗憾 nettop -nm tcp 该命令会显示占用 8080 端口的进程,有其 pid , 可以通过 pid 关掉该进程 杀死进程 kill -9 pid

Mac系统搜索文件

通过 Find 命令搜索文件 find 命令非常高效,并且使用简单。find 命令来自 unix,OS X 和 Linux 系统同样支持该命令。find 最基本的操作就是: find 文件路径 参数 比如你可以通过以下命令在用户文件夹中搜索名字中包含 screen 的文件 find ~ -iname "screen*" 你也可以在特定的文件夹中寻找特定的文件,比如 find ~/Library/ -iname "com.apple.syncedpreferences.plist" 这个命令可以在 Library 文件夹中寻找com.apple.syncedpreferences.plist文件 通过 mdfind 命令搜索文件 mdfind 命令就是 Spotlight 功能的终端界面,这意味着如果 Spotlight 被禁用,mdfind 命令也将无法工作。mdfind 命令非常迅速、高效。最基本的使用方法是: mdfind -name 文件名字 比如你可以通过下面的命令寻找 Photo 1.PNG 文件 mdfind -name "Photo 1.PNG" 因为 mdfind 就是 Spotlight 功能的终端界面,你还可以使用 mdfind 寻找文件和文件夹的内容,比如通过以下命令寻找所有包含 Will Pearson 文字的文件: mdfind "Will Pearson" mdfind 命令还可以通过 -onlyin 参数搜索特定文件夹的内容,比如 mdfind -onlyin ~/Library plist 这条命令可以搜索 Library 文件夹中所有 plist 文件。

Mac中brew使用及配置

更新源 替换 homebrew 使用阿里云的源 替换 brew.git: cd "$(brew --repo)" git remote set-url origin https://mirrors.aliyun.com/homebrew/brew.git 替换 homebrew-core.git cd "$(brew --repo)/Library/Taps/homebrew/homebrew-core" git remote set-url origin https://mirrors.aliyun.com/homebrew/homebrew-core.git 替换 homebrew-bottles homebrew-bottles是 Homebrew 二进制预编译包的镜像 # fish 中在 ~/.config/fish/config.fish 中加入 set -x HOMEBREW_BOTTLE_DOMAIN https://mirrors.aliyun.com/homebrew/homebrew-bottles source ~/.config/fish/config.fish # zsh 中 echo 'export HOMEBREW_BOTTLE_DOMAIN=https://mirrors.aliyun.com/homebrew/homebrew-bottles' >> ~/.zshrc source ~/.zshrc 应用生效 brew update 换回官方源 # 重置 brew.git: cd "$(brew --repo)" # 重置 homebrew-core.git: cd "$(brew --repo)/Library/Taps/homebrew/homebrew-core" git remote set-url origin https://github.

MacBook Pro配置

昨天收到了公司给新配的 MacBook Pro,频幕感觉很细腻,但触摸板前端边缘为啥那么割手啊! 别的不说了,记录下系统配置。 系统偏好配置 触控板 光标与点按 > 三指移动 :这样就可以三指拖动文件了。 新版的 Macbook 将这个功能移动到 辅助功能 > 鼠标与触控板 > 触控板选项… 中,勾选启动拖移三指拖移就可以了。 光标与点按 > 轻拍来点按 :习惯了轻点完成实际按击 光标与点按 > 跟踪速度 :默认的指针滑动速度有点慢,设置成刻度 7 差不多了 键盘 快捷键 > 服务 > 新建位于文件夹位置的终端标签 :勾选这设置并设置了快捷键(control+cmt+c),以后在 Finder 中选择一个目录按下快捷键就可以打开终端并来到当前当前目录,功能很实用啊。熟悉后这个功能已经很少用了。 注意:在 Finder 中文件列表使用分栏方式显示时快捷键是无效的。 网络 # 查看 dns 解析情况 ding @223.5.5.5 +tcp google.com 高级… > DNS :公共 DNS 是必须添加的 223.5.5.5 阿里的 8.8.8.8 google 的 180.76.76.76 百度的 其它 显示 系统偏好设置 -> 安全性与隐私 -> 任何来源 选项:

mac shell 扩展属性

时常在 shell 中执行ls -alh命令时都能看到权限后面多了个@,查了资料才知道这是 mac 为显示文件所加入的属性,如: drwxr-xr-x@ 2 asins staff 68B 7 4 10:23 semantic xattr semantic 能显示文件所加入的属性, com.apple.quarantine 要想删除可以这样,xattr -d com.apple.quarantine semantic。

lsyncd 在mac下自动同步文件到服务器

一、lsyncd 介绍 略 二、安装 使用brew安装简单方便 brew install lsyncd 三、配置 -- install : -- lsyncd for osx -- local dir -> ssh -- brew install lsyncd -- brew install rsync ; /usr/local/bin/rsync instead of local rsync -- start up : sudo lsyncd ~/a.config -- file ~/a.config settings { logfile = "/var/log/lysncd/lsyncd.log", statusFile = "/var/log/lysncd/lsyncd.status", inotifyMode = "CloseWrite", -- 系统 inotify 指定监听的变化,可以是"Modify"、"CloseWrite" (默认) 或"CloseWrite or Modify". maxProcesses = 7, -- nodaemon =true, } sync { default.

JS调试console带颜色

一、NodeJs终端 1.1 使用方式: console.log("the \x1b[42m\x1b[31m\x1b[43mGreat Fire Wall\x1b[0m is most ugly and stupid!"); 效果: 上面可以看出: 所有的文本命令都是以 \x1b[ 打头 以m 结尾 -. 中间一到两位数字 两位数字是颜色 4# 表示背景色 3# 表示前景色 前景 / 背景色的第二个数对应的颜色一样 一位数字是控制 以下是可以使用的文本命令的参考: 1.2 前景色(文字颜色): \x1b[30m = 黑色 \x1b[31m = 红色 \x1b[32m = 绿色 \x1b[33m = 黄色 \x1b[34m = 蓝色 \x1b[35m = 洋红色 \x1b[36m = 青色 \x1b[37m = 白色 1.3 背景色: \x1b[40m = 黑色 \x1b[41m = 红色 \x1b[42m = 绿色 \x1b[43m = 黄色 \x1b[44m = 蓝色 \x1b[45m = 洋红色 \x1b[46m = 青色 \x1b[47m = 白色 1.

JS动画算法

缓动小算法 用一个简单的公式表示就是:A = A + (B - A) / 2,翻译一下就是:我下一秒的位置 = 现在位置 + 现在和初恋之间距离的一半。 运动用的定时器可以使用requestAnimationFrame,对于不支持的浏览器,可以使用下面的兼容代码: // requestAnimationFrame的兼容处理 if (!window.requestAnimationFrame) { requestAnimationFrame = function(fn) { setTimeout(fn, 17); }; } 整理成通用方法 /** * 缓动动画算法 * @param {Number} start 起始位置 * @param {Number} end 目标位置 * @param {Number} rate 缓动速率 * @param {Function} 变化的位置回调,会传入`value`、`isEnding`两参数。 * @param {Number} value 当前位置 * @param {Boolean} isEnding 是否动画结束了 */ function easeOut(start, end, rate, callback) { end = end || 0; rate = rate || 2; if( start == end || typeof start !

iTerm2常用快捷键

文本复制 在 iTerm2 中,选中即复制,所以在 iTerm2 的 session 中不用再去 ⌘+c , 可直接将选中的文本复制到剪切板中去,通常选中有以下两种方法: 使用鼠标选择。 使用 ⌘+f 搜索,查找内容会高亮显示,通过 tab / shift+tab 扩大选中范围,快捷键可在 Profiles > Keys 中设置。 智能选中 双击选中,三击选中整行,四击智能选中 按住⌘键 可以拖拽选中的字符串; 点击 url:调用默认浏览器访问该网址; 点击文件:调用默认程序打开文件; 如果文件名是 filename:42,且默认文本编辑器是 Mac vim 将会直接打开到这一行; 点击文件夹:在 finder 中打开该文件夹; 同时按住 opt 键,可以以矩形选中。 Tab 窗口面板管理 Mac 下默认的终端窗口分屏不是很好使,当初就是因为这个原因,才使用 iTerm2, 那么接下来看下 iTerm2 窗口面板分割功能。 Tab 纵向分割:⌘+d Tab 横向分割:⌘+shift+d 切换 Tab 中的 pane:⌘ + [ 或者 ⌘+ opt + arrow

Http请求中Form Data与Request Payload的区别

HTTP请求中的Form Data与Request Payload的区别date: 2017-08-10 前端开发中经常会用到AJAX发送异步请求,对于POST类型的请求会附带请求数据。而常用的两种传参方式为:Form Data 和 Request Payload。 GET请求 使用get请求时,参数会以key=value的形式拼接在请求的url后面。例如: http://m.baidu.com/address/getlist.html?limit=50&offset=0&t=1502345139870 但是受限于请求URL的长度限制,一般参数较少时会使用get请求。 POST请求 当参数数量较多,且对数据有一定安全性要求时,会考虑用post请求传递参数数据。POST请求的参数数据是在请求体中。 方式一: Form Data形式 当POST请求的请求头里设置Content-Type: application/x-www-form-urlencoded(默认), 参数在请求体以标准的Form Data的形式提交,以&符号拼接,参数格式为key=value&key=value&key=value… 前端代码设置: xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded'); xhr.send('a=1&b=2&c=3'); 在servlet中,后端可以通过request.getParameter(name)的形式来获取表单参数。 方式二:Request Payload形式 如果使用AJAX原生POST请求,请求头里设置Content-Type:application/json,请求的参数会显示在Request Payload中,参数格式为JSON格式:{“key”:“value”,“key”:“value”…},这种方式可读性会更好。 后端可以使用getRequestPayload方法来获取。 Form Data 和 Request Payload 区别 如果请求头里设置Content-Type: application/x-www-form-urlencoded,那么这个请求被认为是表单请求,参数出现在Form Data里,格式为key=value&key=value&key=value… 原生的AJAX请求头里设置Content-Type:application/json,或者使用默认的请求头Content-Type:text/plain;参数会显示在Request payload块里提交。

http_server访问日志分析

cat passport-login.txt |sort|uniq -c|sort -nr > ./passport-access.log sort 排序 一句话需求 排查线上所有使用者,推进业务方旧登录组件入口地址下线的工作。 现状 进入线上passport-login应用单台机器访问日志目录中,通过以下语言 cat 2018/12/2018-12-16-taobao-access_log |grep 'http://account.youku.com/static-resources/js/loadFrame.js'|awk -F " " '{print $10}'|awk -F'?' '{gsub(/https?:\/\//,"http://",$1);gsub(/\/i\/[a-zA-Z0-9=]+/,"/i/xxx",$1);gsub(/\/u\/[a-zA-Z0-9=]+/,"/u/xxx",$1);gsub(/\/detail\/show\/[a-zA-Z0-9=]+/,"/detail/show/xxx",$1);gsub(/\/*\"?$/,"",$1);print $1}'|sort|uniq -c|sort -nr 从日志中搜索loadFrame.js文件引用的 reffer,得到结果如下: 43160 http://www.youku.com 11508 http://www.youku.com/index/y404 6046 http://movie.youku.com 3896 http://tv.youku.com cat cai/logs/cronolog/2019/07/2019-07-03-taobao-access_log |awk -F " " '{print $10}'|awk -F'?' '{gsub(/https?:\/\//,"http://",$1);gsub(/\/i\/[a-zA-Z0-9=]+/,"/i/xxx",$1);gsub(/\/u\/[a-zA-Z0-9=]+/,"/u/xxx",$1);gsub(/\/show\/id_.*?/,"/show/id_xxx",$1);print $1}'|sort|uniq -c|sort -nr