深入解读ahooks

共 5874字,需浏览 12分钟

 ·

2022-02-10 20:45

本文适合对打造工具函数库感兴趣的小伙伴阅读。

欢迎关注前端早茶,与广东靓仔携手共同进阶~

作者:广东靓仔

一、前言

本文基于开源项目:

https://github.com/alibaba/hooks

https://ahooks.js.org/guide/

https://github.com/lerna/lerna

  

    广东靓仔在看ahooks项目代码的时候发现了一些有意思的东西,这里分享下。

二、ahooks是什么

    ahooks是一套高质量可靠的 React Hooks 库
具有以下特性:
  • 易学易用
  • 支持 SSR
  • 对输入输出函数做了特殊处理,且避免闭包问题
  • 包含大量提炼自业务的高级 Hooks

  • 包含丰富的基础 Hooks

  • 使用 TypeScript 构建,提供完整的类型定义文件

安装:
$ npm install --save ahooks
# or
$ yarn add ahooks

使用:

import { useRequest } from 'ahooks';

三、项目目录

 广东靓仔把ahooks的项目代码目录截了个图,如下所示:


看到这个目录,有种亲切的感觉,经过粗略的查看,跟dumi脚手架有点相似,经过求证,确定是使用dumi搭建的。


目录讲解:

+-- config                 // 项目配置
+-- docs                   // 组件库文档目录  
|  +-- guide               // 组件库文档其他路由
|  +-- index.en-US.md      // 组件库文档首页(英文)
|  +-- index.zh-CN.md      // 组件库文档首页(中文)
+-- packages               // lerna包
|  +-- hooks               // 子包hooks
|  +-- use-url-state       // 子包use-url-state
+-- webpack.common.js      // webpack配置文件
+-- gulpfile.js            // 自动化构建工具配置
+-- lerna.json             // 把各个小功能拆分成独立的npm库


看到这里我们先来温习下dumi相关知识。


四、dumi

dumi是为组件开发场景而生的文档工具。

dumi经常与father搭配使用,father 负责构建,而 dumi 负责组件开发及组件文档生成。

安装使用:

$ npx @umijs/create-dumi-lib        # 初始化一个文档模式的组件库开发脚手架
# or
$ yarn create @umijs/dumi-lib

$ npx @umijs/create-dumi-lib --site # 初始化一个站点模式的组件库开发脚手架
# or
$ yarn create @umijs/dumi-lib --site

效果如下:

篇幅有限,这里稍微提下:

1、菜单目录,我们可以通过在config配置navs、menus
2、dumi配置中en-US 是默认语言,如果需要中文创建一个带 zh-CN locale 后缀的同名 Markdown 文件即可。


更多的dumi相关知识可以前往官方文档查看:

https://d.umijs.org/guide

五、hooks

回到ahooks中,从项目目录中可以看到hooks文件是整个工具库的核心

+-- hooks 
|  +-- src               // 子包hooks的源码目录
|  +-- gulpfile.js       // 自动化构建配置
|  +-- package.json      
|  +-- tsconfig.json     // ts配置
|  +-- webpack.config.js // webpack配置
|  +-- yarn.lock         // 锁定版本

在查看源代码的过程中,广东靓仔看到了lodash的影子,推荐一下lodash

下面我们来看看这个hooks具体内容。

tsconfig.json

{
  "extends""../../tsconfig.json",
  "compilerOptions": {
    "rootDir""src"
  }
}

利用extends属性从根目录的tsconfig.json配置文件里继承配置。

compilerOptions指定src文件目录(用于输出),用于控制输出目录结构

webpack.config.js

const merge = require('webpack-merge');
const common = require('../../webpack.common.js');
const path = require('path');

module.exports = merge(common, {
  entry'./es/index.js', // 入口模块的文件相对路径
  output: { // 输出到的目录
    filename'ahooks.js',
    library'ahooks',
    path: path.resolve(__dirname, './dist'),
  },
});

 webpack.common.js 公共配置文件  -- 抽离出公共的部分  通过merge进行合并

代码裁剪下,方便理解:

module.exports = merge(common, config);

webpack.common.js

里面没有什么特殊的,打包的时候,ahooks不想把react打到bundle中,所以使用了如下配置:

 externals: [
    {
      react'React',
    },
  ],

gulpfile.js

const commonConfig = require('../../gulpfile');

exports.default = commonConfig.default;

ahooks使用了gulp自动化构建工具增强工作流程

gulpfile配置

const gulp = require('gulp');
const babel = require('gulp-babel');
const ts = require('gulp-typescript');
const del = require('del');

gulp.task('clean'async function () {
 ...
});

gulp.task('cjs'function () {
   ...
});

gulp.task('es'function () {
   ...
});

gulp.task('declaration'function () {
  ...
});

gulp.task('copyReadme'async function () {
   ...
});
exports.default = gulp.series('clean''cjs''es''declaration''copyReadme');

可以看到使用了gulp的series()clean、cjs、es、declaration、copyReadme组合成更大的操作,然后依次执行

clean里面调用了del类似于rimraf删除当前工作目录

cjs使用gulp-typescript编译 TypeScript 文件流

declaration生成相应的 .d.ts 文件

copyReadme创建一个用于将 hooks文件的元数据对象写入到文件系统的流

lerna.json

ahooks使用了lerna集中了子包在同一个站点中。

Lerna 是一个工具,可以优化使用 git 和 npm 管理多包存储库的工作流程。

广东靓仔把package.json里面关于lerna剪切了下来,如下:

"scripts": {
    "bootstrap""lerna bootstrap",
    "clean""lerna clean --yes",
    "build""lerna run build",
    "pub""yarn run build && lerna publish",
    "pub:beta""yarn run build && lerna publish --dist-tag beta"
  },

Lerna 中的两个主要命令是lerna bootstraplerna publish

bootstrap将 repo 中的依赖项链接在一起。publish将帮助发布任何更新的包。

ahooks的lerna配置如下:

{
  "version""3.1.9",
  "packages": ["packages/*"],
  "npmClient""yarn",
  "command": {
    "version": {
      "allowBranch""master",
      "includeMergedTags"true
    },
    "publish": {
      "message""chore(release): publish",
      "registry""https://registry.npmjs.org/"
    }
  }
}
  • version:存储库的当前版本。

  • packages: 用作包位置的 glob 数组。

  • npmClient:用于指定特定客户端以运行命令的选项(也可以在每个命令的基础上指定)。更改为"yarn"使用 yarn 运行所有命令。默认为“npm”。

  • command.version.allowBranch: lerna version当从除master. 仅限制lerna version在主分支被认为是最佳实践

  • command.version.includeMergedTags: 检测到更改的包时包括来自合并分支的标签

  • command.publish.message:执行版本更新以进行发布时的自定义提交消息

  • command.publish.registry:使用它来设置要发布到的自定义注册表 url 而不是 npmjs.org,如果需要,您必须已经过身份验证。

六、工具函数


export {
  useRequest,
  useControllableValue,
  useDynamicList,
  useVirtualList,
  useResponsive,
  useEventEmitter,
  useLocalStorageState,
  useSessionStorageState,
  useSize,
  configResponsive,
  useUpdateEffect,
  useUpdateLayoutEffect,
  useBoolean,
  useToggle,
  useDocumentVisibility,
  useSelections,
  useThrottle,
  useThrottleFn,
  useThrottleEffect,
  useDebounce,
  useDebounceFn,
  useDebounceEffect,
  usePrevious,
  useMouse,
  useScroll,
  useClickAway,
  useFullscreen,
  useInViewport,
  useKeyPress,
  useEventListener,
  useHover,
  useUnmount,
  useSet,
  useMemoizedFn,
  useMap,
  useCreation,
  useDrag,
  useDrop,
  useMount,
  useCounter,
  useUpdate,
  useTextSelection,
  useEventTarget,
  useHistoryTravel,
  useCookieState,
  useSetState,
  useInterval,
  useWhyDidYouUpdate,
  useTitle,
  useNetwork,
  useTimeout,
  useReactive,
  useFavicon,
  useCountDown,
  useWebSocket,
  useLockFn,
  useUnmountedRef,
  useExternal,
  useSafeState,
  useLatest,
  useIsomorphicLayoutEffect,
  useDeepCompareEffect,
  useAsyncEffect,
  useLongPress,
  useRafState,
  useTrackedEffect,
  usePagination,
  useAntdTable,
  useFusionTable,
  useInfiniteScroll,
  useGetState,
  clearCache,
  useFocusWithin,
};

ahook写了以上工具函数,平时开发过程中自己用到的其实并没有这么多,我们可以封装自己的hooks。

七、总结

    在我们阅读完官方文档后,我们一定会进行更深层次的学习,比如看下框架底层是如何运行的,以及源码的阅读。
    这里广东靓仔给下一些小建议:
  • 在看源码前,我们先去官方文档复习下框架设计理念、源码分层设计
  • 阅读下框架官方开发人员写的相关文章
  • 借助框架的调用栈来进行源码的阅读,通过这个执行流程,我们就完整的对源码进行了一个初步的了解
  • 接下来再对源码执行过程中涉及的所有函数逻辑梳理一遍

关注我,一起携手进阶

欢迎关注前端早茶,与广东靓仔携手共同进阶~

浏览 278
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报