写点什么

实战一个自己用的 node-cli

  • 2023-07-04
    福建
  • 本文字数:2980 字

    阅读完需:约 10 分钟

实战一个自己用的node-cli

我们都用过 vue 的 cli ,或者 react 的 cli, 亦或是其他的 cli 如 vite 等。他们都是提供了一个全局命令,然后在终端执行这个全局命令就可以创建出模板项目。今天我们就自己做一个,给自己用的脚手架项目,帮助自己开发一些项目。


现在我们来造点需求。


背景:我们要在 nextjs 项目中,添加页面路由,用过 nextjs 的同学应该知道,这个 pages 下面的文件就是页面路由。我们一般添加页面都在 pages 文件夹下新建文件 ,有时候还会在 pages 同级文件夹下新建 components 文件夹,来放我们页面的组件。


要求:

  1. 可以单独创建一个页面路由

  2. 如果页面复杂,那我需要在 pages 同级目录下创建一个 components 文件夹下创建同名的组件文件夹

  3. 可以控制是否生成 style 文件

  

分析:我们回忆下 @vue/cli 这样的脚手架是如何使用的

npm install -g @vue/cli
vue create my-project
复制代码


全局安装之后 开始使用这个全局命名。


那么我们就按照这个思路倒着打。


因此我们也需要搞一个全局命令,然后执行我们全局命令后,就可以执行我们想要的动作,创建文件夹,写文件等。


  1. 创建空项目,next-project-add-page

  2. npm init 

  3. 修改 package.json, 添加 bin 字段

  4. 本地调试,先生成软连接 来让我们可以使用 next-add-page 命名, npm  link 

  5. 核心代码编写


{  "name": "next-project-add-page",  "version": "1.0.0",  "description": "",  "main": "index.js",  "scripts": {    "test": "echo \"Error: no test specified\" && exit 1"  },  "bin": {    "next-add-page": "index.js"  },  "author": "",  "license": "ISC",  "dependencies": {    "commander": "^10.0.0"  }}
复制代码

先上一个能走完大概流程的核心代码,里面一些细节的代码逻辑,我们后面再补充。

// index.js// console.log(process.argv)// [//     'C:\\Program Files\\nodejs\\node.exe',//     'C:\\Users\\Administrator\\AppData\\Roaming\\npm\\node_modules\\next-project-add-page\\index.js',//     'add', // 想要执行的命令//     'list', // 新增的页面//     '-components', // 是否添加到pages同级的components 文件夹下为 组件//     '-style', // 是否添加样式文件// ]const { program } = require('commander');const child_process = require('child_process');const { clearInterval } = require('timers');const fs = require('fs');const path = require('path');program  .option('-components')  .option('-style');
program.parse();console.log(program.opts()) // { Components: true, Style: true }
;

function intervalProgress() { const readline = require('readline'); const unloadChar='-'; const loadedChar='=';
let i = 0; let time = setInterval(()=>{ if(i>10){ clearInterval(time); console.log(`创建完成,请查收`); process.exit(0); } readline.cursorTo(process.stdout,0,1); readline.clearScreenDown(process.stdout); renderProgress('文件创建中',i); i++; },200);
function renderProgress(text,step){ const PERCENT = Math.round(step*10); const COUNT = 2; const unloadStr = new Array(COUNT*(10-step)).fill(unloadChar).join(''); const loadedStr = new Array(COUNT*(step)).fill(loadedChar).join(''); process.stdout.write(`${text}:【${loadedStr}${unloadStr}|${PERCENT}%】`); }
}



function main(){ if(process.argv[2] && process.argv[2] == 'add') { if(process.argv[3]) { // 页面名称 // 判断pages 文件夹是否存在 if(fs.existsSync(`./pages`) && !fs.existsSync(`./pages/${process.argv[3]}`)) { let subProcess= child_process.exec("cd ./pages && mkdir " + process.argv[3], function(err,stdout){ if(err)console.log(err); // 读取 tempalte/index.tsx 的文件 let tempalteStr = fs.readFileSync( path.resolve(__dirname, './template/index.tsx')); fs.writeFile(`./pages/${process.argv[3]}/index.tsx`, tempalteStr, (err) =>{ console.log(err); }); // 创建style less if(program.opts().Style && process.argv[3]) { fs.writeFile(`./pages/${process.argv[3]}/index.less`,'', (err) =>{ console.log(err); }); } subProcess.kill(); }); } } } if(program.opts().Components && process.argv[3]) { // 添加component组件 // 页面名称 // 判断components 文件夹是否存在 if(!fs.existsSync(`./components`)) { fs.mkdirSync('./components'); } if(!fs.existsSync(`./components/${process.argv[3]}`)){ let subProcess=child_process.exec("cd ./components && mkdir " + process.argv[3], function(err,stdout){ if(err)console.log(err); subProcess.kill(); }); } }
// 展示进度条 intervalProgress(); // 精确点: 实时查询新建的几个文件(文件夹)是否创建成功,如果创建完毕,应该提前结束进度条 }
main();
复制代码


 代码大概解说:

  • 使用 nodejs 的 fs 模块 api,对文件的读写以及文件存在的判断。

  • commander 对命令行的解析,得到命令行具体的值后 继续做文件的读写

  • 使用 child_process 子进程 对文件的读写

  • process.stdout.write 来写终端的输出内容

  • 用 template 文件夹 放 具体的模板文件,具体生成文件的时候,可以将模板的内容给到相应的文件中


上述代码不是很复杂,一些比较细节的内容我没有做细节处理,比如进度条的展示,这里是用一个 定时器 来模拟进度的一个过程,如果需要精确点可以监听文件的生成进度,从而调优进度条的展示。

 

  • 现在可以 nextjs 项目下 执行命令:next-add-page add list -components -style

  • next-add-page:是全局的一个命令

  • add: 是添加页面的 一个命令

  • list: 是添加页面的名称 

  • -components: 在 components 文件夹下创建同名的组件 (可选)

  • -style:  创建样式文件 (可选)

是否可选,取决与代码对这个命令行参数的解析以及操作。


现在执行这个命令行:



就可以看到项目中 生成了对应的文件。



到这里基本的需求已经完成了。

接下里是发布,具体发布到 npm 的步骤就不多说了,没有发布过的可以参考下这里:https://cnodejs.org/topic/5823c4411120be9438b02a31

到这里应该知道怎木去开发自己的一个 cli 脚手架了。


参考:

https://juejin.cn/post/6844903702453551111

https://juejin.cn/post/6857842033084760071

https://www.runoob.com/nodejs/nodejs-fs.html

发布于: 2023-07-04阅读数: 20
用户头像

还未添加个人签名 2023-06-19 加入

还未添加个人简介

评论

发布
暂无评论
实战一个自己用的node-cli_Vue_互联网工科生_InfoQ写作社区