命令行和代码片段记录

1,001 阅读6分钟

打包相关

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相关报错。
以国际化脚本为例,全局引入国际化脚本对象,避免每个文件都需要引入一次
// webpack.config.js
plugins: [
    new webpack.ProvidePlugin({ $i18n: ['@/i8n', 'default'] }) // @/i8n为模块所在路径
]

// .eslintrc.js
{ globals: { $i18n: 'readonly' } } // 解决eslint报错

// global.d.ts
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]; 打开包的git地址。
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; 查看commit记录的详细信息。
git log -1 -p [filePath];查看某个文件最近一次提交的修改内容。
git reflog; 查看包括被删除的commit记录和reset操作的所有记录。
git show [commitId] [filePath]; 查看某个文件在某次commitId提交的记录。
git show --name-only [commitId];查看某次提交的文件名称列表。
git push orign -- delete [分支名称]; 删除远程分支。
git rebase [branchName]; 以[branchName]的最新commit准,为当前所在分支重定基底。
git merge [branchName] --squash: 将branchName的多个commitId合并为1个,然后合并到当前分支。
git clean -nfd; 删除未追踪的文件(n:询问;f:文件;d:文件夹)。
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]; -u为包括新增的文件或者文件夹。
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; // 批量删除分支名包含"feature"关键字的分支

linux

open -e xxx; // 打开某个文件
source xxx; // 读取并且执行某个文件;eg:source ~/.bash_profile可以使修改的配置立即生效
curl
  -d '{"name": "jack", "age": "12"}' // 设置post请求体
  -b 'cookie1=1;cookie2=2' // 设置cookie
  -H 'Content-Type: application/json;' // 设置请求头
  -o data.json // 将接口的返回数据下载到本地
lsof -i:3333; // 查看端口占用情况
kill -9 [pid]; // 杀死某个进程。eg:杀死进程id是9270的进程:kill -9 9270;

正则

金额:/((^[1-9]\d*)|^0)(\.\d{0,2}){0,1}$/

js

// requestAnimationFrame模拟setTimeOut
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)
}

// 并发限制promise
 class LimitPromise {            
    constructor(max, fn) {                
        this.max = max; // 并发数                
        this.callback = fn; // 任务函数;返回一个promise的函数               
        this.loop = []; // 任务队列                
        this.allData = []; // 任务结果队列            
    }            

    push = () => { // 调用栈push任务                
        const resolvedNum = this.allData.filter(Boolean).length; // 完成的任务个数               
        const loopLength = this.loop.length; // 任务队列中的任务个数           
        const index = resolvedNum + loopLength;  // 待push到任务队列的任务索引              
        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] // data: res的数据;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
            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))
    }
}

// mock Object.assign
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;
    }
})

// instanceof(x, y)
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;}
}

// new 为关键字,只模拟功能实现,不模拟具体调用,最后调用为new2(constructor, params1, params1);
function new2() {
    var constructor = Array.prototype.shift(arguments); // 获取构造函数,并且shift会改变arguments
    var obj = new Object();
    obj.__proto__ = constructor.prototype; // 加入原型链
    var result = constructor.apply(obj, arguments);
    return typeof result === 'object' ? result : obj; // 构造如果显示return一个对象,则返回该对象,否则返回this;
}

mock bind
Function.prototype.bind2 = function(context) {
    const args = Array.prototype.slice.call(arguments, 1); // 获取除绑定的this参数之外的其他参数
    const self = this;
    var fBind = function() {
        return self.apply(this instance fBind ? this : context, args.concat(Array.prototype.slice.call(arguments))); 
        // this instance fBind ? this : context为判断fBind是否作为构造函数调用,如果是则将this指向实例,否则this指向context参数。
    }
    fBind.prototype = Object.create(self.prototype);
    return fBind;
}

// 复制某个dom节点的text
function clip(ele) {
    if (!ele) return;
    const selection = window.getSelection(); // 获取选中区域对象

    if (ele.nodeName === 'INPUT' || ele.nodeName === 'TEXTAREA') {
        ele.select(); // 此时ele被选中
        ele.setSelectionRange(0, ele.value.length);
    }  else {
        selection.removeAllRanges(); // 清空选中的区域
        const range = document.createRange(); // 新建区域
        range.selectNodeContents(ele); // 将目标节点添加置range
        selection.addRange(range); // 往选区中添加新建的区域,此时ele被选中
    }

    document.execCommand('copy'); // 执行复制命令
    selection.removeAllRanges(); // 此时ele恢复未选中状态
}

// 将search参数直接转成对象
Object.fromEntries(new URLSearchParams(location.search))

// 将blob数据下载到本地文件
function downloadBlob(blob, name = 'file.txt') {
  // Convert your blob into a Blob URL (a special url that points to an object in the browser's memory)
  const blobUrl = URL.createObjectURL(blob);

  // Create a link element
  const link = document.createElement("a");

  // Set link's href to point to the Blob URL
  link.href = blobUrl;
  link.download = name;

  // Append link to the body
  document.body.appendChild(link);

  // Dispatch click event on the link
  // This is necessary as link.click() does not work on the latest firefox
  link.dispatchEvent(
    new MouseEvent('click', { 
      bubbles: true, 
      cancelable: true, 
      view: window 
    })
  );

  // Remove link from body
  document.body.removeChild(link);
}

example:
let jsonBlob = new Blob(['{"name": "test"}'])
downloadBlob(jsonBlob, 'myfile.json');


// document.createNodeIterator
将某个dom变成可迭代对象

example:
const body = document.createNodeIterator(document.body);
let cur = body.nextNode();while(cur) {
  console.log(cur); // 深度优先遍历节点
  cur = body.nextNode();}

// new IntersectionObserver(callback, options)
观察目标元素与视口或者root元素的交叉情况

yarn

yarn upgrade [packageName]@[version] // 更新某个包到某个版本

docker

docker run --name custom_docker_container -d -p 8888:8080 -v /data:/data docker_image_name// 使用一个叫做docker_image_name的镜像,以后台模式启动一个叫做custom_docker_container的容器,映射本地
8888端口到容器8080端口,绑定本地/data文件到容器/data文件

docker exec -it custom_docker_container /bin/sh
// 以伪终端的形式进入一个叫做custom_docker_container的容器

docker ps -a // 列出所有的容器

docker images // 列出所有的镜像

docker build -t custom_image:latest // 使用当前目录的dockerFile创建一个叫做custom_image的镜像,版本为latest

https://www.coderjia.cn/archives/dba3f94c-a021-468a-8ac6-e840f85867ea  // 配置镜像源

typescript

// 返回一个对象所有属性值组成的联合类型
const obj = { name: 'jack', age: 12 } as const; // as const 必须有,没有的话会返回string | number
type valuestype = typeof obj[keyof typeof obj]; // 'jack' | 12

小工具

yalc: 前端本地link工具