观Bun 1.0有感之实现前端检查器集成eslint配置+jest和mocha自动化测试

观Bun 1.0有感之实现前端检查器集成eslint配置+jest和mocha自动化测试

近期,前端运行时 Bun 1.0 正式发布。在相关的话题文章中,我看到这么一段话

  • "Bun 不仅是一个专注性能与开发者体验的全新 JavaScript 运行时,还是一个快速的、全能的工具包,可用于运行、构建、测试和调试JavaScript和TypeScript代码,无论是单个文件还是完整的全栈应用"。*

是不是一开始就觉得这好像这是一个很厉害的东西,确实,我当时被这句话中 "全能" 所吸引,因为我也在开发自己的一个脚手架,一个功能强大,拓展性强的脚手架一直是我的追求。我被Bun 1.0中的测试运行器所吸引,它内置了一个测试模块,且与Jest完全兼容。我的想法也油然而生:

  • 在我的脚手架上实现一个前端检查器,集成eslint语法检查+jest和mocha自动化测试

为什么要实现前端检查器

  • 对团队代码规范实施统一管控,不同项目会维护不同的lint规范,无法实施统一管控
  • 可以用于代码提交前对项目进行集中管控,对不符合规范的项目进行拦截
  • 实现自动化测试的自动识别和执行,避免手动执行

在开发中,其实我们每个项目通常都会去配置一个eslint配置文件,这样子不同的项目配置文件存在着一些差异,不能实现团队项目的统一管控。而我所实现的前端检查器主要的一个任务就是不需要的项目中去创建eslint配置,而是通过脚手架去维护一个eslint配置,并用这套配置对代码进行检查。对于实现jest和mocha自动化测试,希望项目中不配置自动化测试工具也能通过脚手架去进行自动化测试

如何实现前端检查器

  • eslint配置 + API调用
  • jest 和 mocha自动化测试

说明

这个脚手架是我之前就开始做的,使用的技术栈是 lernacommandegg.jsmongodb,在实现前端检查器之前已经实现了可使用 t-tsheep init下载vue3、react18、vue-element-admin 三种模板和实现了t-tsheep install命令拉取github和gitee远程仓库并下载项目及项目依赖两个功能,仓库地址:github.com/luo29/tshee... 。后续可能会写从零开始搭建脚手架并实现这些功能的文章。

功能实现

  • 终端创建 lint 分包
arduino 复制代码
// 终端
lerna create lint packages/
  • 代码架构实现
js 复制代码
// packages/lint/lib/index.js
import path from "node:path";
import Command from "@tsheep.com/command";
import { log, makeList, printErrorLog } from "@tsheep.com/utils";
import { ESLint } from "eslint";
import { execa } from "execa";
import ora from "ora";
import jest from "jest";
import Mocha, { test } from "mocha";
import vueConfig from "./eslint/vueConfig.js";

/**
 * examples:
 * t-tsheep lint
 */
class LintCommand extends Command {
  get command() {
    return "lint";
  }
  get description() {
    return "lint project";
  }
  get options() {
    return [];
  }
  extractESlint(resultText, type) {
    const problems = /[0-9]+ problems/;
    const warnings = /([0-9]+) warnings/;
    const errors = /([0-9]+) errors/;
    switch (type) {
      case "problems":
        return resultText.match(problems)[0].match(/[0-9]+/)[0];
      case "warnings":
        return resultText.match(warnings)[0].match(/[0-9]+/)[0];
      case "errors":
        return resultText.match(errors)[0].match(/[0-9]+/)[0];
      default:
        return null;
    }
  }

  parseESlintResult(resultText) {
    const problems = this.extractESlint(resultText, "problems");
    const errors = this.extractESlint(resultText, "errors");
    const warnings = this.extractESlint(resultText, "warnings");
    return {
      problems: +problems || 0,
      errors: +errors || 0,
      warnings: +warnings || 0,
    };
  }

  async action() {
    // 1.eslint
    await this.eslintAction();
    const testMode = await makeList({
      choices: [
        { name: "jest", value: "jest" },
        { name: "mocha", value: "mocha" },
      ],
      message: "请选择测试模型",
    });
    if (testMode === "jest") {
      // 2.jest
      await this.jestAction();
    } else {
      // 3.mocha
      await this.mochaAction();
    }
  }

  async eslintAction() {
    log.verbose("lint");
    const spinner = ora("正在安装ESlint相关依赖").start();
    try {
      await execa("npm", ["install", "-D", "eslint-plugin-vue"]);
      await execa("npm", ["install", "-D", "eslint-config-airbnb-base"]);
    } catch (e) {
      printErrorLog(e);
    } finally {
      spinner.stop();
    }
    log.info("正在进行eslint检查");
    // 执行工作,eslint
    const cwd = process.cwd();
    const eslint = new ESLint({ cwd, overrideConfig: vueConfig });
    const results = await eslint.lintFiles(["./src/**/*.js", "./src/**/*.vue"]);
    const formatter = await eslint.loadFormatter("stylish");
    const resultText = formatter.format(results);
    const eslintResult = this.parseESlintResult(resultText);
    log.verbose("eslintResult", eslintResult);
    log.success(
      "eslint检查完毕",
      "错误:" + eslintResult.errors,
      ",警告:" + eslintResult.warnings
    );
  }

  async jestAction() {
    log.info("自动执行jest测试");
    await jest.run("test");
    log.success("jest测试执行成功");
  }

  async mochaAction() {
    const cwd = process.cwd();
    log.info("自动执行mocha测试");
    const mochaInstance = new Mocha();
    mochaInstance.addFile(path.resolve(cwd, "__tests__/mocha_test.js"));
    mochaInstance.run(() => {
      log.success("mocha测试执行完毕");
    });
  }
}
function Lint(instance) {
  return new LintCommand(instance);
}
export default Lint;
  • eslint配置
js 复制代码
// packages/lib/eslint/Vueconfig.js
export default {
  env: {
    browser: true,
    es2021: true,
  },
  extends: ["plugin:vue/vue3-essential", "airbnb-base"],
  overrides: [],
  parserOptions: {
    ecmaVersion: "latest",
    sourceType: "module",
  },
  plugins: ["vue"],
  rules: {},
};

这是配置的vue模板eslint检查,在这里也可以根据项目所需的eslint检查进行配置

实现效果

  • 创建一个vue项目进行测试
  • 执行t-tsheep lint 进行检查

总结

这就是从遐想到构建又到实现的一路"砍瓜切菜"。因为这次只展现了实现的代码和结果,全部代码在上面提到的仓库里面。后续我也可能会写一个从零实现这个脚手架的专栏。

相关推荐
_tison1 小时前
夜天之书 #103 开源嘉年华纪实
开源
customer081 小时前
【开源免费】基于SpringBoot+Vue.JS周边产品销售网站(JAVA毕业设计)
java·vue.js·spring boot·后端·spring cloud·java-ee·开源
非著名程序员7 小时前
腾讯为什么支持开源?
开源
CSDN云计算7 小时前
如何以开源加速AI企业落地,红帽带来新解法
人工智能·开源·openshift·红帽·instructlab
customer089 小时前
【开源免费】基于SpringBoot+Vue.JS医院管理系统(JAVA毕业设计)
java·vue.js·spring boot·后端·spring cloud·开源·intellij-idea
王解10 小时前
Jest项目实战(4):将工具库顺利迁移到GitHub的完整指南
单元测试·github
油泼辣子多加10 小时前
2024年11月4日Github流行趋势
github
梓羽玩Python12 小时前
推荐一款用了5年的全能下载神器:Motrix!全平台支持,不限速下载网盘文件就靠它!
程序员·开源·github
逆天的蝈蝈12 小时前
开源与商业的碰撞TPFLOW与Gadmin低代码的商业合作
低代码·开源