为了简单教学,一切从简。此npm包作为一个工具库,存放一些简单的工具函数。
我们先从如何使用此工具包来看
一. 如何安装
只需在你的前端项目终端输入安装依赖命令即可
npm install sy-front-end-utils
二. 如何使用
分为两种引入 CommonJS 和 ES Module
// CommonJS
const { formatDate } =require('sy-front-end-utils');
// ES Module
import { formatDate } from'sy-front-end-utils';
示例:
const date = new Date('2024-01-08 14:30:00');
formatDate(date); // 返回: "2024-01-08 14:30:00"
毋庸置疑 就和使用第三方依赖一摸一样
三. 如何构建
首先在根目录放入主函数文件index.js
/**
* 日期格式化
* @param {Date} date 日期对象
* @param {string} format 格式字符串
* @returns {string} 格式化后的日期字符串
*/
export const formatDate = (date, format = 'YYYY-MM-DD HH:mm:ss') => {
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, '0');
const day = String(date.getDate()).padStart(2, '0');
const hours = String(date.getHours()).padStart(2, '0');
const minutes = String(date.getMinutes()).padStart(2, '0');
const seconds = String(date.getSeconds()).padStart(2, '0');
return format
.replace('YYYY', year)
.replace('MM', month)
.replace('DD', day)
.replace('HH', hours)
.replace('mm', minutes)
.replace('ss', seconds);
};
/**
* 深拷贝对象
* @param {Object} obj 要拷贝的对象
* @returns {Object} 拷贝后的新对象
*/
export const deepClone = (obj) => {
if (obj === null || typeof obj !== 'object') {
return obj;
}
if (obj instanceof Date) {
return new Date(obj);
}
if (obj instanceof Array) {
return obj.map(item => deepClone(item));
}
if (obj instanceof Object) {
const copy = {};
for (const key in obj) {
if (obj.hasOwnProperty(key)) {
copy[key] = deepClone(obj[key]);
}
}
return copy;
}
};
/**
* 防抖函数
* @param {Function} func 要执行的函数
* @param {number} wait 等待时间
* @returns {Function} 防抖后的函数
*/
export const debounce = (func, wait = 300) => {
let timeout;
return function executedFunction(...args) {
const later = () => {
clearTimeout(timeout);
func(...args);
};
clearTimeout(timeout);
timeout = setTimeout(later, wait);
};
};
/**
* 节流函数
* @param {Function} func 要执行的函数
* @param {number} limit 时间间隔
* @returns {Function} 节流后的函数
*/
export const throttle = (func, limit = 300) => {
let inThrottle;
return function executedFunction(...args) {
if (!inThrottle) {
func(...args);
inThrottle = true;
setTimeout(() => (inThrottle = false), limit);
}
};
};
/**
* 生成指定范围内的随机整数
* @param {number} min 最小值
* @param {number} max 最大值
* @returns {number} 随机整数
*/
export const randomInteger = (min, max) => {
return Math.floor(Math.random() * (max - min + 1)) + min;
};
/**
* 检查是否为有效的电子邮件地址
* @param {string} email 电子邮件地址
* @returns {boolean} 是否有效
*/
export const isValidEmail = (email) => {
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
return emailRegex.test(email);
};
/**
* 获取URL参数
* @param {string} name 参数名
* @returns {string|null} 参数值
*/
export const getUrlParam = (name) => {
const urlParams = new URLSearchParams(window.location.search);
return urlParams.get(name);
};
/**
* 将对象转换为查询字符串
* @param {Object} obj 要转换的对象
* @returns {string} 查询字符串
*/
export const objectToQueryString = (obj) => {
return Object.keys(obj)
.map((key) => `${encodeURIComponent(key)}=${encodeURIComponent(obj[key])}`)
.join('&');
};
/**
* 将驼峰命名转换为短横线命名
* @param {string} str 驼峰命名的字符串
* @returns {string} 短横线命名的字符串
*/
export const camelToKebabCase = (str) => {
return str.replace(/([a-z0-9]|(?=[A-Z]))([A-Z])/g, '$1-$2').toLowerCase();
};
/**
* 将短横线命名转换为驼峰命名
* @param {string} str 短横线命名的字符串
* @returns {string} 驼峰命名的字符串
*/
export const kebabToCamelCase = (str) => {
return str.replace(/-./g, (x) => x[1].toUpperCase());
};
package.json 文件
{
"name": "your-package-name",
"version": "1.0.0",
"description": "你的包描述",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "你的名字",
"license": "MIT"
}
在 package.json 中:
-
修改 name 为你的包名
-
更新 description 描述
-
添加相关的 keywords
-
修改 author 信息
做到这两步一个简单npm依赖包也就可以准备发布了
要发布肯定要将项目先打包
npm init -y
引入babel依赖帮我们在不同浏览器做兼容处理
npm install --save-dev @babel/core @babel/cli @babel/preset-env
package.json 文件中加入build命令
"build": "node build.js"
到这里npm包就可以发布了
可以先将发布命令告诉你
npm login
npm run build
npm publish
没错就是这么简单,只需要在终端依次输入这三个命令,没有报错就成功了
请先别急,让我们继续完善一些
以下为可选选项,需要则加
a. 创建README.md文件
用来介绍你的依赖包
b. 加入测试用例
1.安装 Jest 和相关依赖
npm install --save-dev jest @babel/core @babel/preset-env babel-jest
- 创建 babel 配置文件,以支持 ES 模块语法
{
"presets": [["@babel/preset-env", { "targets": { "node": "current" } }]]
}
- 创建测试文件夹和测试文件
import {
formatDate,
deepClone,
debounce,
isValidEmail,
randomInteger,
camelToKebabCase,
kebabToCamelCase
} from '../index.js';
describe('工具函数测试', () => {
// 测试 formatDate
test('formatDate 格式化日期', () => {
const date = new Date('2024-01-08 14:30:00');
expect(formatDate(date)).toBe('2024-01-08 14:30:00');
});
// 测试 deepClone
test('deepClone 深拷贝对象', () => {
const original = { a: 1, b: { c: 2 } };
const cloned = deepClone(original);
cloned.b.c = 3;
expect(original.b.c).toBe(2);
expect(cloned.b.c).toBe(3);
});
// 测试 isValidEmail
test('isValidEmail 验证邮箱格式', () => {
expect(isValidEmail('test@example.com')).toBe(true);
expect(isValidEmail('invalid-email')).toBe(false);
});
// 测试 randomInteger
test('randomInteger 生成随机整数', () => {
const num = randomInteger(1, 10);
expect(num).toBeGreaterThanOrEqual(1);
expect(num).toBeLessThanOrEqual(10);
});
// 测试 camelToKebabCase
test('camelToKebabCase 驼峰转短横线', () => {
expect(camelToKebabCase('backgroundColor')).toBe('background-color');
});
// 测试 kebabToCamelCase
test('kebabToCamelCase 短横线转驼峰', () => {
expect(kebabToCamelCase('background-color')).toBe('backgroundColor');
});
});
- 修改 package.json 的测试脚本
"scripts": {
"test": "jest --coverage",
"test:watch": "jest --watch",
"build": "node build.js"
},
- 运行测试
npm test监视模式(在开发时很有用)npm run test:watch
提示:Jest 会生成测试覆盖率报告,你可以在 coverage 目录中查看详细报告。
c. 兼容commonJs和ES模块兼容
- 修改package.json并创建相应的入口文件
"main": "./dist/index.cjs",
"module": "./dist/index.mjs",
"exports": {
".": {
"require": "./dist/index.cjs",
"import": "./dist/index.mjs"
}
},
- 创建构建脚本 build.js
import { build } from 'esbuild';
// 构建 ESM 版本
build({
entryPoints: ['./index.js'],
outfile: 'dist/index.mjs',
bundle: true,
format: 'esm',
platform: 'neutral',
target: ['es2015'],
minify: true,
sourcemap: true
}).catch(() => process.exit(1));
// 构建 CommonJS 版本
build({
entryPoints: ['./index.js'],
outfile: 'dist/index.cjs',
bundle: true,
format: 'cjs',
platform: 'neutral',
target: ['es2015'],
minify: true,
sourcemap: true
}).catch(() => process.exit(1));
- 安装构建依赖
npm install --save-dev esbuild
d.压缩文件
在build.js中有两个参数
minify: true //压缩代码,移除空格和注释
sourcemap: true //生成 source map 文件,方便调试
这样会生成压缩后的文件:
-
dist/index.mjs(压缩后的 ES 模块版本)
-
dist/index.mjs.map(ES 模块的 source map)
-
dist/index.cjs(压缩后的 CommonJS 版本)
-
dist/index.cjs.map(CommonJS 的 source map)
四. 如何发布
必须使用npm源
npm config set registry https://registry.npmjs.org/
如果使用是淘宝源,无法发布。可能都无法登录,因为淘宝源仅有只读属性
# 1. 登录到 npm(如果还没登录)
npm login
# 2. 构建项目
npm run build
# 3. 发布新版本
npm publish
发布完成后可更换为淘宝源npm config set registry https://registry.npmmirror.com