npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

mv-common

v1.1.4

Published

一款支持ESModule以及CommonJS的工具库

Downloads

496

Readme

MCommon

介绍

一款支持ESModule以及CommonJS的工具库

安装

(npm|yarn|pnpm) install mv-common

使用说明

此工具会识别使用使用者环境,当使用的环境为CommonJS时,仅会引入CommonJS 的工具方法,不会额外引入ESModule相关,反之,只会引入ESModule,不会引入CommonJS相关。

// 支持按需导入
import { isValidUrl } from 'mv-common';
isValidUrl('http://17Memory.cn'); // true

// 支持全局导入
import common from 'mv-common';
common.isValidUrl('http://17Memory.cn'); // true

贡献

  1. Fork 本仓库
  2. 新建 feat/xxx 分支
  3. Push代码,并提交 Merge Request, 作者欢迎各位为此开源工具贡献一份力量~

示例

此工具分为三类,分别是:Basic Common、Browser API、CommonJS

Basic Common

Basic Common 不论是在 ESModule 或 CommonJS 环境下,都会被加载, 所以不论哪种环境都可以使用

/**
 * 是否是一个空数组
 * @param { Array<unknown> } value 需要判断的数据
 * @returns { boolean } 是否为空数组
 * **/
import { isEmptyArray } from 'mv-common';

isEmptyArray([]); // true
isEmptyArray([1, 2, 3]); // false

// 当传递的类型不是数组类型或为空时,则会返回 false
isEmptyArray('array'); // false

/**
 * 判断一个数据或一组数据均为指定的类型
 * @param { string } type 类型名称  array、object 等使用原型链判断的类型末尾小写
 * @param { Array } args 需要判断的数据
 * @returns { boolean } 一个数据或一组数据是否均为指定的类型
 * **/
import { isEmptyArray } from 'mv-common';

isEmptyArray('array', [], []); // true
isEmptyArray('array', ''); // false
isEmptyArray('array', '', []); // false

/**
 * 交集方法
 * @param { Array<Array<unknown>> } args 数据列表
 * @returns { Array<unknown> } 交集数组
 * **/
import { intersectionArrayList } from 'mv-common';

intersectionArrayList([1, 2, 3], [1, 2, 4], [2]); // [2]
intersectionArrayList([1, 2, 3], [1, 2, 4], [6]); // []

/**
 * 差集方法
 * @param { Array<unknown> } baseArray  求差集的基准列表
 * @param { Array<unknown> } args 差集列表
 * @returns { Array<unknown> } 差集
 * **/
import { differenceArrayList } from 'mv-common';

differenceArrayList([1, 2, 3], [1, 2, 4], [1, 2, 5]); // [3]

/**
 * 并集方法
 * @param { Array<Array<unknown>> } args  求并集的数组
 * @returns { Array<unknown> } 并集数组
 * **/
import { unionArrayList } from 'mv-common';

unionArrayList([1, 2, 3], [1, 2, 4]); // [1, 2]

/**
 * 判断一个url是不是有有效的http格式
 * @param { string } url 链接地址
 * @returns { boolean } 是否是一个链接
 * **/
import { isValidUrl } from 'mv-common';

isValidUrl('http://17Memory.cn'); // true
isValidUrl(0); // false

/**
 * 获取一个数据的类型
 * @param { unknown } value 需要判断类型的数据
 * @returns { string | null } 判断的数据类型
 * **/
import { getType } from 'mv-common';

getType('http://17Memory.cn'); // string
getType(0); // number
getType([]); // array

/**
 * 判断一个数据的类型是否为指定的类型
 * @param { unknown } value 需要判断类型的数据
 * @param { string } type 期望的数据类型
 * @return { boolean } 是否为期望的类型
 * **/
import { isType } from 'mv-common';

isType('http://17Memory.cn', 'string'); // true

/**
 * 异步或同步延迟等待一段时间
 * @param { number } timeout 等待时常,默认为 1000ms
 * @param { boolean } sync 是否同步
 * @returns { Promise<boolean> } 异步,是否执行完成
 * **/
import { sleep } from 'mv-common';

// 会阻塞主线程的执行
sleep(1000, true); // true

// 异步任务,不会阻塞主线程
sleep(1000, false); // true

/**
 * 防抖
 * @param { (...rest: Array<unknown>) => unknown } cb 方法
 * @param { number } delay 防抖延迟时常
 * @param { boolean } immediate 是否需要立即执行
 * **/
import { debounce } from 'mv-common';

// 防抖,时间为 1000
debounce(
    () => {
        console.log(123);
    },
    1000,
    false
);

// 下一轮JS轮询任务执行
debounce(() => {
    console.log(123);
});

/**
 * 节流
 * @param { (...rest: Array<unknown>) => unknown } cb 方法
 * @param { number } delay 节流延迟时常, 默认值为: 0
 * **/
import { throttle } from 'mv-common';

// 节流,时间为 1000
throttle(() => {
    console.log(123);
}, 1000);

// 下一轮JS轮询任务执行
debounce(() => {
    console.log(123);
});

/**
 * 是否是一个空对象
 * @param { object } value 需要判断的数据
 * @returns { boolean } 是否为空对象
 * **/
import { isEmptyJSON } from 'mv-common';

isEmptyJSON({}); // true
isEmptyJSON({ a: 123 }); // false

// 当传递的类型不是JSON类型或为空时,则会返回 false
isEmptyJSON(123); // false

/**
 * 扁平化一个JSON对象
 * @param { Object } obj 需要扁平化的对象
 * @returns { Object } 返回扁平化之后的JSON对象
 * **/
import { flatJSON } from 'mv-common';

// 常规使用
flatJSON({ a: 123, b: { c: 456, q: 789 } }); // { a: 123, c: 456, q: 789 }

// 多级单属性传递时,只会保留最后一级
flatJSON({ a: { b: { c: 123 } } }); // {c: 123}

// 多属性重名时,后面的会覆盖前面的
flatJSON({ b: 123, c: 456, a: { v: { c: 123 } } }); // { b: 123, c: 123 }

/**
 * 将一个JSON对象按照指定的分隔符,拼接为特定的字符串
 * @param { Object } content 内容
 * @param { string } sep 分隔符字符串, 默认为空字符串
 * @return { string } 处理完成之后的字符串
 * **/
import { splitJsonToContent } from "mv-common"

// 常规使用
splitJsonToContent({ a: 123, b: 456 }, ":") // a: 123 \n b: 456

// 当传递多级JSON时,则JSON会被扁平化
splitJsonToContent({ a: 123 b: { c: { d: 123 } } }, ":")  // a:123 \n d:123
import { merge } from "mv-common"

// 合并对象
merge.recursive({a: 123}, b: {456}) // {a: 123, b: 456}

// 当存在冲突时, 新的会覆盖旧的
merge.recursive({a: 123}, {a: 12345, b: 12312}) // {a: 12345, b: 12312}

// 支持多层级合并,详情参考: https://github.com/swordev/merge
basicCommon.merge.recursive(
    { a: 123, b: { c: { d: 123 } } },
    { q: 123, b: { d: 123 } },
) // { a: 123, b: { c: { d: 123 }, d: 123 }, q: 123 }

Browser API

Browser API 仅会在 ESModule 环境下被导入,依赖浏览器运行环境

/**
 * 获取浏览器属性
 * @returns { string } name 浏览器名称
 * @returns { string } version 浏览器版本
 * **/
import { getBrowserInfo } from 'mv-common';

getBrowserInfo(); // {name: 'Chrome', version: 'xxx.x.x.x'}
/**
 * 将 blob 转换为 string 字符串
 * @param { Blob } blob 二进制数据内容
 * **/
import { blobToString } from 'mv-common';

blobToString(new Blob([JSON.stringify({ a: 123 })])); // {name: 123}

CommonJS

CommonJS 仅会在 CommonJS环境下被导入,依赖于 Node 运行环境,由于其的特性,因此在此环境下使用时,库的代码无法被 Tree Sharking

/**
 * 查看一个文件或目录是否在指定的路径下存在
 * @param { string } filename 文件名称
 * @param { string } cwd 工作目录,默认值为: 当前工作目录
 * @returns { boolean } 是否存在
 * **/
import { exists } from 'mv-common';

exists('/aa.txt'); // true | false
exists('/aa/bb', '/aa/bb/cc'); // true | false
/**
 * 浅层读取一个目录下的文件或者文件夹
 * @param { string } targetPath 目标路径
 * @param { string } type 文件类型,默认值为: 全部类型
 * @return { Array<string> } 文件列表
 * **/
import { readForTypeFileDir } from 'mv-common';

// 返回  aa/bb 目录下的文件列表
readForTypeFileDir('aa/bb', 'file'); // ['xx', 'xx']

// 返回 aa/bb 目录下的目录列表
readForTypeFileDir('aa/bb', 'dir'); // ['xx', 'xx']

// 返回 aa/bb 目录下所有文件
readForTypeFileDir('aa/bb', 'all'); // ['xx', 'xx']
readForTypeFileDir('aa/bb'); // ['xx', 'xx']
/**
 * 创建一个目录(仅支持目录)
 * @param { string } targetPath 目标路径
 * @param { boolean } cover 是否覆盖创建 默认值为: false
 * **/
import { createDir } from 'mv-common';

// 当 aa/bb 存在时,则会递归删除后重新创建(非异步阻塞函数)
createDir('aa/bb', true); // undefined

// 当 aa/bb 存在时,则函数中止(非异步阻塞函数)
createDir('aa/bb', false); // undefined
createDir('aa/bb'); // undefined
/**
 * 写入的一个文件(仅支持文件)
 * @param { string } targetPath 目标路径
 * @param { string } content 文件内容
 * @param { boolean } cover 是否覆盖创建,默认值为: false
 * **/
import { createFile } from 'mv-common';

// 当 aa/bb/cc.txt 存在时,则会删除后重新创建(非异步阻塞函数)
createFile('aa/bb/cc.txt', '12321', true); // undefined

// 当 aa/bb/cc.txt 存在时,则函数中止, 当 aa/bb 不存在时,则会先创建后在写入txt(非异步阻塞函数)
createFile('aa/bb/cc.txt', '12321', false); // undefined
createFile('aa/bb/cc.txt', '12321'); // undefined
/**
 * 当文件存在时,读取一个文件的文件内容
 * @param { string } targetPath 目标文件路径的
 * @param { Parameters<typeof fs.readFileSync>[1] } options 读取时需要传递的参数
 * @returns { string | buffer } 返回的文件内容
 * **/
import { readExistsFile } from 'mv-common';

// 当 aa/bb/cc.txt 存在时,则会读取其内容(非异步阻塞函数)
readExistsFile('aa/bb/cc.txt'); // xxxxxxx

// 当 aa/bb/dd.txt 不存在时,返回为空(非异步阻塞函数)
readExistsFile('aa/bb/dd.txt'); // ''

// 读取时,可传递参数(非异步阻塞函数)
readExistsFile('aa/bb/cc.txt', { encoding: 'utf-8' }); // xxx
/**
 * 移动工具类,此方法仅适用文件的移动
 * @param { string } sourcePath 需要拷贝的路径
 * @param { string } targetPath 目标路径
 * @param { boolean } cover 是否强制覆盖
 * @returns { number } type 移动是否成功: 1 | 0
 * @returns { string } sourcePath 源路径
 * @returns { string } targetPath 目标路径
 * **/
import { copyFile } from 'mv-common';

// 将 aa/bb 拷贝到 cc目录下,覆盖拷贝
copyFile('aa/bb.txt', 'cc', true); // { type: 1, sourcePath: 'xx', targetPath: 'xx' }

// 将 aa/bb 拷贝到 cc目录下,若cc目录下存在aa.txt,在则函数中止, type 返回为 0
copyFile('aa/bb/aa.txt', 'cc', false); // { type: 0, sourcePath: 'xx', targetPath: 'xx' }
copyFile('aa/bb/aa.txt', 'cc'); // { type: 0, sourcePath: 'xx', targetPath: 'xx' }
/**
 * 拷贝整个目录及其子路径至指定的目录
 * @param { string } origin 源路径
 * @param { string } targetPath 目标路径
 * @param { boolean } cover 是否覆盖
 * @param { (sourcePath: string, destPath: string) => boolean | undefined } filterCb 自定义判断函数
 * **/
import { copyDirectory } from 'mv-common';

// 将 aa/bb 拷贝到 cc目录下,覆盖拷贝
copyDirectory('aa/bb', 'cc', true);

// 将 aa/bb 拷贝到 cc目录下,非覆盖拷贝
copyDirectory('aa/bb', 'cc', false);
copyDirectory('aa/bb', 'cc');

// 将 aa/bb 拷贝到 cc目录下,非覆盖拷贝
copyDirectory('aa/bb', 'cc', true, (sourcePath: string, destPath: string) => {
    // 可自行判断每个拷贝文件,返回值为 true 则拷贝,false 则不拷贝
    return true;
});
/**
 * 移除文件, 当传递的是文件,则删除文件,传递的是目录,则递归删除目录
 * @param { string } targetPath 文件路径
 * */
import { removeFileOrDir } from 'mv-common';

// 若 aa/bb 目录下存在子文件,则子文件也会递归删除
removeFileOrDir('aa/bb'); // undefined

// 删除文件
removeFileOrDir('aa/bb/aa.txt'); // undefined

// 若路径不存在,则中止函数
removeFileOrDir('aa/bb/dd'); // undefined
/**
 * 检测权限,若权限不为读写,则赋值为读写
 * @param { string } filepath 文件路径
 * **/
import { checkXPermission } from 'mv-common';

// 给 aa/bb 赋予读写权限
checkXPermission('aa/bb'); // undefined
/**
 * 检测文件是否为只读权限
 * @param { string } filepath 文件路径
 * **/
import { checkReadPermission } from 'mv-common';

// 给 aa/bb 赋予只读权限
checkReadPermission('aa/bb'); // undefined
/**
 * 递归删除目录, 手动方式删除(兼容老版本Node)
 * @param { string } dirPath 目录的路径
 * @param { Array<string> } whiteList 删除文件的白名单
 * **/
import { dropCleanFolder } from 'mv-common';

// 删除 aa/bb 及其子目录
dropCleanFolder('aa/bb'); // undefined
/**
 * 使用子进程执行一条命令
 * @param { string } command 执行的命令
 * @param { Partial<SpawnSyncOptionsWithStringEncoding> } options 执行命令的参数
 * **/
import { execCommand } from 'mv-common';

// 执行一条命令, 当指定 stdio 为: inherit 时,则 resolve 于 reject的返回值均为null,因为此时,输出管道将指向于父进程
execCommand('echo 123', { stdio: 'inherit' }).then((res) => console.log(res)); // null

// 反之,可通过 resolve 于 reject 来捕获 stdout 与 stderr, 获取命令的执行结果
execCommand('echo 123').then((res) => console.log(res)); // xxxxxx

// 默认工作目录为当前程序的执行目录,需要时,可指定
execCommand('echo 123', { cwd: '123213' }).then((res) => console.log(res)); // xxxxxx
/**
 * 获取系统信息
 * @returns { string } platform 系统平台
 * @returns { string } digit 系统位数
 * @returns { boolean } isWindow 是否是windows系统
 * @returns { boolean } isMac 是否时mac系统
 * @returns { boolean } isWin64 是否是win64
 * @returns { boolean } isWin32 是否是win32
 * **/
import { getSystemInfo } from 'mv-common';

getSystemInfo(); // { platform: 'xx', digit: 'xx', isWindow: true, isMac: false, isWin64: true, isWin32: false };
/**
 * 获取当前系统用户的家目录
 * **/
import { getHome } from 'mv-common';

getHome(); // xxxx
/**
 * 获取系统的 appData目录
 * **/
import { getAppData } from 'mv-common';

getAppData(); // xxxx
/**
 * 根据appData目录为基准,获取路径
 * @param { string } refer 参照路径
 * **/
import { getAppData } from 'mv-common';

getReferToAppData('aaa'); // /appData/aaa
/**
 * 根据进程的名称,模糊查询,获取进程的PID
 * @param { string } name 进程的名称
 * **/
import { getPidByName } from 'mv-common';

// 返回当前系统进程中包含名称 'nodejs' 关键字的进程, 当系统进程中不存在此进程的名称时,则返回空数组
await getPidByName('nodejs'); // [xxx, xxx]
/**
 * 提供进程的名称,模糊查询进程是否存在
 * @param  { string } processName 进程名称
 * **/
import { isActiveProcessByName } from 'mv-common';

// 查询当前系统进程中是否包含 python 关键字名称的进程
await isActiveProcessByName('nodejs'); // true | false
/**
 * 提供一个PID,查看这个PID是否正在运行
 * @param {string} pid 进程ID
 * **/
import { isActiveProcessByPid } from 'mv-common';

await isActiveProcessByPid(1001); // true | false
/**
 * 根据进程的PID,结束此进程
 * @param { number | Array<number> } pid 进程PID
 * **/
import { killProcessPid } from 'mv-common';

// 结束 pid 为 123 的进程
await killProcessPid(123); // true | false

// 结束 pid 为 123, 456, 789 的进程
await killProcessPid([123, 456, 789]); // true | false
/**
 * 提供进程的名称,结束掉此进程,名称会模糊查询
 * @param { string } processName 进程的名称
 * **/
import { processName } from 'mv-common';

// 结束系统进程中名称的包含 123 关键字的所有进程
await processName('123'); // true | false
/**
 * 获取当前项目的包版本管理器, 目前支持 yarn|npm|pnpm
 * @param { string } targetPath 目标路径
 * **/
import { getPackageMangerName } from 'mv-common';

// 获取指定路径下,采用的是什么包管理器
getPackageMangerName('123'); // npm | yarn | pnpm
/**
 * 当文件存在时,则合并内容,反之创建文件
 * @param { string } source 源路径
 * @param { string } targetPath 目标路径
 * @param { Object } options 写入或创建文件的参数
 * **/
import { mergeOrCreateFile } from 'mv-common';

// 文件不存在,直接移动
mergeOrCreateFile('/xx', '/xx/xx');

// 文件存在,追加内容
mergeOrCreateFile('/xx/xx', '/xx/xx');

// 文件存在
mergeOrCreateFile('/xx/xx', '/xx/xx', {
    wrap: true, // 追加内容时,是否在追加的内容前,加上换行默认值为: false
    jsonOrArray: true, // 追加内容时,移动的文件是否为json,这样的话在追加内容时,json内容会先做一次合并, 并且, 此时的 wrap 参数会取消生效。默认值为: false
    tabWidth: 4 // 追加内容时,且文件内容为json,写入文件后格式化的缩进, 此时的 wrap 参数会取消生效。默认值为: 4
});
/**
 * 判断一个目录是否是盘符目录
 * @param { string } targetPath 目标路径
 * **/
import { isDriveDirectory } from 'mv-common';

isDriveDirectory('/aa/bb'); // true | false
/**
 * 向上层目录层级执行一个函数,直到函数返回成功或遇到盘符目录为止
 * @param { string } targetPath 需要执行函数的目录
 * @param { Function } cb 执行的自定义函数, 此函数返回true则终止执行,反之执行至盘符目录为止
 * **/
import { parentExecHandlerPromise } from 'mv-common';

// targetPath 当前层级的目录
await parentExecHandlerPromise('/aa/bb', (targetPath: string) => true); // 当cb函数返回true则结束递归向上目录执行
/**
 * 向上查询文件的存在目录
 * @param { string } targetPath 基准目录
 * @param { string } handler 文件名称或执行函数
 * @returns { string } 查询到的文件目录
 * **/
import { findParentFile } from 'mv-common';

// targetPath 当前层级的目录
await findParentFile('/aa/bb', 'aa.txt'); // 以 /aa/bb为基准,向上查找 aa.txt 是否存在