前端通用组件封装的尝试

1,766 阅读4分钟

image.png

前些天发了条沸点, 想讨论下关于多 muti repo情况下的组件复用问题, 但是后感觉还是无果, 这里分享下我自己这两天的成果.

为什么不选择 monoRepo

其实我本人是非常想去尝试 lerna + monoRepo 的方式去规划现有项目的, 奈何项目中有一部分项目后期可能会放出源码买断这种情况, 所以 monoRepo 在最开始就被部门老大摁在地上.

MutiRepo

首先说一下我一开始的设想, 现在手上有两个项目, 都是用 React 开发的, 其中一个项目从去年年底开始一点点做出来, 中间跟UI来回商讨, 已经抽出来很多可以直接拿来就用的通用组件了, 组件本身并不牵扯到业务逻辑, 所以移植到另一个项目中直接使用也是可以的, 但是同样一份代码在两个项目之间来回 C/V 有时候稍不留神就有可能出错,那么为什么不做成 npm package呢? 这个想法也是有的, 但是目前来看, 如果每次修改一点点内容都要经历一下几个步骤:

  1. yarn build
  2. git bulabula
  3. npm publish 然后经过漫长的等待, 再去更新到自己的项目中, 时间上太过于浪费了, 当然了兄弟们有什么更骚的操作希望能指出来.

最终选择使用的方案是 git submodule, 也就是将一个 git 仓库作为另一个项目的子项目, git分支互不冲突, 刚好满足我所设想的需求. 接下来简短的描述下过程之后我再说一下我现在遇到的问题. 其实在选择 git submodule 之前我还想通过将 git 作为依赖的方式安装到项目中去, 这样的话好像抽离出来了, 但是本地开发组件库又成了一个问题. 所以最终还是选择了 git submodule 这种方式.

配置过程

  1. 在需要添加依赖的项目中初始化 git submodule , ie: 在 OSAP-SSP 中运行git submodule add git@myPersonalGitRepo/CommonUI.git , 之后这个模块就被添加到当前项目中了, 并且还存在一个 .gitmodule 文件, 里面应该是这样的
[submodule "CommonUI"]
	path = CommonUI
	url = git@myPersonalGitRepo/CommonUI.git
  1. 子模块创建成功之后就需要配置 webpack, 把这个子模块当作当前项目的一部分使用, 只需要在主项目中添加新的 entry 和修改 alias 即可
{
    ...webpackConfig,
    entry: {
        index: resolve('src/index.tsx'),
+       CommonUI: resolve('CommonUI/src/index.ts'),
    },
    resolve: {
        alias:{
-           '@Common/UI': resolve('src/common/Commponents/Layout'),
+           '@Common/UI': resolve('CommonUI/src'),
        }
    }
}
  1. 经过上面两步之后, webpack 在不做 tscheck 的情况下是完全可以正常运行的, 但是我们使用的是 typescript , 下面还需要修改 tsconfig 文件 在主项目中的 tsconfig 文件中
{
    "compilerOptions": {
        ....
        "paths": {
-           "@Common/UI": ["/src/common/Components/Layout"],
+           "@Common/UI": ["CommonUI/src"],
        }
    },
-   "include": ["src/**/*", "typings"]
+   "include": ["src/**/*", "typings", "CommonUI"]
}

在子项目(sub-module)的 tsconfig 中

+ {
+     "extends": "../tsconfig.json",
+     "include": ["src/**/*"]
+ }
  1. 这时候在本地运行 yarn serve 项目应该就可以跑起来了, 虽然 submodule 中存在依赖@Common/Util 但是由于在主项目中配置了 alias , 所以并不会出现文件找不到的报错.

至此, 在 submodule 中如果不去安装任何npm package , 那么在运行 webpack 的时候并不会报错, 项目是完全正常运行的, (除了这个 CommonUI 会被打包成一个文件导致加载时间猛增😢), 其他的效果和之前一模一样. VSCode , 虽然都告诉我找不到模块了

image.png

但是看一眼 console 竟然没有任何报错???

image.png

得这个是可以假装看不见的, 反正 work 了就行呗, 然后当我在 submodule 安装 husky 等基本依赖的时候, 问题出现了, 主项目的webpack开始疯狂报错

Type '{ onChange: (e: any) => void; type: string; checked: boolean; className: string; form?: string | undefined; slot?: string | undefined; style?: CSSProperties | 
undefined; title?: string | undefined; ... 274 more ...; step?: string | ... 1 more ... | undefined; }' is not assignable to type 'DetailedHTMLProps<InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>'.
  Type '{ onChange: (e: any) => void; type: string; checked: boolean; className: string; form?: string | undefined; slot?: string | undefined; style?: CSSProperties | undefined; title?: string | undefined; ... 274 more ...; step?: string | ... 1 more ... | undefined; }' is not assignable to type 'InputHTMLAttributes<HTMLInputElement>'.
    Types of property 'style' are incompatible.
      Type 'import("MainProject/CommonUI/node_modules/@types/react/index").CSSProperties | undefined' is not assignable to type 'React.CSSProperties | undefined'.

这个问题竟然还是 ForkTSChecker 的原因, 然后我赶紧去他们的 github 上看看文档有没有什么可配置的需要调整, 然后我看到这样的一句描述

It's very important to be aware that this plugin uses TypeScript's, not webpack's modules resolution. It means that you have to setup tsconfig.json correctly.

虽然官方说的是 module 需要配置好, 但是我觉得肯定还有别的什么地方需要我去修改, 其实说到底还是 tsconfig 的原因, 未完待续...