React进阶之前端业务Hooks库(一)

发布于:2025-02-21 ⋅ 阅读:(25) ⋅ 点赞:(0)

初始化安装和打包
pnpm run init
启动本地doc
pnpm run dev
针对文档站的打包,会成一个dist
pnpm run build:doc

项目结构

中间生成的文件:

  • .umi 本地dev启动的能力
  • .umi-production 要打包的内容

其他文件

  • dist 打包后的产物

项目初始化过程中,依赖了编码项目工程化,encode-fe-lint,初始化了代码的规范,做到了一个脚手架cli的能力
例如:

  1. 创建demo

pnpm init

  1. 安装包

npx encode-fe-lint -h

走到了cli的能力中

  1. 初始化

npx encode-fe-lint init

  1. 选择
    在这里插入图片描述
    安装好后,就会注入这两个能力
    scan:代码扫描
    fix:代码修复
    在这里插入图片描述
    • .vscode
      • settings.json:初始化会把定义的规范和内容通过eslint插件能力告诉用户可以基于这部分安装
        在这里插入图片描述
        将这些都配置好

这个encode-fe-lint插件的思路:
根目录下创建encode-fe-lint.config.js文件:指定的文件目录读取的功能

再回到项目目录上:

  • config 借助dumi的配置,存放的是配置文件
    • config.ts 配置化表达路由,表达文档功能
      • extraBabelPlugins:
        • babel-plugin-import:dumi基于webpack来做的,编辑器使用的是babel做的
          • libraryName: ‘@alifd/next’,主题包使用的是阿里系的alifd/next
        • fusion
      • alias:别名,之后要在doc文档中,文档站中创建demo需要从encodeHooks中取,需要从alias目录指向去引
      • resolve:文档站要读取文档内容包含的信息是什么
      • links:刚使用@alifd/next导出主题包,这里可以通过cdn的方式引入主题包
      • navs 对应的导航栏
      • menus 对应的菜单

搭建站点:
react 用的是 dumi 来搭建,初始化配置 dumi config
Vue就是vuePress,针对vue2场景下用到的,像vue-cli这个网站就是用的vuePress来做的
vite使用的是vitePress搭建站点的
国外:React做的更多一些,dumi,docusaurs做站点

  • tsconfig.json
    • encodeHooks/encode-hooks 使用tspath,在这里定义,方便对应的文档站,方便这部分代码入口保持一致
  • docs:
    • index.md 官网的模板,markdown的形式展示文档的内容
    • guide
      • index.md 一些说明,测试的使用
  • packages
    • hooks 在实际的开发中,hook只是提供了一部分的内容,除了hooks还有components,utils,plugins,apis等这些都能做导出的方法去引用
  • public 头部信息,logo图片等静态资源
  • .babelrc 使用babel作react代码运行环境,
    • “presets”: [[“@babel/env”], “@babel/react”] 通过这个可以运行react代码了,babel是一个树状的结构
  • gulpfile.js 打包工具,通过gulp和webpack分别实现commonJS和esmodule以及对应的umd的效果
  • jest.config.js 单测的配置能力,通过jest方式在整个应用中运行的一个测试,运行pnpm run test
    • transform:针对.tsx文件都会经过ts-jest和tsconfig来解析
  • jest.setup.js:会在初始化的时候加入,针对HTMLElement整个类型上注入了全屏相关的方法
  • package.json
    • preinstall:限制pnpm安装 或者在 packageManager 限制pnpm版本
    • init:安装依赖并且执行build打包
    • build:pnpm的方式,因为是monorepo的项目,通过外部统一管理包的方式,其实执行的是packages包下的每个包中packages.json的build指令 pnpm -r 递归
    • dev:dumi的dev
    • clean-dist: rimraf包能够删除当前 packages 的hooks下的dist,es,lib,node_modules这些
    • test:执行的是jest,pnpm run test
    • coveralls:单测覆盖率,走的是jest.config.js文件,从单测配置文件中读取,collectCoverageFrom这个配置覆盖的文件
    • pub:发包,打包好后进行单个包的publish,
    • pub:beta 发布beta包打上tag标识
    • files:最终发布在docs中的内容
    • encode-fe-lint-scan
    • encode-fe-lint-fix:通过encode-fe-lint工具自定义注入到scripts中
  • pnpm-workspace.yml:可以看出是monorepo多包管理工具,有时候也会这样写:packages: - ‘apps/*',就在packages下或者apps下目录进行多个包的工具的管理
  • tsconfig.json:jsx:react环境,target:最后生成es5代码,exclude:过滤无用的内容
  • tsconfig.pro.json:tsconfig做根目录,它就能做子应用通过extends去注入,这里是把exclude注入到tsconfig.json文件中,并且对tsconfig.json文件进行覆盖
  • webpack.common.js:打包成umd,产物内容是production生产环境的内容,将react剔除出去当作外部的包的方式去引用

实现useToggle

先弄清这两点:

  1. 自定义hooks该实现的能力是什么
  2. 如何去打包构建,怎样进行自定义指令hook的封装

请添加图片描述

  • packages
    • hooks
      • src
        • useToggle
          • index.ts 完整代码的入口
          • index.md 作为dumi消费的内容,这里通过 <code>引用到对应的demo
          • demo 引用的例子
          • _test_ 对应的单测
      • package.json:files:最终发到npm包上的内容

useToggle切换

  1. useToggle() default params to false,不传参则置为false
  2. useToggle(a,b)

useToggle/index.ts

import {
    useState, useMemo } from 'react';

export interface Action<T>{
   
    setLeft: () => void,
    setRight: () => void,
    set: (value: T) => void,    
    toggle: () => void
}

// 1. useToggle() default params to false,不传参则置为false
function useToggle<T=boolean>():[boolean,Action<T>]

// 2. useToggle(a) 有一个参数的情况
function useToggle<T>(defaultValue:T):[T,Action<T>]

// 2. useToggle(a,b) 有两个参数的情况
function useToggle<T,U>(defaultValue:T,reverseValue:U):[T|U,Action<T|U>]

function useToggle<D, R>(defaultValue = false as D, reverseValue?: R) {
   
    const [state, setState] = useState<D | R>(defaultValue);
    
    const actions = useMemo(() => {
   
        const reverseValueOrigin = reverseValue ? reverseValue : !defaultValue as D | R;; 

        const setLeft = () => setState(defaultValue);
        const setRight = () => setState(reverseValueOrigin);
        const set = (value: D | R) => setState(value);
        const toggle = () => setState((s) => (s === defaultValue ? reverseValueOrigin : defaultValue));


        return {
   
            setLeft,
            setRight,
            set,
            toggle
        }
    }, []);


    return [state, actions]
}

单测

packages/hooks/src/_test_/index.test.ts
import * as

网站公告

今日签到

点亮在社区的每一天
去签到