2

vite不能选配方案?vite-creater强势来袭! - 加伊bky

 1 year ago
source link: https://www.cnblogs.com/Kay-Larry/p/17362007.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

我正在参加「掘金·启航计划」

vite出现之后,迅速带走了一大波webpack的使用者,即使是对打包工具不熟悉的小白,也能很快感受到两者的区别——vite快的多!

vite官方文档第一句也是讲述其名字的由来 Vite (法语意为 "快速的") ,其logo也与其名字一样,处处都透露着一个字,那就是快!

但是习惯了vue-cli的同学(我),对于一个不能保存模板策略的工具,是无法忍受的,它居然每次都需要我选择模板、选择用js还是ts,这是让人无法忍受的。当然,vite官方还提供了社区维护的模板 即

image-20230428111113806

awesome-vite ,同学可点击链接感受一下这些模板,不能说我们小白用不到吧,可以说是完全不认识。

为此,"好东西" vite-creater 诞生了 github源码 👉 点击走你

什么是vite-creater?

vite-creater是vite的一个前置的自动化cli程序,它可以按照用户自定义的流程全自动的创建项目,并安装依赖,当vite-creater提示完成时,你就可以直接npm run了!它调用的是npm create vite,除了选择框架外,其余的一切操作都不需要你动手,你只需预设一个策略即可!

我需要vite-creater吗?

如果你是一个熟练的vue玩家,我猜你可能需要它,它可以像vue-cli一样,储存一个自己的选配策略,它甚至支持你包含自定义的第三方库。

如果你还不了解vite,或者你希望使用vite原汁原味的功能,你可能不需要vite-creater,不过欢迎你使用,vite-creater会随着vite的更新而更新!

使用vite-creater

安装vite-creater

npm i vite-creater -g
vcreater init <yourProjectName>

vite-creater内置了一个贴心的选配策略:

image-20230428112459247

这也是目前应用最多的,开发起来最容易的一套策略,在此直接回车,你会直接一键生成项目

image-20230428112853574

如果你不喜欢,或者你需要更多的东西,可以点击 "点击进入自定义流程"

自定义选配

vite-creater会问询一系列常用套件,包括:css预处理器、使用js还是ts、是否使用vue-router、使用vuex还是pinia

(vite-creater目前版本只支持 问询vue常用包,如需其他框架,可以全选择no,然后在自定义第三方包中添加你的框架需要的包即可)

最后,vite-creater会问你,是否需要其他的第三方包,比如我们需要使用 超好用的大屏自适应工具 vue-autofit ,我们就输入vue-autofit

image-20230428113321682

最后,可以选择将此选配方案保存,你可以选择给它取一个名字,当然也可以不取,因为vite-creater会在预设方案列表中展示所有依赖名称和使用的语言。

如果vite-creater要求你选择框架,你可以根据自己的需要选择你的框架:

image-20230428113518967

当选择完框架后,即可快速完成项目创建了!并且已经下载了你的自定义包。

image-20230428113553834
image-20230428115522189

使用保存的选配方案

image-20230428115850797

当你创建过一个方案并选择了保存后,工具会在下次使用时向你展示你保存的选配方案,直接选择即可一键生成项目,不用再重复选配过程。

vite-creater是怎么实现的?

vite-creater是node编写的。

调用Node编写的cli程序,必须在node环境下才可以运行,因为node的cli实际上是由node代理执行的,即V8引擎去解析和执行的,当我们全局安装了一个node cli程序时,node会自动把其命令加载到环境变量中,当我们的JS代码被执行时,是node在与操作系统交互。所以,我们不需要了解它具体的运行原理,我们只需要知道JS怎么写就可以了。

开发所需的库

"commander": "^10.0.1" 可以执行dos命令

"inquirer": "^9.2.0" 交互式输出工具,提供问询式命令行交互会用到

"configstore": "^6.0.0" 本地存储,相当于是cookie或者localStorage,用来储存用户保存的选配

使用npm 初始化项目
npm init

需要输入项目基本信息,此步骤会初始化一个标准的Npm包,并生成一个package.json ,

注意如果希望发布到npm,应该先在npm官网查看是否有相同或相似的包名,有的话是发布不了的,需要取一个标新立异的包名,或者就需要带上@userName/的前缀

使用commander库初始化命令
import { program } from 'commander';
program
  .version('1.0.0')
  .description(`vite-creater是一款用于快速创建vite项目的脚手架工具`);

program
  .command('init <projectName>')
  .description('使用vite-creater创建项目')
  .option('-p, --projectName <string>', 'project name')
  .action(async (initProjectName) => {
    await askForOptions(initProjectName) //这里调用我们的自定义问询函数
  });
program.parse(process.argv);

在node开发的cli中,可以使用async/await来阻塞程序,以等待步骤完成或者用户输入。

使用inquirer创建交互式问询输出
import inquirer from 'inquirer';

let preSetRules = [
    {
      name: 'selectRule',
      type: 'list',
      message: '选择一个预设规则,或者进入自定义流程',
      choices: preSetRulesList, //这是一个数组,仅可包含字符串,如["item1","item2"]
    }
  ]
 let isPreSetRules = await inquirer.prompt(preSetRules)

当如上代码被执行时,将会输出一个可以通过上下箭头键选择的列表(list)

使用configstore 储存用户的选配方案
import Configstore from 'configstore';
const conf = new Configstore('vite-creater');
conf.set("customRulesList", customRulesList); //新建或修改 参数:键名,数据
let customRulesList = conf.get('customRulesList');

其中customRulesList 可以是数组或者对象,当然也可以是字符串等,你可以把configstore 完全当作cookie来使用。

使用child_process创建子进程

这是一个node内置的库,允许开发者创建一个子进程,并与子进程通讯

import { exec } from 'child_process';
function execCreateTs(command) {
  console.log('exec:', command);
  return new Promise((resolve, reject) => {
    const child = exec(command, (err, stdout, stderr) => {
      if (err) {
        console.log('err::: ', err);
        reject(err)
      }
    })
    child.stdout.on('data', async data => { //监听子进程的输出
      if (data.includes('Package name')) {
        process.stdout.write('\x1b[32m' + data + '\x1b[0m');
        child.stdin.write('\n');
      }
      if (data.includes('Vue')) {
        process.stdout.write('\x1b[2J\x1b[0f');
        process.stdout.write('\x1b[32m' + data + '\x1b[0m');
        clearAnimation()
        selectFramework(child)
      }
      if (data.includes('TypeScript')) {
        process.stdout.write('\x1b[32m' + data + '\x1b[0m');
        process.stdout.write('\x1b[2J\x1b[0f');
        child.stdin.write('\n');
        resolve(child.stdout)
      }
      if (data.includes('is not empty')) {
        // 退出进程
        console.log('\n\x1b[31m×\x1b[0m 目录已存在');
        process.exit();
      }
    })
  })
}

上述代码由vite-creater创建ts项目为例,参数command即可以是任何dos命令。下面的if来查询子进程的输出中包含的字符,以此来确定子进程进行到哪一步了(我不知道这么做是不是符合规范的,不过开发的时候我想到了这个办法。)

细心的同学注意到了selectFramework()方法,这个方法是在子进程中出现了Vue字符时,我们判定vite进入了框架选择步骤,于是我们将子进程的输出展示到主进程中,也就是上面提到的框架选择页面

selectFramework方法代码如下:

async function waitUserPresskey() {
  // 返回一个promise对象
  return await new Promise((resolve, reject) => {
    process.stdin.setRawMode(true);
    process.stdin.resume();
    process.stdin.on('data', (key) => {
      key = key.toString('ascii'); //需要转为ascii码
      resolve(key)
    });
  });
}
async function selectFramework(child) {
  let input = await waitUserPresskey();
  // 如果按下ctrl+c,退出进程
  if (input === '\u0003') {
    process.exit();
  }
  child.stdin.write(input); // 向子进程转发命令
}

当调用它时,程序会等待一个用户输入,然后直接转发到子进程中,当子进程再次输出其他信息时,又会回到我们上面的监听,于是,只要用户还没有选定框架,vite会一直处在框架选择页面,也就是还包含Vue字符,所以会再次进入selectFramework函数,这样就完成了一个递归问询,直到用户选择了框架。

全自动化流程实现

当完成上述步骤之后,我们已经可以看到vite+vue的项目已经创建完成了,这时就已经完成了vite官方工具所做的,一般来说,我们需要进入该文件夹,然后执行npm i ,然后安装我们需要的包 npm i ....

根据上面的学习,我们理所当然的可以将这一步收纳进自动化的范畴,只需执行两条简单的dos命令即可。

    await execNpmInstall('npm i')
    await execNpmInstall(installCommand)
function execNpmInstall(command) {
  console.log('exec:', command);
  return new Promise((resolve, reject) => {
    const child = exec(command, (err, stdout, stderr) => {
      if (err) {
        reject(err)
      }
    })
    child.stdout.on('data', async data => {
      // 当npm i 完成时
      if (data.includes('packages in')) {
        console.log('\n', data);
        resolve(child.stdout)
      }
    })
  })
}

如果我们需要安装 之前用户储存的第三方库,只需要使用使用conf.get('xxx');去获取数据,然后传入该函数即可。

上面简述了vite-creater的开发过程,至此,我们就可以整理所有的功能,打包发布了,在本地登录自己的npm账号后,使用npm publish命令即可发布。

查看 vite-creater 的 npm主页

本项目已在 github开源 github源码 👉 点击走你

懦弱之举,我决不姑息!


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK