观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 进行检查

总结

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

相关推荐
字节跳动开源43 分钟前
火山引擎开源 Agent 驱动的搜索自迭代技术
数据库·开源·agent
码哥字节3 小时前
0元搭了240篇文章的AI知识库,比付费版查得更准
开源·ai编程·mcp
维基框架5 小时前
GitHub重构漏洞赏金计划 向AI批量报告说不
人工智能·重构·github
咖啡星人k5 小时前
【无标题】
前端·ai·github
逛逛GitHub5 小时前
本周 TOP 17 排名的 GitHub 开源项目大盘点,第一个值得收藏。
github
山林竹笋5 小时前
人工智能领域开源TOP20(2026.06.22-2026.06.28)
人工智能·开源·大模型·智能体·技术趋势
DogDaoDao7 小时前
OpenBrowser 深度解析:让 AI 真正「用上」浏览器的自主代理框架
人工智能·程序员·大模型·github·web·ai工具·openbrowser
Black_Rock_br8 小时前
打通 PyTorch Monarch 与 ROCm:单 Controller 架构的异构算力实战
人工智能·pytorch·python·开源
晚来的棠棠10 小时前
彻底解决 github 无法访问或者访问慢的问题_github打开太慢了
github
在线梦游10 小时前
百度网盘不限速下载教程(最新版):免费提速方法+直链解析工具推荐
开源