Vite项目自动添加eslint prettier源码解读

目录
  • 引言
  • 使用
  • 源码阅读
  • 总结

引言

vite-pretty-lint库是一个为Vite创建的VueReact项目初始化eslintprettier的库。

该库的目的是为了让开发者在创建项目时,不需要手动配置eslintprettier,而是通过vite-pretty-lint库来自动配置。

源码地址:

使用

根据vite-pretty-lint库的README.md,使用该库的只需要执行一行命令即可:

// NPM
npm init vite-pretty-lint
// YARN
yarn create vite-pretty-lint
// PNPM
pnpm init vite-pretty-lint

这里就涉及到了一个知识点,npm init <initializer>yarn create <initializer>pnpm init <initializer>,这三个命令的作用是一样的,都是用来初始化一个项目的。

<initializer>是一个初始化项目的包名,比如vite-pretty-lint就是一个初始化项目的包名;

执行npm init vite-pretty-lint命令后,相当于执行npx create-vite-pretty-lint命令;

这里不多讲解,参考:npm init

源码阅读

打开lib/main.js文件直接看,一开头就看到了下面这段代码:

const projectDirectory = process.cwd();
const eslintFile = path.join(projectDirectory, '.eslintrc.json');
const prettierFile = path.join(projectDirectory, '.prettierrc.json');
const eslintIgnoreFile = path.join(projectDirectory, '.eslintignore');

一看这些名字就知道,这里是用来创建eslintprettier的配置文件的,这里的projectDirectory就是当前项目的根目录。

当然现在这些暂时还没有用到,接着往下走:

async function run() {
    let projectType, packageManager;
    try {
        const answers = await askForProjectType();
        projectType = answers.projectType;
        packageManager = answers.packageManager;
    } catch (error) {
        console.log(chalk.blue('\n Goodbye!'));
        return;
    }
    // 省略后面代码
}

一个run函数,这个就是执行命令的入口函数,可以将代码拉到最低下就知道了。

这里直接看askForProjectType函数,这个函数是通过./utils.js文件来的,进去看看

export function askForProjectType() {
  return enquirer.prompt([
    {
      type: 'select',
      name: 'projectType',
      message: 'What type of project do you have?',
      choices: getOptions(),
    },
    {
      type: 'select',
      name: 'packageManager',
      message: 'What package manager do you use?',
      choices: ['npm', 'yarn', 'pnpm'],
    },
  ]);
}

这里就是通过enquirer库来获取用户的输入,enquirer库是一个命令行交互的库,可以参考:enquirer

这里只有两个问题,一个是项目类型,一个是包管理器,包管理器就是npmyarnpnpm;

项目类型是用过getOptions函数来获取的:

export function getOptions() {
  const OPTIONS = [];
  fs.readdirSync(path.join(__dirname, 'templates')).forEach((template) => {
    const { name } = path.parse(path.join(__dirname, 'templates', template));
    OPTIONS.push(name);
  });
  return OPTIONS;
}

getOptions函数就是获取templates文件夹下的所有文件夹,然后将文件夹名作为选项返回。

回到main.js文件,继续往下看:

const {packages, eslintOverrides} = await import(`./templates/${projectType}.js`);
const packageList = [...commonPackages, ...packages];
const eslintConfigOverrides = [...eslintConfig.overrides, ...eslintOverrides];
const eslint = {...eslintConfig, overrides: eslintConfigOverrides};

当用户回答完问题后,就会根据用户的选择来导入对应的模板文件,比如用户选择了react,那么就会导入./templates/react.js文件。

可以进去templates文件夹里面的文件看看,这里是vue.js文件:

export const packages = ['vue-eslint-parser', 'eslint-plugin-vue'];
export const eslintOverrides = [
  {
    files: ['*.js'],
    extends: ['eslint:recommended', 'plugin:prettier/recommended'],
  },
  {
    files: ['*.vue'],
    parser: 'vue-eslint-parser',
    parserOptions: {
      ecmaVersion: 'latest',
      sourceType: 'module',
    },
    extends: [
      'eslint:recommended',
      'plugin:vue/vue3-recommended',
      'plugin:prettier/recommended',
    ],
    rules: {
      'vue/multi-word-component-names': 'off',
    },
  },
];

这里的packages就是需要安装的包,eslintOverrides就是eslint的配置,这里的配置就是vue项目的eslint配置。

然后下面就是一些合并的配置,都是通过shared.js文件来的:

// shared.js
export const commonPackages = [
  'eslint',
  'prettier',
  'eslint-plugin-prettier',
  'eslint-config-prettier',
  'vite-plugin-eslint',
];
export const eslintConfig = {
  env: {
    browser: true,
    es2021: true,
    node: true,
  },
  overrides: [],
};

继续往下看:

const commandMap = {
    npm: `npm install --save-dev ${packageList.join(' ')}`,
    yarn: `yarn add --dev ${packageList.join(' ')}`,
    pnpm: `pnpm install --save-dev ${packageList.join(' ')}`,
};
const viteConfigFiles = ['vite.config.js', 'vite.config.ts'];
const [viteFile] = viteConfigFiles
    .map((file) => path.join(projectDirectory, file))
    .filter((file) => fs.existsSync(file));
if (!viteFile) {
    console.log(
        chalk.red(
            '\n No vite config file found. Please run this command in a Vite project.\n'
        )
    );
    return;
}

这里就是通过commandMap来获取对应的安装命令;

然后通过viteConfigFiles来获取vite的配置文件;

这里是vite.config.js或者vite.config.ts,然后通过viteFile来判断是否存在vite的配置文件;

没有vite的配置文件就证明不是vite项目,然后程序结束。

继续往下看:

const viteConfig = viteEslint(fs.readFileSync(viteFile, 'utf8'));
const installCommand = commandMap[packageManager];
if (!installCommand) {
    console.log(chalk.red('\n Sorry, we only support npm、yarn and pnpm!'));
    return;
}

这里就是通过viteEslint来获取vite的配置文件,然后通过installCommand来获取对应的安装命令。

vimEslint也是在shared.js文件里面的:

export function viteEslint(code) {
  const ast = babel.parseSync(code, {
    sourceType: 'module',
    comments: false,
  });
  const { program } = ast;
  const importList = program.body
    .filter((body) => {
      return body.type === 'ImportDeclaration';
    })
    .map((body) => {
      delete body.trailingComments;
      return body;
    });
  if (importList.find((body) => body.source.value === 'vite-plugin-eslint')) {
    return code;
  }
  const nonImportList = program.body.filter((body) => {
    return body.type !== 'ImportDeclaration';
  });
  const exportStatement = program.body.find(
    (body) => body.type === 'ExportDefaultDeclaration'
  );
  if (exportStatement.declaration.type === 'CallExpression') {
    const [argument] = exportStatement.declaration.arguments;
    if (argument.type === 'ObjectExpression') {
      const plugin = argument.properties.find(
        ({ key }) => key.name === 'plugins'
      );
      if (plugin) {
        plugin.value.elements.push(eslintPluginCall);
      }
    }
  }
  importList.push(eslintImport);
  importList.push(blankLine);
  program.body = importList.concat(nonImportList);
  ast.program = program;
  return babel.transformFromAstSync(ast, code, { sourceType: 'module' }).code;
}

这里就是通过babel来解析vite的配置文件,然后通过importList来获取import的配置,通过nonImportList来获取非import的配置,通过exportStatement来获取export的配置;

参考:babel

接着往下看:

const spinner = createSpinner('Installing packages...').start();
exec(`${commandMap[packageManager]}`, {cwd: projectDirectory}, (error) => {
    if (error) {
        spinner.error({
            text: chalk.bold.red('Failed to install packages!'),
            mark: '',
        });
        console.error(error);
        return;
    }
    fs.writeFileSync(eslintFile, JSON.stringify(eslint, null, 2));
    fs.writeFileSync(prettierFile, JSON.stringify(prettierConfig, null, 2));
    fs.writeFileSync(eslintIgnoreFile, eslintIgnore.join('\n'));
    fs.writeFileSync(viteFile, viteConfig);
    spinner.success({text: chalk.bold.green('All done! '), mark: ''});
    console.log(
        chalk.bold.cyan('\n Reload your editor to activate the settings!')
    );
});

通过nanospinner来创建一个spinner,参考:nanospinner

通过child_processexec来执行安装命令,参考:child_process

最后安装完成,通过fs来写入对应的配置文件;

总结

通过学习vite-plugin-eslint,我们学习到了在vite项目中如何配置eslintprettier;

并且在这个过程中,我们学习到了如何通过viteplugin来实现对vite的扩展;

还有这个项目的对vite的配置文件的解析,通过babel来解析vite的配置文件,然后通过importList来获取import的配置,通过nonImportList来获取非import的配置,通过exportStatement来获取export的配置;

以上就是Vite项目自动添加eslint prettier源码解读的详细内容,更多关于Vite添加eslint prettier的资料请关注我们其它相关文章!

(0)

相关推荐

  • vite项目添加eslint prettier及husky方法实例

    目录 1. 初始化vite项目 2. 添加eslint 3. 添加 prettier 4. 添加 husky和lint-staged 5. 配置commitlint 1. 初始化vite项目 npm init vite Project name: - vite-project // 项目名称,默认 vite-project Select a framework: › react // 选择框架 Select a variant: › react-ts // 选择组合 2. 添加eslint 安装

  • eslint+prettier统一代码风格的实现方法

    1.实现效果 Eslint校验代码语法,prettier统一格式化代码,按下保存自动修复eslint错误,自动格式化代码. 2.安装vscode插件 Vetur ESLint Prettier - Code formatter 3.配置vscode设置 文件–首选项–设置,打开json模式,添加以下配置: { // 控制工作台中活动栏的可见性. "workbench.activityBar.visible": true, //主题设置 "workbench.colorThem

  • 提高团队代码质量利器ESLint及Prettier详解

    目录 正文 ESLint VUE 项目的规则 Prettier ESLint 与 Prettier 正文 每个开发人员都有独特的代码编写风格和不同的文本编辑器.在团队项目开发过程,不能强迫每个团队成员都写一样的代码风格. 可能会看到以下部分(或全部)内容: 缺少分号: 有单引号.双引号,风格不一致: 一些行之间有大量的空格,而其他行之间没有空格: 在使向右滚动多年以查看其中包含的所有内容的行上运行: 看似随意的缩进: 注释掉代码块: 初始化但未使用的变量: 一些使用“严格”JS 的文件和其他不使

  • React项目配置prettier和eslint的方法

    目录 配置prettier和eslint 配置stylelint 保存自动修复 参考视频: https://www.bilibili.com/video/BV1rh411e7E5?vd_source=eee62ea3954ac01bff9e87e2a7b40084 prettier代码格式化 eslint js语法检查 stylellint css样式检查 配置prettier和eslint 1.初始化React项目 npx create-react-app study_react 2.安装vs

  • vue基础ESLint Prettier配置教程详解

    目录 引言 前言 安装 VsCode 插件 配置 VsCode "Workspace.json" 配置 vue 的 "package.json" 配置 vue 的 ".eslintrc.js" 配置 vue 的 ".prettierrc" 配置 "eslint --fix" 一键修复 配置 ESlint 提交时检测 测试配置效果 问题排查 尾声 引言 VsCode + Vue + ESLint + Pret

  • Vite项目自动添加eslint prettier源码解读

    目录 引言 使用 源码阅读 总结 引言 vite-pretty-lint库是一个为Vite创建的Vue或React项目初始化eslint和prettier的库. 该库的目的是为了让开发者在创建项目时,不需要手动配置eslint和prettier,而是通过vite-pretty-lint库来自动配置. 源码地址: vite-pretty-lint github1s 直接看 使用 根据vite-pretty-lint库的README.md,使用该库的只需要执行一行命令即可: // NPM npm i

  • Evil.js项目源码解读

    目录 引言 源码解析 立即执行函数 为什么要用立即执行函数? includes方法 map方法 filter方法 setTimeout Promise.then JSON.stringify Date.getTime localStorage.getItem 用途 引言 2022年8月18日,一个名叫Evil.js的项目突然走红,README介绍如下: 什么?黑心996公司要让你提桶跑路了? 想在离开前给你们的项目留点小 礼物 ? 偷偷地把本项目引入你们的项目吧,你们的项目会有但不仅限于如下的神

  • Python新建项目自动添加介绍和utf-8编码的方法

    你是不是觉得每次新建项目都要写一次# coding:utf-8,感觉特烦人 呐!懒(fu)人(li)教程来啦,先看效果图吧 中文版 如图进入设置 然后将下列内容粘贴进去就行了,是不是很简单 """ -*- coding:utf-8 -*- Author:${USER} Age:24 Call:199**9**9*9 Email:nsq88@vip.qq.com Time: ${DATE} ${TIHE} Software: ${PRODUCT_NAME} "&quo

  • 我用Python给班主任写了一个自动阅卷脚本(附源码)

    导语 幼儿园升小学,小学升中学,中学升高中.......... 每个人都要经历的九年义务教育:伴随的都是作业.随堂考.以及每个科目的大大小小的考试.当然小编被考试支配的恐惧以及过去了哈~除了学生考试的压力之外. 有调查发现,目前老师大量的时间被小型考试,如课堂测验.周测等高频次测验的批改客观题.计分.登分等占用,被迫压缩了备课.精准辅导的时间. 今天小编带大家做一款解放教师的自动阅卷系统. 几千张的答题卡扫描录入电脑阅卷系统,老师们只需打开电脑登陆,即可找到自己要批改的那道题. 大大提高了改卷效

  • springBoot2.6.2自动装配之注解源码解析

    目录 前言 一.@SpringBootConfiguration 二.@ComponentScan 三.@EnableAutoConfiguration 3.1@AutoConfigurationPackage 3.2 @import 四.按需装配 前言 自动装配的核心即@SpringBootApplication注解中三大注解核心 @SpringBootApplication @SpringBootConfiguration @ComponentScan @EnableAutoConfigur

  • Java HashSet添加 遍历元素源码分析

    目录 HashSet 类图 HashSet 简单说明 HashSet 底层机制说明 模拟数组+链表的结构 HashSet 添加元素底层机制 HashSet 添加元素的底层实现 HashSet 扩容机制 HashSet 添加元素源码 HashSet 遍历元素底层机制 HashSet 遍历元素底层机制 HashSet 遍历元素源码 HashSet 类图 HashSet 简单说明 1.HashSet 实现了 Set 接口 2.HashSet 底层实际上是由 HashMap 实现的 public Has

  • React之echarts-for-react源码解读

    目录 前言 从与原生初始化对比开始 陷阱-默认值height为300px 主逻辑源码剖析 挂载渲染过程 更新渲染过程 卸载过程 项目依赖 后续 前言 在当前工业4.0和智能制造的产业升级浪潮当中,智慧大屏无疑是展示企业IT成果的最有效方式之一.然而其背后怎么能缺少ECharts的身影呢?对于React应用而言,直接使用ECharts并不是最高效且优雅的方式,而echarts-for-react则是针对React应用对ECharts进行轻量封装和增强的工具库. echarts-for-react的

  • Ajax::prototype 源码解读

    AJAX之旅(1):由prototype_1.3.1进入javascript殿堂-类的初探  还是决定冠上ajax的头衔,毕竟很多人会用这个关键词搜索.虽然我认为这只是个炒作的概念,不过不得不承认ajax叫起来要方便多了.所以ajax的意思我就不详细解释了. 写这个教程的起因很简单:经过一段时间的ajax学习,有一些体会,并且越发认识到ajax技术的强大,所以决定记录下来,顺便也是对自己思路的整理.有关这个教程的后续,请关注http://www.x2design.net 前几年,javascri

  • Bootstrap源码解读排版(1)

    源码解读Bootstrap排版 粗体 可以使用<b>和<strong>标签让文本直接加粗. 例如: <p>我在学习<strong>Bootstrap</strong></p> 源码 b, strong { font-weight: bold; } 斜体 使用标签<em>或<i>来实现. 例如: <p>我在学<i>Bootstrap</i>.</p> 强调相关的类

随机推荐