Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

🐛 [Bug]: ESLint & StyleLint 问题清零 #211

Closed
kagol opened this issue Feb 23, 2022 · 9 comments
Closed

🐛 [Bug]: ESLint & StyleLint 问题清零 #211

kagol opened this issue Feb 23, 2022 · 9 comments
Labels
contribution welcome Welcome PR good first issue Good for newcomers refactoring Refactor code
Milestone

Comments

@kagol
Copy link
Member

kagol commented Feb 23, 2022

2022.4.8 更新

1.0版本范围内40个组件的ESLint问题已全部修复,L0单元测试已全部补齐!🎉🥳


2022.3.31 更新

ESLint和单元测试最新进展如下:

#211 (comment)


2022.3.28 更新

增加 cli 命令进行 eslint 和单元测试自检脚本:code-check

默认检查所有已完成组件的 eslint 和 单元测试:

pnpm cli --filter vue-devui -- code-check

只检查 eslint:

pnpm cli --filter vue-devui -- code-check -t eslint

只检查单元测试:

pnpm cli --filter vue-devui -- code-check -t unit-test

只检查部分组件的 eslint 和 单元测试:

pnpm cli --filter vue-devui -- code-check -c loading,modal

只检查部分组件的 eslint:

pnpm cli --filter vue-devui -- code-check -t eslint -c loading,modal

只检查部分组件的单元测试:

pnpm cli --filter vue-devui -- code-check -t unit-test -c loading,modal

2022.3.15 更新

  • stylelint已全部修复
  • eslint已自动修复部分问题

请田主使用以下命令进行自检,并修复自己组件存在的问题,欢迎在评论区分享修复经验:

./node_modules/.bin/eslint "packages/**/fullscreen/**/{*.ts,*.tsx}"

执行以下命令可以检测存在的eslintstylelint问题,并修复能修复的问题:

pnpm eslint
pnpm stylelint

请大家通过执行以上命令,发现自己负责的组件的问题,并进行修复,修复经验可通过直接回复此issue进行经验的沉淀,供其他田主参考。

@kagol kagol pinned this issue Feb 23, 2022
@kagol kagol changed the title eslint & stylelint 问题清零 ESLint & StyleLint 问题清零 Feb 23, 2022
@kagol kagol added refactoring Refactor code contribution welcome Welcome PR labels Feb 23, 2022
@kagol
Copy link
Member Author

kagol commented Mar 15, 2022

已完成stylelint/eslint问题的自动修复

@kagol
Copy link
Member Author

kagol commented Mar 16, 2022

截止到 commit 5d660db,1.0 版本各组件的单元测试和ESLint情况如下:

请田主们修复自己负责的组件田的单元测试和 ESLint 问题

组件 单元测试 ESLint
Button ✕ 0/7
Fullscreen ✕ 20
Icon ✕ 1
Overlay ✕ 3/9 ✕ 1
Panel ✕ 8
Ripple ✕ 16
Search ✕ 1
Status ✕ 1
Pagination ✕ 11
Alert ✕ 6
Loading ✕ 6
Modal ✕ 0/0 ✕ 5
Notification ✕ 0/0
Popover ✕ 2/9 ✕ 4
ReadTip ✕ 21
Result ✕ 2
AutoComplete ✕ 46
Input ✕ 1
Radio ✕ 2
Slider ✕ 6
Switch ✕ 1 ✕ 1
TagInput ✕ 10
Textarea ✕ 3
Upload ✕ 1 ✕ 23
Avatar ✕ 13
Badge ✕ 1
Card ✕ 1
Comment ✕ 9
Countdown ✕ 1
ImagePreview ✕ 38
Progress ✕ 3
Rate ✕ 4
Skeleton ✕ 8
Statistic ✕ 11
Timeline ✕ 14
Grid ✕ 0/0 ✕ 13
Layout ✕ 0/0 ✕ 6
Splitter ✕ 11/12 ✕ 32

@kagol
Copy link
Member Author

kagol commented Mar 16, 2022

单元测试自检

全量单元测试

pnpm test
Test Suites: 13 failed, 45 passed, 58 total
Tests:       63 failed, 260 passed, 323 total

单个组件单元测试

pnpm test --filter vue-devui -- --testMatch **/button.spec.ts **/fullscreen.spec.ts

ESLint 规范自检

全量 ESLint

pnpm eslint
✖ 1543 problems (799 errors, 744 warnings)
  308 errors and 0 warnings potentially fixable with the `--fix` option.

单个组件 ESLint

./node_modules/.bin/eslint "packages/**/{alert,loading}/**/{*.ts,*.tsx}"

@kagol kagol added the good first issue Good for newcomers label Mar 16, 2022
@kagol kagol added this to the v1.0.0 milestone Mar 18, 2022
@kagol kagol changed the title ESLint & StyleLint 问题清零 🐛 [Bug]: ESLint & StyleLint 问题清零 Mar 18, 2022
@kagol kagol unpinned this issue Mar 19, 2022
@kagol
Copy link
Member Author

kagol commented Mar 24, 2022

ESLint 问题修复案例

案例1:warning Unexpected any. Specify a different type @typescript-eslint/no-explicit-any

该问题出现频率比较高,原因是有些类型写了any,需要明确的类型。

比如Pagination组件的单元测试文件pagination.spec.ts中:

const wrapper = mount({
    components: {
        DPagination
    },
    template: `<d-pagination ... />`
}, globalOption);

const btns = wrapper.findAll('a.devui-pagination-link');

expect(btns.map((ele: any) => ele.text()).join()).toEqual('<,1,...,4,5,6,...,16,>');

其中的ele: any就属于这类问题。

解决办法是给ele加上明确的类型,看逻辑是<button>元素,由于是@vue/test-utils库的包裹元素,因此需要包一层DOMWrapper

import { DOMWrapper } from '@vue/test-utils';

expect(btns.map((ele:  DOMWrapper<Element>) => ele.text()).join()).toEqual('<,1,...,4,5,6,...,16,>');

案例2:'xxx' was used before it was defined no-use-before-define

这也是一个比较常见的问题,在声明之前使用变量或方法,解决办法也很简单,只需要调整下代码的顺序即可,将变量或方法的声明放在调用的语句之前。

比如Pagination组件的pagination.tsx中:

    // 极简模式下,可选的下拉选择页码
    const litePageOptions = computed(() =>  liteSelectOptions(totalPages.value));

    // 当前页码
    const cursor = computed({
      get() {
        // 是否需要修正错误的pageIndex
        if (!props.showTruePageIndex && props.pageIndex > totalPages.value) {
          emit('update:pageIndex', totalPages.value || 1);
          return totalPages.value || 1;
        }
        return props.pageIndex || 1;
      },
      set(val: number) {
        emit('update:pageIndex', val);
      }
    });

    // 总页数
    const totalPages = computed(() => Math.ceil(props.total / props.pageSize));

其中的totalPages的声明在比较靠后的位置,但是却在声明之前在litePageOptionscursor变量中都使用了totalPages,所以提示 ESLint 问题。

解决的方法就是将totalPages的声明放在litePageOptionscursor之前。

    // 总页数
    const totalPages = computed(() => Math.ceil(props.total / props.pageSize));

    // 极简模式下,可选的下拉选择页码
    const litePageOptions = computed(() =>  liteSelectOptions(totalPages.value));

    // 当前页码
    const cursor = computed({ ... });

@kagol
Copy link
Member Author

kagol commented Mar 24, 2022

案例3:warning Missing return type on function @typescript-eslint/explicit-module-boundary-types

该问题是因为函数缺少返回类型,比如Fullscreen组件utils.ts文件的launchImmersiveFullScreen方法中:

export const launchImmersiveFullScreen = async (docElement: any) => {
  let fullscreenLaunch = null;
  if (docElement.requestFullscreen) {
    fullscreenLaunch = docElement.requestFullscreen();
  } else if (docElement.mozRequestFullScreen) {
    fullscreenLaunch = docElement.mozRequestFullScreen();
  } else if (docElement.webkitRequestFullScreen) {
    fullscreenLaunch = Promise.resolve(docElement.webkitRequestFullScreen());
  } else if (docElement.msRequestFullscreen) {
    fullscreenLaunch = Promise.resolve(docElement.msRequestFullscreen());
  }
  return await fullscreenLaunch.then(() => !!document.fullscreenElement);
};

先看下launchImmersiveFullScreen方法的参数问题,docElement用了any,也缺失了返回类型,docElement其实就是document对象,可以使用HTMLElement类型,但是launchImmersiveFullScreen这个方法是用来启动沉浸式全屏的,为了实现浏览器兼容,比如使用了docElement.mozRequestFullScreen兼容火狐,而这些方法在HTMLElement中是没有的,会报TS类型错误,所以需要做一些改造。

interface CompatibleHTMLElement extends HTMLElement {
  mozRequestFullScreen?: () => void;
  webkitRequestFullScreen?: () => void;
  msRequestFullscreen?: () => void;
}

这里定义了一个CompatibleHTMLElement的类型,继承了HTMLElement,并增加了一些自定义的方法。

export const launchImmersiveFullScreen = async (docElement: CompatibleHTMLElement) => {
  ...
}

再来看下launchImmersiveFullScreen方法的返回类型问题。

return await fullscreenLaunch.then(() => !!document.fullscreenElement);

该方法返回了一个Promise对象,它的类型是一个泛型,我们需要传入具体的类型:

export const launchImmersiveFullScreen = async (docElement: CompatibleHTMLElement): Promise<boolean> => {
  ...
  return await fullscreenLaunch.then(() => !!document.fullscreenElement);
};

@kagol
Copy link
Member Author

kagol commented Mar 25, 2022

案例4:'xxx' is already declared in the upper scope @typescript-eslint/no-shadow

这个问题是由于嵌套的作用域中定义了相同的变量名,比如Tree组件的use-checked.ts文件中:

export default function useChecked(...) {
  const onNodeClick = (item: TreeItem) => {
    // 这里定义了 id 变量
    const { id } = item;
    ...
    filter 里面又定义了一个 id 参数
    const currentSelectedItem = flatData.filter(({ id }) => currentSelected[id] && currentSelected[id] !== 'none');
    ...
  }
}

修改方式就是将其中一个 id 的名字改了,比如把里面的 id 改成 itemId:

const currentSelectedItem = flatData.filter(({ id: itemId }) => currentSelected[itemId] && currentSelected[itemId] !== 'none');

@kagol
Copy link
Member Author

kagol commented Mar 31, 2022

2022.3.31 Update

截止到 commit 49e7933ESLint/单元测试进展如下

组件 单元测试 ESLint
Button ✔️
Fullscreen ✔️ ✔️
Icon ✔️ ✔️
Overlay ✔️
Panel ✔️ ✔️
Ripple ✔️ ✔️
Search ✔️
Status ✔️ ✔️
Pagination ✔️
Alert ✔️ ✔️
Loading ✔️ ✔️
Modal
Notification ✔️
Popover ✔️
ReadTip ✔️
Result ✔️ ✔️
AutoComplete ✔️
Input ✔️ ✔️
Radio ✔️ ✔️
Slider ✔️ ✔️
Switch ✔️
TagInput ✔️
Textarea ✔️ ✔️
Upload
Avatar ✔️
Badge ✔️
Card ✔️ ✔️
Comment ✔️
Countdown ✔️ ✔️
ImagePreview ✔️
Progress ✔️
Rate ✔️
Skeleton ✔️ ✔️
Statistic ✔️
Timeline ✔️
Grid ✔️
Layout
Splitter ✔️

@kagol
Copy link
Member Author

kagol commented Apr 1, 2022

2022.4.1 Update

截止到 commit22f5fe1ESLint/单元测试进展如下

组件 单元测试 ESLint
Button ✔️
Fullscreen ✔️ ✔️
Icon ✔️ ✔️
Overlay ✔️
Panel ✔️ ✔️
Ripple ✔️ ✔️
Search ✔️
Status ✔️ ✔️
Pagination ✔️
Alert ✔️ ✔️
Loading ✔️ ✔️
Modal
Notification ✔️
Popover ✔️
ReadTip ✔️
Result ✔️ ✔️
AutoComplete ✔️
Input ✔️ ✔️
Radio ✔️ ✔️
Slider ✔️ ✔️
Switch ✔️
TagInput ✔️
Textarea ✔️ ✔️
Upload
Avatar ✔️
Badge ✔️
Card ✔️ ✔️
Comment ✔️
Countdown ✔️ ✔️
ImagePreview ✔️
Progress ✔️ ✔️
Rate ✔️ ✔️
Skeleton ✔️ ✔️
Statistic ✔️
Timeline ✔️ ✔️
Grid ✔️ ✔️
Layout ✔️
Splitter ✔️ ✔️

@kagol
Copy link
Member Author

kagol commented Apr 8, 2022

2022.4.8 Update

截止到 commit af1d0e1,1.0版本范围内40个组件的ESLint问题已全部修复,L0单元测试已全部补齐!🎉🥳

@kagol kagol closed this as completed Apr 8, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
contribution welcome Welcome PR good first issue Good for newcomers refactoring Refactor code
Projects
None yet
Development

No branches or pull requests

1 participant