1 准备工作
- 在github上创建仓库并clone到本地
- npm init 初始化配置
zhongweisheng@zws code % git clone https://github.com/Weison-Zhong/weison-utils.git
zhongweisheng@zws code % cd weison-utils
zhongweisheng@zws weison-utils % npm init
package name: (weison-utils) weison-utils
version: (1.0.0) 0.0.1
description: 前端常用工具库
entry point: (index.js)
test command:
git repository: (https://github.com/Weison-Zhong/weison-utils.git)
keywords: 前端 前端工具库 utils 钟伟胜
author: weison
license: (ISC) MIT
Is this OK? (yes)
- 创建src和dist目录
- 在src目录下新建index.js并写上工具函数
export function myTypeof(val) {
var type = typeof val;
var resObj = {
"[object Array]": "array",
"[object Map]": "map",
"[object Set]": "set",
"[object Object]": "object",
"[object Number]": "object number",
"[object String]": "object string",
"[object Boolean]": "object boolean",
};
if (val === null) {
return "null";
} else if (type === "object") {
var typeStr = Object.prototype.toString.call(val);
return resObj[typeStr];
} else {
return type;
}
}
//节流,连续触发只会在每time时间段内执行回调
//例如滚动屏幕scroll,不停的滚动只会在[0,time],[time+1,time*2],...每个time时间段内分别执行一次回调
export function throttle(
cb,
interval,
isImmediately = true,
isLastExec = false
) {
//isImmediately是否首次触发事件马上执行回调,否的话则等到下个time时间段再执行
//isLastExec是否执行最后一次
let last = isImmediately ? 0 : Date.now();
let t = null;
return function () {
const args = arguments;
const now = Date.now(); //当前时间戳
if (now - last > interval) {
//上次执行的时间戳减去当前触发事件的时间戳大于设定的间隔
cb.apply(this, args);
last = now; //回调后更新最新一次执行的时间戳
} else if (isLastExec) {
t && clearTimeout(t);
t = setTimeout(() => {
cb.apply(this, args);
last = Date.now(); //需要重新获取now并刷新last防止最后一次执行后新触发事件时立马执行
}, interval);
}
};
}
//防抖,连续触发只会在最后一次触发事件延迟time内不再触发事件后执行回调一次
//例如滚动屏幕scroll,不停的滚动只会在(1,需要停止滚动 2,且停止滚动后等待time内不再滚动)后执行一次回调
export function debounce(cb, time = 3000, isImmediately = false) {
//isImmediately是否立即执行
let t = null;
let exec = true;
return function () {
const args = arguments;
t && clearTimeout(t); //清除上次触发事件的定时器
if (isImmediately && exec) {
cb.apply(this, args); //首次需立即执行
exec = false;
} else {
t = setTimeout(() => {
//重新设定最新一次触发事件的定时器
cb.apply(this, args); //time内不再触发,即t不被clear,那么time后执行一次回调cb
}, time);
}
};
}
//深拷贝
export function deepClone(origin, target) {
var tar = target || {},
toStr = Object.prototype.toString,
arrType = "[object Array]";
for (var key in origin) {
if (origin.hasOwnProperty(key)) {
if (typeof origin[key] === "object" && origin[key] !== null) {
toStr.call(origin[key]) === arrType ? (tar[key] = []) : (tar[key] = {});
deepClone(origin[key], tar[key]);
} else {
tar[key] = origin[key];
}
}
}
return tar;
}
2 配置rollup并打包
- npm install -D rollup
- 根目录下新建rollup.config.js配置文件
export default {
input: "./src/index.js", // 入口
output: [
{
format: "umd", // 打包为umd通用格式,兼容了amd和CommonJS,可在浏览器或node环境运行
file: "dist/index.js", //输出目录及文件名
name: "index.js",
},
],
};
- 修改package.json配置文件
{
"name": "weison-utils",
"version": "0.0.1",
"description": "前端常用工具库",
+ "main": "dist/index.js",
"scripts": {
+ "build": "rollup -c"
},
"repository": {
"type": "git",
"url": "git+https://github.com/Weison-Zhong/weison-utils.git"
},
"keywords": [
"前端",
"前端工具库",
"utils",
"钟伟胜"
],
"author": "weison",
"license": "MIT",
"bugs": {
"url": "https://github.com/Weison-Zhong/weison-utils/issues"
},
"homepage": "https://github.com/Weison-Zhong/weison-utils#readme",
"devDependencies": {
"rollup": "^2.76.0"
}
}
- 运行
npm run build
打包
3 发布到npm
- 注册npm账号注册入口
- 如果设置了其他npm镜像源的务必要换回官方源
npm config set registry https://registry.npmjs.org
- 登录 npm login 按提示操作
- 发布 npm publish
4 发布成功后尝试在项目中使用,以我博客的置顶按钮显隐切换为例
- yarn add weison-utils
import React, { useEffect, useState, useCallback, memo } from "react";
import { getScrolledSize, getViewportSize } from "../../utils/tools";
import { debounce } from "weison-utils";
const handleScrollToTop = () =>
(document.body.scrollTop = document.documentElement.scrollTop = 0);
export default memo(() => {
const [isShow, setIsShow] = useState(false);
const scrollCb = useCallback(() => {
const scrolledHeight = getScrolledSize().top;
const clientHeight = getViewportSize().height;
if (scrolledHeight > clientHeight / 2) {
//滚动距离超过窗口高度一半时显示置顶按钮
setIsShow(true);
} else {
setIsShow(false);
}
}, []);
useEffect(() => {
const debouncedScrollCb = debounce(scrollCb, 800);
document.addEventListener("scroll", debouncedScrollCb);
return () => document.removeEventListener("scroll", debouncedScrollCb);
}, []);
return (
<>
{isShow && (
<button
className="bg-primary fixed z-50 bottom-3 right-3 w-10 h-10 border-2 rotate-180 rounded-full overflow-hidden border-secondary hover:border-primary focus:border-primary focus:outline-none"
onClick={handleScrollToTop}
>
<i className="icon-long-arrow-down iconfont text-xl text-secondary" />
</button>
)}
</>
);
});
5 设置github action自动发布npm
- 到npm官网登录账号生成一个token,点击右上角个人中心Access Tokens
- 新建一个名为npm的token
- 复制token值
- 把刚刚复制的token值粘贴到github上
- 这里的Name命名可按照个人喜好
- 在Actions选项下输入 Publish Node.js Package 按回车键搜索
- 修改npm-publish.yml文件如下
# This workflow will run tests using node and then publish a package to GitHub Packages when a release is created
# For more information see: https://help.github.com/actions/language-and-framework-guides/publishing-nodejs-packages
name: Node.js Package
on:
push:
branches:
- main //推送到main分支触发构建
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: 16
- run: npm i
publish-npm:
needs: build
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: 16
registry-url: https://registry.npmjs.org/
- run: npm publish
env:
NODE_AUTH_TOKEN: ${{secrets.npm}} //刚刚添加的npm的token值(注意这里的secrets.xxx里面的xxx要和上面自定义token名的Name对应上)
-
点击右上角Start commit 保存
-
回到工具库代码,我们删掉package-lock.json这个文件,不然待会GitHub会build失败;
- 记得每次更新要修改下版本号,如果版本号有冲突那么npm发布是会失败的
- 尝试push代码触发自动构建发布
最后
- github链接 整个工具库比较基础,没有用到typescript,单元测试和组件库文档,后续学习了这块知识再来更新啦~~~
- 我还有篇文章介绍入门写react组件库,感兴趣的可以瞄瞄一步步写一个react组件库并打包发布到npm
- 最后分享下我的博客网站,学习react后写的,开源了管理系统及后台WebApi,欢迎查看交流 👉 www.weison-zhong.cn