记录和整理自己日常使用的技术wiki
renmm / blogs Goto Github PK
View Code? Open in Web Editor NEW整理自己平时遇到的技术wiki
整理自己平时遇到的技术wiki
记录和整理自己日常使用的技术wiki
通过nvm来切换node的版本时,需要注意先把全局安装的模块给安装到新的node版本里。
npm ls -g --depth=0
npm uninstall -g [module xx]
需要重新打开命令行,已打开的不生效
nvm alias default <版本号>
临时切换版本,只在当前终端内有效,新开终端无效。
nvm use <版本号>
@vue/[email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
└── [email protected]
feat: 添加了分享功能
给每篇博文添加了分享功能
- 添加分享到微博功能
- 添加分享到微信功能
- 添加分享到朋友圈功能
Issue #1, #2
Closes #1
type用于说明 commit 的类别,可以使用如下类别:
在开发npm包时,约定目录结构,有助于理解代码结构。
功能 | 说明 | 场景 |
---|---|---|
纯node环境 | 符合commonjs规范,适合node环境使用 | node server端,比如工具包,日志等 |
浏览器使用 | 使用script方式引入 | 组件库,client端使用 |
cli命令行工具 | 命令行使用,例如工具包/脚手架之类 | 命令行工具 |
统一使用ts编码,好处:类型提示
按目录约定:
功能 | 说明 |
---|---|
src | 源码目录 |
lib | 打包输出的代码,也有dist目录,可以统一约定lib |
es | 符合es module规范的代码 |
umd | 符合umd规范的代码,给浏览器的script 直接饮用 |
typings | 类型定义 |
假设开发一个lib包: lib-a, 按照约定:
lib-a
├── umd
| └── index.js
├── es
| └── index.js
├── lib
| └── index.js
├── src -- 源码目录
| └── index.js
├── typings
| └── index.d.ts
├── .gitignore
└── package.json
// package.json
{
"main": "lib/index.js",
"module": "es/index.js",
"types": "typings/index.d.ts"
}
单元测试,
基准,用于基准测试,就是一个性能的衡量基准。
使用semantic-release 去自动管理发布
可参考https://blog.dteam.top/posts/2020-05/semantic-release.html
用图表展示数据
是基于g2,封装的react,vue组件化的
标记 | 设计模式原则名称 | 简单定义 |
---|---|---|
SRP | 单一职责原则 | 一个类只负责一个功能领域中的相应职责 |
OCP | 开闭原则 | 对扩展开放,对修改关闭 |
LSP | 里氏代换原则 | 所有引用基类的地方必须能透明地使用其子类的对象 |
ISP | 接口隔离原则 | 类之间的依赖关系应该建立在最小的接口上 |
DIP | 依赖倒转原则 | 依赖于抽象,不能依赖于具体实现 |
CARP | 合成/聚合复用原则 | 尽量使用合成/聚合,而不是通过继承达到复用的目的 |
LOD | 迪米特法则 | 一个软件实体应当尽可能少的与其他实体发生相互作用 |
astexplorer 是一个集成了很多AST的编译器。可以实时看输出的AST语法。
我对其如何实现兼容多个版本的parser感兴趣,记录下我的整理思路。
答:使用parser.loadParser去加载多个异步模块。
正则表达式,主要使用场景是针对字符串进行替换,分词摘取等
正则表达式测试:https://c.runoob.com/front-end/854
正则表达式图形理解:https://regexper.com/
一些有用的表达式:
生成ast时,需要做分词处理,比如
通常是用字母、下划线、冒号开头(vue的绑定属性用:开头,通常我们不会这么定义)的,然后包含字母数字下划线中划线冒号和点的
const attrKey = /[a-zA-Z_:][-a-zA-Z0-9_:.]*/
const attr = /([a-zA-Z_:][-a-zA-Z0-9_:.]*)=("([^"]*)"|'([^']*)'|([^\s"'=<>`]+)/
web页面录屏实现
Virtual Dom算法实现笔记
使用RecordRTC进行屏幕录制
navigator.sendBeacon() 方法可用于通过HTTP将少量数据异步传输到Web服务器
wiki: https://developer.mozilla.org/zh-CN/docs/Web/API/Navigator/sendBeacon
记录自己写cli遇到的问题和想法💡~
(function(modules) { // webpackBootstrap
// The module cache
var installedModules = {};
// The require function
function __webpack_require__(moduleId) {
// Check if module is in cache
if (installedModules[moduleId]) {
/******/
return installedModules[moduleId].exports;
}
// Create a new module (and put it into the cache)
var module = installedModules[moduleId] = {
i: moduleId,
l: false,
exports: {}
};
// Execute the module function
modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
// Flag the module as loaded
module.l = true;
// Return the exports of the module
return module.exports;
}
// expose the modules object (__webpack_modules__)
__webpack_require__.m = modules;
// expose the module cache
__webpack_require__.c = installedModules;
// define getter function for harmony exports
__webpack_require__.d = function(exports, name, getter) {
if (!__webpack_require__.o(exports, name)) {
Object.defineProperty(exports, name, {
enumerable: true,
get: getter
});
}
};
// define __esModule on exports
__webpack_require__.r = function(exports) {
if (typeof Symbol !== 'undefined' && Symbol.toStringTag) {
Object.defineProperty(exports, Symbol.toStringTag, {
value: 'Module'
});
}
Object.defineProperty(exports, '__esModule', {
value: true
});
};
// create a fake namespace object
/******/
// mode & 1: value is a module id, require it
/******/
// mode & 2: merge all properties of value into the ns
/******/
// mode & 4: return value when already ns object
/******/
// mode & 8|1: behave like require
__webpack_require__.t = function(value, mode) {
if (mode & 1) value = __webpack_require__(value);
if (mode & 8) return value;
if ((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
var ns = Object.create(null);
__webpack_require__.r(ns);
Object.defineProperty(ns, 'default', {
enumerable: true,
value: value
});
if (mode & 2 && typeof value != 'string') for (var key in value) __webpack_require__.d(ns, key,
function(key) {
return value[key];
}.bind(null, key));
return ns;
};
// getDefaultExport function for compatibility with non-harmony modules
__webpack_require__.n = function(module) {
var getter = module && module.__esModule ?
function getDefault() {
return module['default'];
}:
function getModuleExports() {
return module;
};
__webpack_require__.d(getter, 'a', getter);
return getter;
};
// Object.prototype.hasOwnProperty.call
__webpack_require__.o = function(object, property) {
return Object.prototype.hasOwnProperty.call(object, property);
};
// __webpack_public_path__
__webpack_require__.p = "/";
// Load entry module and return exports
return __webpack_require__(__webpack_require__.s = "wNqJ");
})
({
"wNqJ":
(function(module, exports) {
var add = function add() {
console.log('add');
};
add();
})
});
参考:
require.context(
'./', true,
/^\.\/(?!utils|transpilers)[^/]+\/(transformers\/([^/]+)\/)?(codeExample\.txt|[^/]+?\.js)$/
);
require.context(directory, useSubdirectories = false, regExp = /^\.\//);
这段代码的意思:
/^\.\/(?!utils|transpilers)[^/]+\/(transformers\/([^/]+)\/)?(codeExample\.txt|[^/]+?\.js)$/
匹配'x'仅仅当'x'后面不跟着'y',这个叫做正向否定查找。
例如,/\d+(?!.)/匹配一个数字仅仅当这个数字后面没有跟小数点的时候。正则表达式/\d+(?!.)/.exec("3.141")匹配‘141’而不是‘3.141’
x(?!y)
监听数据变化时使用,一般用于当数据变化,需要执行联动时操作。
watch: {
// 如果 `question` 发生改变,这个函数就会运行
question: function (newQuestion, oldQuestion) {
this.answer = 'Waiting for you to stop typing...'
this.debouncedGetAnswer()
}
},
watch: {
obj: {
handler(newName, oldName) {
console.log('obj.a changed');
},
immediate: true,
deep: true
}
}
不过,这样写,可能会有性能影响,如果obj对象嵌套多,会造成一定的内存开销,可以用字符串形式监听。
优化完:
watch: {
'obj.a': {
handler(newName, oldName) {
console.log('obj.a changed');
},
immediate: true,
}
}
uni-app里提供了2套sdk方案,一套是vue,使用webview渲染;一套是nvue(native vue的缩写), 使用原生渲染(基于 weex 改进的原生渲染引擎)
记录前端实用性的开源库
直接贴最终代码: 传送门
我们知道css实现文本过长,实现省略号:
.text {
overflow: hidden;
text-overflow:ellipsis;
white-space: nowrap;
}
.w100{ width: 100px;}
<div class="text w100">这段css要生效,前提是长度固定(例如width:100px),使用百分比都不行</div>
这段css要生效,前提是长度固定(例如width:100px),使用百分比都不行。
当使用flex布局时,固定长度+可变长度(适配不同移动端设备),这时需要注意几个css属性就可以实现
html结构需要调整:
<div class="filed">
<div class="filed--label">萨达多撒多</div>
<div class="filed-text">
<div class="filed-text--wrapper">当使用flex布局时,固定长度+可变长度(适配不同移动端设备),这时需要注意几个css属性就可以实现</div>
</div>
</div>
.filed { display: flex;}
.filed--label {width: 100px;}
.filed-text {
flex:1;
overflow: hidden;
}
.filed-text--wrapper {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
width: 100%;
}
当react组件想要使用redux的store里的数据时,使用connect函数。
最顶层的react组件,提供store数据源,与connect搭配使用。
直接上如何使用:
const ThemeContext = React.createContext('light');
const App = () => {
return (
<ThemeContext.Provider value="dark">
<Toolbar />
</ThemeContext.Provider>
)
}
按位操作符将其操作数当作 32 位的比特序列(由 0 和 1 组成)操作,返回值依然是标准的 JavaScript 数值
位运算在某些场景下,如需要大量计算的情况下,可以提高性能,比如图片处理,虚拟dom等
对每对比特位执行与(AND)操作。只有 a 和 b 都是 1 时,a AND b 才是 1。
场景:适用于频繁条件判断时使用
if (flags & VNodeFlags.ELEMENT) {
// VNode 是普通标签
mountElement(/* ... */)
} else if (flags & VNodeFlags.COMPONENT) {
// VNode 是组件
mountComponent(/* ... */)
} else if (flags & VNodeFlags.TEXT) {
// VNode 是纯文本
mountText(/* ... */)
}
wiki: https://developer.mozilla.org/zh-CN/docs/Web/Events
{selector: 'body > #u1 .active '}
点击输入框,触发点击事件,采集到数据: {selector: 'body > .input-wrap .active'}
在自动化跑脚本时,.active样式是点击后才加上的,所以自动化时找不到此元素。
答:className由于有可能动态变化,所以,className标识元素不安全,应该采用tag来表示。
// puppeteer里与document.querySelectorAll表现一致
document.querySelectorAll('body:nth-child(2)')
===
document.querySelectorAll('body')
//selenium里表示找body集合里第2个元素,与jquery api 表现一致。
按钮随屏滚动,点击按钮回到按钮的原始位置。(组件的位置不固定)
分析:
和回到首页功能类似,只不过是回到某一个指定元素位置。
https://segmentfault.com/a/1190000015338047
https://xiaotianxia.github.io/blog/vuepress/js/scroll_behaviors.html
以abc
包为例:
# 安装到dependencies
npm i --save abc
yarn add abc
# 安装到devDependencies
npm i --save-dev abc
yarn add -D abc
# 全局安装
npm i -g abc
yarn global add abc
# 项目
npm list
yarn list
# 全局查看
npm list -g --depth=0
yarn global list
# 项目
npm uninstall abc
yarn remove abc
# 全局
npm uninstall -g abc
yyarn global remove abc
# 项目
npm update abc
yarn upgrade abc
# 全局
npm update -g abc
yarn global upgrade abc
sketch是目前最流行的设计网页的工具。
在使用lerna publish时,确保以下2点:
npm login
Username: xxxxx
Password:
Email: (this IS public) [email protected]
Logged in as xxxxx on https://registry.npmjs.org/.
登录成功后,再使用lerna publish发布版本。
const fnIntercept = <F extends (...args: any[]) => any>(fn: F, intercept) => {
return (...args: Parameters<F>): ReturnType<F> => {
intercept(...args);
return fn(...args);
};
};
以一个宏任务(script(整体代码))开始,内部执行task,执行完当前所有的微任务队列后,单个宏任务完毕,返回值。
可以简单理解为2层循环,外层为宏任务循环,内存为微任务循环。
特点:
执行下看看,会输出啥
(function test() {
setTimeout(function() { console.log(1) }, 0); //回调会被添加到macro-task队列
new Promise(function(resolve) {
console.log(2);
for (var i = 0; i < 10000; i++) {
i == 9999 && resolve();
}
console.log(3);
}).then(function() { // then 1
console.log(4);
new Promise(function(resolve) {
setTimeout(function() { //回调会被添加到macro-task队列
resolve();
console.log(5);
}, 0);
console.log(6);
}).then(function() { // then 2
console.log(7); //回调会在resolve后,添加到micro-task队列
});
}).then(function() { // then 3
console.log(10);
new Promise(function(resolve) {
setTimeout(function() { //回调会被添加到macro-task队列
resolve();
console.log(11);
}, 0);
console.log(12);
}).then(function() { // then 4
console.log(13); //回调会在resolve后,添加到micro-task队列
});
})
console.log(8);
return 9;
})();
//控制台打印的结果如下:
//2
//3
//8
//4
//6
//10
//12
//9 (此次是chrome输出的,干扰项,请忽略,因为多个语句块,也只返回最后一个,所以没有任何意义~)
//1
//5
//7
//11
//13
从script开始(整体代码):
第一轮:
入栈:
task = [
2,
3,
8,
]
console:
2,3,8,
简化宏任务,实际是发起异步任务,异步任务执行完毕,再将cb存放到macro-task
macro-task = [
1,
]
micro-task = [
then 1
]
执行micro-task: then 1
入栈:
task = [4, 6]
console:
4,6
macro-task = [
setTimeout(1),
setTimeout(5)
]
micro-task = [
then 3
]
执行micro-task:then 3
入栈:
task = [10, 12]
macro-task = [
setTimeout(1),
setTimeout(5),
setTimeout(11)
]
setTimeout(1) 直接执行,没啥可说的
...
执行macro-task: setTimeout(5)
入栈:
task = [5]
micro-task = [then 2]
最终console:
2,3,8,4,6,10,12
1,
5,7
11,13
能理解下面的,基本没问题了
let a = (function test() {
setTimeout(function() { console.log(1) }, 0); //回调会被添加到macro-task队列
new Promise(function(resolve) {
console.log(2);
for (var i = 0; i < 10000; i++) {
i == 9999 && resolve();
}
console.log(3);
}).then(function() { // then 1
console.log(4);
new Promise(function(resolve) {
setTimeout(function() { //回调会被添加到macro-task队列
resolve();
console.log(5);
}, 0);
console.log(6);
}).then(function() { // then 2
console.log(7); //回调会在resolve后,添加到micro-task队列
});
}).then(function() { // then 3
console.log(10);
new Promise(function(resolve) {
setTimeout(function() { //回调会被添加到macro-task队列
resolve();
console.log(11);
}, 0);
console.log(12);
}).then(function() { // then 4
console.log(13); //回调会在resolve后,添加到micro-task队列
});
})
console.log(8);
return 9;
})();
console.log(a)
console.log(77);
let b = (function test2 () {
setTimeout(function() { console.log(21) }, 0);
new Promise(function(resolve) {
console.log(22);
for (var i = 0; i < 10000; i++) {
i == 9999 && resolve();
}
console.log(23);
}).then(function() { // then 1
console.log(24);
new Promise(function(resolve) {
setTimeout(function() { //回调会被添加到macro-task队列
resolve();
console.log(25);
}, 0);
console.log(26);
}).then(function() { // then 2
console.log(27); //回调会在resolve后,添加到micro-task队列
});
})
console.log(88);
return 99;
})();
console.log(b)
//控制台打印的结果如下:
//2
//3
//8
//9
//77
//22
//23
//88
//99
//4
//6
//24
//26
//10
//12
//1
//21
//5
//7
//25
//27
//11
//13
git config --global url."https://hub.fastgit.xyz/".insteadOf https://github.com/
git config --list
判断类型 | 作用 |
---|---|
String | string |
Number | number |
Boolean | boolean |
Null | object |
Undefined | undefined |
Symbol | symbol |
BigInt | bigint |
Function | function |
宿主对象 | (由 JS 环境提供) |
其他任何对象 | object |
除了 null 和 undefined之外,所有基本类型都有其对应的包装对象
类型 | 值 |
---|---|
String | string |
Number | number |
Boolean | boolean |
Null | object |
Undefined | undefined |
Symbol | symbol |
BigInt | bigint |
Function | function |
宿主对象 | (由 JS 环境提供) |
其他任何对象 | object |
判断两个值是否相同
document.json
meta.json
pages
previews
user.json
场景: 常见于移动端表单布局
使用flex布局,核心是justify-content: space-between; 表示:
均匀排列每个元素,首个元素放置于起点,末尾元素放置于终点
.layout-2-columns{
display: flex;
justify-content: space-between;
}
<div class="layout-2-columns" >
<div class="label">城市</div>
<div class="wrapper">
<select name="cars" id="cars">
<option value="volvo">Volvo</option>
<option value="saab">Saab</option>
<option value="mercedes">Mercedes</option>
<option value="audi">Audi</option>
</select>
</div>
</div>
// todos
为什么想分析这个库呢,因为我最近有个项目,想学习如何实现一个AST解析。
而这个库呢,包含了很多AST库如何解析,是一个非常好的入手项目。
线上地址:https://astexplorer.net/
仓库地址:https://github.com/fkling/astexplorer
// todos
//todos
移动端click会有2个问题:
是因为双击缩放的功能,这个功能最早是由iphone为解决访问网站所设计(当时主流网站都是为大屏设计)
$ cd "$(brew --repo)" && git remote -v
origin https://github.com/Homebrew/brew.git (fetch)
origin https://github.com/Homebrew/brew.git (push)
$ cd "$(brew --repo homebrew/core)" && git remote -v
origin https://github.com/Homebrew/homebrew-core.git (fetch)
origin https://github.com/Homebrew/homebrew-core.git (push)
$ git -C "$(brew --repo)" remote set-url origin https://mirrors.aliyun.com/homebrew/brew.git
$ git -C "$(brew --repo homebrew/core)" remote set-url origin https://mirrors.aliyun.com/homebrew/homebrew-core.git
$ echo 'export HOMEBREW_BOTTLE_DOMAIN=https://mirrors.aliyun.com/homebrew/homebrew-bottles' >> ~/.zshrc
$ source ~/.zshrc
$ echo 'export HOMEBREW_BOTTLE_DOMAIN=https://mirrors.aliyun.com/homebrew/homebrew-bottles' >> ~/.bash_profile
$ source ~/.bash_profile
$ brew update
切换完毕后再次执行brew install Graphviz ,成功!
使用github的功能来管理项目的整个迭代。
issue,一般都是用英文写,那如果项目都用issue来创建,英语不好,全靠翻译,这尼玛自己给自己添堵呢!效率呢?
推荐issues-translate-action) 做双语翻译,nice!
封装/继承/多态
一句话表示,将行为和逻辑封装起来,控制属性/方法的访问权限(也即私有属性/受保护属性/公共属性,方法也一样,类似这种)
子类继承父类,实现方法/属性的复用。类型有类继承,接口继承
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.