打包相关
1. rollup打包lodash-es默认不会tree-shake,需要利用插件babel-plugin-lodash进行处理。
步骤:
1. npm i babel-plugin-lodash @rollup/plugin-babel --save-dev
2. 在rollup.config.js中增加配置:plugins: plugins: ['lodash']
webpack.ProvidePlugin + eslint + typescript 配置全局变量,并且解决eslint和ts相关报错。
以国际化脚本为例,全局引入国际化脚本对象,避免每个文件都需要引入一次
plugins: [
new webpack.ProvidePlugin({ $i18n: ['@/i8n', 'default'] })
]
{ globals: { $i18n: 'readonly' } }
import i18n from '@/i18n';
declare global { let $i18n: typeof i18n }
vscode
设置类:
Auto Reveal:控制资源管理器是否应在打开文件时自动显示并选择文件。
插件类:
快捷键:
删除光标所在行:command + X
操作类:
新建代码片段:设置 -> 用户代码片段
快捷键代码片段
"Print to console": {
"prefix": "log",
"body": [
"console.log('$1');",
"$2"
],
"description": "Log output to console" },
"quick react module": {
"prefix": "react",
"body": [
"import React from 'react';",
"",
"export default function () {",
" return (",
" <></>",
" );",
"}",
""
],
"description": "快速生成react模版代码"
},
"className": {
"prefix": "className",
"body": [ "className={styles.${1:container}}" ],
"description": "快速生成className"
},
"import styles": {
"prefix": "import styles",
"body": [
"import styles from './index.module.less'"
],
"description": "快速生成className"
},
"useState-module": {
"prefix": "state",
"body": [
"const [${1}, set${1/.*/${0:/pascalcase}/}]=useState($0)"
],
"description": "useStateModule"
}
npm
1. npm repo [packageName]
2. npm docs [packageName]
3. npm view [packagename] versions/version
4. npm ls [packageName]
5. npm ls [packageName] -g
6. npm link
7. npm link [packageName]
git
git log -p
git log -1 -p [filePath]
git reflog
git show [commitId] [filePath]
git show --name-only [commitId]
git push orign -- delete [分支名称]
git rebase [branchName]
git merge [branchName] --squash: 将branchName的多个commitId合并为1个,然后合并到当前分支。
git clean -nfd
git branch -m [oldName] [newName]
git branch -b [本地分支名称] origin/[远端分支名称];将远端分支拉取到本地并新建本地分支。
git checkout -b [newBranchName] [oldBranchName]
git fetch
git stash save [commitInfo];将工作区的修改暂存。
git stash save -u [commitInfo]
git stash push -m [commitInfo] [文件路径];仅对指定的文件路径的文件来做stash操作。
git restore -s [commitID] [filePath];将filepath对应的文件恢复到commitId时的状态,可用于撤销某次提交对某个文件的更改。
git stash show -p [commitInfo]:查看某个暂存的修改。
git stash drop [commitInfo]
git stash list
git stash pop
git stash clear
git stash apply [commitInfo]
git restore --worktree [filePath]: 撤销文件在工作区的修改。
git restore --staged [filePath]:撤销add操作。
git restore -s [commitId] [filePath]:将文件恢复到指定commitId版本。
git reset HEAD [文件路径];撤销add操作。
git reset --hard可以撤销git stash pop之后导致的冲突,并且stash的内容不会丢失git reset --mixed(默认) 将commit内容重置到工作区,工作区原有的内容也保留。
git reset --soft 将commit内容重置到暂存区。工作区和暂存区的内容也保留。
git grep -n -p [code]: 查看指定code所在位置。
git diff --name-only: diff只显示文件名。
git rm -r --cached [文件名]:停止对git已跟踪的文件跟踪
git revert [commitId]: 反做某次提交
git branch | grep "feature" | xargs git branch -d
linux
open -e xxx;
source xxx;
curl
-d '{"name": "jack", "age": "12"}'
-b 'cookie1=1;cookie2=2'
-H 'Content-Type: application/json;'
-o data.json
lsof -i:3333;
kill -9 [pid];
正则
金额:/((^[1-9]\d*)|^0)(\.\d{0,2}){0,1}$/
js
function timeout(time, callback) {
const now = Date.now();
let raf;
function r() {
if (Date.now() - now < time) {
raf && cancelAnimationFrame(raf);
raf = window.requestAnimationFrame(r)
} else {
callback();
cancelAnimationFrame(raf);
}
}
raf = window.requestAnimationFrame(r)
}
class LimitPromise {
constructor(max, fn) {
this.max = max;
this.callback = fn;
this.loop = [];
this.allData = [];
}
push = () => {
const resolvedNum = this.allData.filter(Boolean).length;
const loopLength = this.loop.length;
const index = resolvedNum + loopLength;
const item = this.list[index];
if (index >= this.list.length) return ;
const task = this.createTask(item, index);
this.loop.push(task);
}
start = list => {
this.list = list;
while(this.loop.length < this.max) {
this.push()
}
return this.run(Promise.race(this.loop));
}
run = race => {
return race.then((config) => {
const [data, index, f] = config;
this.allData[index] = { data };
this.loop.splice(this.loop.indexOf(f), 1);
if (this.allData.filter(Boolean).length === this.list.length) {
return this.allData
} else {
this.push();
return this.run(Promise.race(this.loop))
}
})
}
createTask = (args, index) => {
const p = this.callback(args).then(data => {
return [data, index, p]
})
return p;
}
}
eg:
const p = new LimitPromise(3, fn);
p.start(['参数1', '参数2', ‘参数3’, ‘参数4’]).then(res => { console.log(res) })
function renderArr(len) {
return Array(len).fill(0).map(Number.call, Number)
};
renderArr(10) => [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
function compose(...funcs) { return function (x) {
return funcs.reduce(function (arg, fn) {
return fn(arg);
}, x);
};
}
function curry(fn, context) {
return function curried(...args) {
const bool = fn.length <= args.length;
if (bool) {
fn.apply(context, args)
} else {
return function(...args2) {
return curried(...args.concat(args2))
}
}
}
}
function partial(fn) {
const args = Array.prototype.slice.call(arguments, 1);
return function() {
return fn.apply(this, args.concat(...arguments))
}
}
Object.defineProperty(Object, assgin2, {
wirte: true,
configurable: true,
enumerable: false,
value(target) {
if (target == null) throw new TypeError('Cannot convert undefined or null to object');
const results = typeOf target === 'Object' ? target : Object(target);
if (arguments.length > 1) {
for (let i = 1; i < arguments.length; i += 1) {
const arg = arguments[i];
if (arg !== null) {
const obj = typeOf arg === 'Object' || 'Function' ? arg : Object(arg);
for (const k in obj) {
if (Object.prototype.hasOwnProperty(obj, k)) {
results[k] = obj[k]
}
}
}
}
}
return results;
}
})
function instanceof(x, y) {
while(x.__proto__!==null) {
if(x.__proto__===y.prototype) {
return true;
break;
}
x.__proto__ = x.__proto__.proto__;
}
if(x.__proto__==null) {return false;}
}
function new2() {
var constructor = Array.prototype.shift(arguments);
var obj = new Object();
obj.__proto__ = constructor.prototype;
var result = constructor.apply(obj, arguments);
return typeof result === 'object' ? result : obj;
}
mock bind
Function.prototype.bind2 = function(context) {
const args = Array.prototype.slice.call(arguments, 1);
const self = this;
var fBind = function() {
return self.apply(this instance fBind ? this : context, args.concat(Array.prototype.slice.call(arguments)));
}
fBind.prototype = Object.create(self.prototype);
return fBind;
}
function clip(ele) {
if (!ele) return;
const selection = window.getSelection();
if (ele.nodeName === 'INPUT' || ele.nodeName === 'TEXTAREA') {
ele.select();
ele.setSelectionRange(0, ele.value.length);
} else {
selection.removeAllRanges();
const range = document.createRange();
range.selectNodeContents(ele);
selection.addRange(range);
}
document.execCommand('copy');
selection.removeAllRanges();
}
Object.fromEntries(new URLSearchParams(location.search))
function downloadBlob(blob, name = 'file.txt') {
const blobUrl = URL.createObjectURL(blob);
const link = document.createElement("a");
link.href = blobUrl;
link.download = name;
document.body.appendChild(link);
link.dispatchEvent(
new MouseEvent('click', {
bubbles: true,
cancelable: true,
view: window
})
);
document.body.removeChild(link);
}
example:
let jsonBlob = new Blob(['{"name": "test"}'])
downloadBlob(jsonBlob, 'myfile.json');
将某个dom变成可迭代对象
example:
const body = document.createNodeIterator(document.body);
let cur = body.nextNode();while(cur) {
console.log(cur);
cur = body.nextNode();}
观察目标元素与视口或者root元素的交叉情况
场景:文件下载请求时将响应头设置为responseType: 'blob',后端接口成功会返回文件流,错误时返回json,需将blob对象转为json在响应拦截器中添加可将blob对象转为json
const res = response.data;
if (res.type === 'text/html') {
var enc = new TextDecoder('utf-8');
res.arrayBuffer().then(buffer => {
let data = JSON.parse(enc.decode(new Uint8Array(buffer))) || {};
})
}
yarn
yarn upgrade [packageName]@[version]
docker
docker run --name custom_docker_container -d -p 8888:8080 -v /data:/data docker_image_name
8888端口到容器8080端口,绑定本地/data文件到容器/data文件
docker exec -it custom_docker_container /bin/sh
docker ps -a
docker images
docker build -t custom_image:latest
https:
typescript
const obj = { name: 'jack', age: 12 } as const;
type valuestype = typeof obj[keyof typeof obj];
小工具
yalc: 前端本地link工具