当前位置: 首页 > news >正文

前端从零到一搭建脚手架并发布到npm

这里写自定义目录标题

  • 为什么需要脚手架?
  • 前置-第三方工具的使用
    • 1. 创建demo并运行-4步
      • 新建文件夹 zyfcli,并初始化npm init -y
      • 配置入口文件
    • 2.commander-命令行指令
    • 3. chalk-命令行美化工具
    • 4. inquirer-命令行交互工具
    • 5. figlet-艺术字
    • 6. ora-loading工具
    • 7. 小demo的完整代码
  • 正式版走起
    • 1. 处理bin的index文件
    • 2.处理create.js
    • 3. 添加utils工具函数
    • 4. 查看效果
  • 发布到npm
  • 参考
  • 代码仓库
    • npm 地址

在这里插入图片描述

好多前端工作多年依然不会搭建脚手架,本文就介绍下如何从零开始搭建一个前端脚手架。

为什么需要脚手架?

  1. 减少重复性的工作,不再从零创建一个项目,或者复制粘贴另一个项目的代码 。
  2. 根据动态交互生成项目结构和配置文件,具备更高的灵活性和人性化定制的能力 。
  3. 有利于多人开发协作,避免了人工传递文件的繁琐。
  4. 可以集成多套开发模板,根据项目需要选择合适的模板。

前置-第三方工具的使用

实现一个脚手架,通常需要以下工具

  1. commander: 命令行工具
  2. download-git-repo: 来通过git下载项目模板的插件
  3. inquirer: 用于命令行交互问询等
  4. ora: 用于实现node命令环境的loading效果,并显示各种状态的图标,显示 loading 动画
  5. chalk: chalk是一个颜色的插件。可以通过chalk.green(‘success’)来改变颜色。修改控制台输出内容样式
  6. log-symbols: 用于在打印输出的内容中加入icon更友好(显示出 √ 或 × 等的图标)

**注意:**插件的版本。

为了演示先创建一个小项目

1. 创建demo并运行-4步

新建文件夹 zyfcli,并初始化npm init -y

装包-注意版本

pnpm i commander@9.5.0 chalk@4.0.0 inquirer@8.2.1 ora@4.0.0 figlet download-git-repo  ora log-symbols

注意:版本过高会报错,已踩坑…
在这里插入图片描述

配置入口文件

在根目录下新建bin/index.js【整个脚手架的入口文件】

#! /usr/bin/env node
console.log('hello world')

验证结果:在命令行中输入node ./bin/index.js,如果能打印出hello即成功

将入口文件配置到package.json 的bin字段

{"name": "zyfcli","bin": "bin/index.js",  
}
// 写法2,注意bin里key,需要和nage保持一致
{"name": "zyfcli","bin": {"zyfcli": "bin/www"}
}

npm link将命令挂载到全局
执行 npm link将命令挂载到全局,然后再输入 zyfcli 就可以到达刚才node ./bin/index.js 的效果了

2.commander-命令行指令

引入commander

const program = require("commander");program.name('zyfcli').usage(`<command>[option]`).version(`1.0.0`)
// 解析用户执行命令传入参数
program.parse(process.argv);

在命令行输入commander --help,即可看到简单的效果
在这里插入图片描述

3. chalk-命令行美化工具

#! /usr/bin/env node
const program = require("commander");
const chalk = require('chalk')program.name('zyfcli').usage(`<command>[option]`).version(`1.0.0`)// 解析用户执行命令传入参数
program.parse(process.argv);// 演示美化工具
console.log(`${chalk.green("hello")} zyf`);

输入 zyfcli,看hello显示颜色
在这里插入图片描述
其他用法

console.log(`${chalk.green  --颜色.bold   --加粗.underline  --下划线("hello")} zyf`);

4. inquirer-命令行交互工具

const Inquirer = require('inquirer');// 命令行交互
new Inquirer.prompt([{name: 'zyfcli',type: "checkbox",message: "Check the features needed for your project",choices: [{name: 'Babel',checked: 'true',},{name: 'TypeScript',}]}
]).then((data) => {console.log(data);
})

在这里插入图片描述

5. figlet-艺术字

  1. 安装 npm i figlet
  2. 使用
const figlet = require('figlet')console.log(figlet.textSync('Hello Word'));
  1. 效果

6. ora-loading工具

注意版本

  1. 使用
const ora = require('ora');
const spinner = ora('Loading unicorns').start();setTimeout(() => {// spinner.color = 'yellow';spinner.text = 'Loading rainbows';spinner.succeed()// spinner.stop()
}, 1000);

效果
在这里插入图片描述

7. 小demo的完整代码

#! /usr/bin/env node
// 演示工具的使用
const program = require("commander");
const chalk = require('chalk');
const Inquirer = require('inquirer');
const figlet = require('figlet')
const ora = require('ora');program.name('zyfcli').usage(`<command>[option]`).version(`1.0.0`)// 演示美化工具
console.log(`${chalk.green.bold.underline("hello")} zyf`);// 命令行交互
// new Inquirer.prompt([
//   {
//     name: 'zyfcli',
//     type: "checkbox",
//     message: "Check the features needed for your project",
//     choices: [
//       {
//         name: 'Babel',
//         checked: 'true',
//       },
//       {
//         name: 'TypeScript',
//       }
//     ]
//   }
// ]).then((data) => {
//   console.log(data);
// })// 艺术字
console.log(figlet.textSync('Hello Word'));// loading
const spinner = ora('Loading unicorns').start();setTimeout(() => {// spinner.color = 'yellow';spinner.text = 'Loading rainbows';// spinner.succeed()// spinner.stop()
}, 1000);// 解析用户执行命令传入参数
program.parse(process.argv);

正式版走起

先看下目录结构
在这里插入图片描述

1. 处理bin的index文件

#! /usr/bin/env node
const program = require("commander");
const chalk = require("chalk");
const figlet = require("figlet");program.name("zyfcli").usage(`zyfcli <command> [option]`).version(`zyfcli ${require("../package.json").version}`);program.command("create <project-name>") // 增加创建指令.description("create a new project") // 添加描述信息.option("-f, --force", "overwrite target directory if it exists") // 强制覆盖.action((projectName, cmd) => {// 处理用户输入create 指令附加的参数require("../lib/create")(projectName, cmd);});program.command("config [value]").description("inspect and modify the config").option("-g, --get <key>", "get value by key").option("-s, --set <key> <value>", "set option[key] is value").option("-d, --delete <key>", "delete option by key").action((value, keys) => {console.log(value, keys);});program.on("--help", function () {console.log("\r\n" +figlet.textSync("zyf-cli", {font: "3D-ASCII",horizontalLayout: "default",verticalLayout: "default",width: 80,whitespaceBreak: true,}));// 前后两个空行调整格式,更舒适console.log();console.log(`Run ${chalk.cyan("zyfcli <command> --help")} for detailed usage of given command.`);console.log();
});program.parse(process.argv);

create.js先不写东西

看下效果
在这里插入图片描述

2.处理create.js

路径:根目录/lib/create.js

const path = require("path");
const fs = require("fs-extra");
const Inquirer = require("inquirer");
const downloadGitRepo = require("download-git-repo");
const chalk = require("chalk");
const util = require("util");
const { loading } = require("./util");module.exports = async function (projectName, options) {// 获取当前工作目录const cwd = process.cwd();const targetDirectory = path.join(cwd, projectName);// 处理文件夹await handleFolder(projectName, options, targetDirectory);// 1.选择模版const { template } = await new Inquirer.prompt([{name: "template",type: "list",message: "Please choose a template to create project",choices: [{ name: 'react', value: 'zyf118725/reactTs' },{ name: 'vue', value: 'https://vue仓库' }, // 演示{ name: 'angular', value: 'https://angular仓库' },],},]);// 2.下载await download(template, targetDirectory);// 3.模板使用提示console.log(`\r\nSuccessfully created project ${chalk.cyan(projectName)}`);console.log(`\r\n  cd ${chalk.cyan(projectName)}`);console.log("  npm install");// console.log("  npm run serve\r\n");
};// 处理文件夹创建重名问题
async function handleFolder(projectName, options, targetDirectory) {if (fs.existsSync(targetDirectory)) {if (options.force) {// 删除重名目录await fs.remove(targetDirectory);} else {let { isOverwrite } = await new Inquirer.prompt([{name: "isOverwrite", // 与返回值对应type: "list", // list 类型message: "Target directory exists, Please choose an action",choices: [{ name: "Overwrite", value: true },{ name: "Cancel", value: false },],},]);if (!isOverwrite) {console.log("Cancel");return;} else {await loading(`Removing ${projectName}, please wait a minute`,fs.remove,targetDirectory);}}}
}// 下载git仓库
async function download(templateUrl, targetDirectory) {const downloadGitRepoPromise = util.promisify(downloadGitRepo);await loading("downloading template, please wait",downloadGitRepoPromise,templateUrl,targetDirectory // 项目创建位置);
}

3. 添加utils工具函数

封装axios等函数。

const ora = require("ora");/*** 睡觉函数* @param {Number} n 睡眠时间*/
function sleep(n) {return new Promise((resolve, reject) => {setTimeout(() => {resolve();}, n);});
}/*** loading加载效果* @param {String} message 加载信息* @param {Function} fn 加载函数* @param {List} args fn 函数执行的参数* @returns 异步调用返回值*/
async function loading(message, fn, ...args) {const spinner = ora(message);spinner.start(); // 开启加载try {let executeRes = await fn(...args);spinner.succeed();return executeRes;} catch (error) {spinner.fail("request fail, reTrying");await sleep(1000);return loading(message, fn, ...args);}
}module.exports = { loading };

4. 查看效果

创建一个democli项目

在这里插入图片描述
在这里插入图片描述

发布到npm

npm包的发布比较简单,就不在赘述了,没整过的小伙伴可以查下教程

  1. npm login
  2. npm publish

在这里插入图片描述
额,名字太简单了改下名字
修改下package继续发包,注意package的name和bin中的名称。
在这里插入图片描述

发布成功
在这里插入图片描述

参考

  1. 掘金-从0到1搭建React脚手架 https://www.yuque.com/yafei/dqso8a/pzb1yp89dc4uppno
  2. https://blog.csdn.net/gao_xu_520/article/details/120505635
  3. 掘金-工具详解:https://juejin.cn/post/7077717940941881358
  4. commander中文文档(github):https://github.com/tj/commander.js/blob/master/Readme_zh-CN.md

代码仓库

  1. zyfcli: https://github.com/zyf118725/zyfcli
  2. react: https://github.com/zyf118725/reactTs

npm 地址

https://www.npmjs.com/package/yfli

未完待续。。。
![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/66d5245123894436a74e2c7042d0d522.jpeg#pic_center #pic_center =500x)

下班码字不易,如果有帮到你请给个打赏谢谢
在这里插入图片描述

在这里插入图片描述

相关文章:

前端从零到一搭建脚手架并发布到npm

这里写自定义目录标题 为什么需要脚手架&#xff1f;前置-第三方工具的使用1. 创建demo并运行-4步新建文件夹 zyfcli&#xff0c;并初始化npm init -y配置入口文件 2.commander-命令行指令3. chalk-命令行美化工具4. inquirer-命令行交互工具5. figlet-艺术字6. ora-loading工具…...

使用 git 提交项目到 github

文章推荐&#xff1a;https://zhuanlan.zhihu.com/p/193140870 连接失败&#xff1a;https://zhuanlan.zhihu.com/p/521340971 分支出错&#xff1a;https://blog.csdn.net/gongdamrgao/article/details/115032436...

SRE 与传统 IT 运营有何不同?

软件开发和部署方法的发展要求组织管理和维护 IT 基础设施的方式发生转变。站点可靠性工程(SRE) 是一门将软件工程的各个方面融入 IT 运营的学科&#xff0c;处于这一变革的前沿。随着专业人士和组织都寻求适应&#xff0c;对 SRE 认证和培训计划的需求激增。本博客探讨了 SRE …...

html公众号页面实现点击按钮跳转到导航

实现效果&#xff1a; 点击导航自动跳转到&#xff1a; html页面代码&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>跳转导航</title><meta name"keywords" conten…...

【算法】快速排序的基本思想、优化 | 挖坑填补法和区间分割法

创作不易&#xff0c;本篇文章如果帮助到了你&#xff0c;还请点赞 关注支持一下♡>&#x16966;<)!! 主页专栏有更多知识&#xff0c;如有疑问欢迎大家指正讨论&#xff0c;共同进步&#xff01; 更多算法分析与设计知识专栏&#xff1a;算法分析&#x1f525; 给大家跳…...

OSPF动态路由实验(华为)

思科设备参考&#xff1a;OSPF动态路由实验&#xff08;思科&#xff09; 一&#xff0c;技术简介 OSPF&#xff08;Open Shortest Path First&#xff09;是一种内部网关协议&#xff0c;主要用于在单一自治系统内决策路由。它是一种基于链路状态的路由协议&#xff0c;通过…...

EasyRecovery2024专业免费的电脑数据恢复软件

EasyRecovery数据恢复软件是一款功能强大的数据恢复工具&#xff0c;广泛应用于各种数据丢失场景&#xff0c;帮助用户从不同类型的存储介质中恢复丢失或删除的文件。 该软件支持恢复的数据类型非常广泛&#xff0c;包括但不限于办公文档、图片、音频、视频、电子邮件以及各种…...

Vue集成PageOffice实现在线编辑word、excel(前端配置)

一、什么是PageOffice PageOffice是一款在线的office编辑软件&#xff0c;帮助Web应用系统或Web网站实现用户在线编辑Word、Excel、PowerPoint文档。可以完美实现在线公文流转&#xff0c;领导批阅&#xff0c;盖章。可以给文件添加水印&#xff0c;在线安全预览防止用户下载…...

IBM SPSS Statistics for Mac:数据分析的卓越工具

IBM SPSS Statistics for Mac是一款功能强大的数据分析软件&#xff0c;专为Mac用户设计&#xff0c;提供了一系列专业的统计分析和数据管理功能。无论是科研人员、数据分析师还是学生&#xff0c;都能从中获得高效、准确的数据分析支持。 IBM SPSS Statistics for Mac v27.0.1…...

python爬虫------- Selenium下篇(二十三天)

&#x1f388;&#x1f388;作者主页&#xff1a; 喔的嘛呀&#x1f388;&#x1f388; &#x1f388;&#x1f388;所属专栏&#xff1a;python爬虫学习&#x1f388;&#x1f388; ✨✨谢谢大家捧场&#xff0c;祝屏幕前的小伙伴们每天都有好运相伴左右&#xff0c;一定要天天…...

获取字符串的全排列(去除字符串中2个字符相同时造成的重复)

一、概念 现有一个字符串&#xff0c;要打印出该字符串中字符的全排列。 以字符串abc为例&#xff0c;输出的结果为&#xff1a;abc、acb、bac、bca、cab、cba。 以字符串aab为例&#xff0c;输出的结果为&#xff1a;aab、aba、baa。 二、代码 public class Permutation {pub…...

HTML5新增的多媒体标签

在网页中加入音乐 <audio></audio> src 设置音乐文件名以及路径,<audio>标记支持MP3、WAV及OGG 3种音乐格式 autoplay&#xff1a;是否自动播放,加入autopaly属性表示自动播放 controls&#xff1a; 是否显示播放面板,加入controls属性表示显示播放面板 …...

温湿度传感器(DHT11)以及光照强度传感器(BH1750)的使用

前言 对于一些单片机类的环境检测或者智能家居小项目中&#xff0c;温湿度传感器&#xff08;DHT11&#xff09;以及光照强度传感器&#xff08;BH1750&#xff09;往往是必不可少的两个外设&#xff0c;下面我们来剖析这两个外设的原理&#xff0c;以及使用。 1. 温湿度传感…...

ActiveMQ 04 Linux下安装

Active MQ 04 Linux下安装 下载 解压 在init.d下建立软连接 ln -s /usr/local/activemq/bin/activemq ./设置开启启动 chkconfig activemq on 服务管理 service activemq start service activemq status service activemq stopNIO配置 默认配置为tcp&#xff0c;使用的…...

.pyc 文件是什么?是否有必要同步到 GitHub 远程仓库?

git status 时发现有很多 .pyc 的没有被 add (env) username:~/path/to/project$ git status On branch main Your branch is up to date with origin/main.Changes to be committed:(use "git restore --staged <file>..." to unstage)new file: xxx.pyCha…...

Zookeeper的集群搭建和ZAB协议详解

Zookeeper的集群搭建 1&#xff09;zk集群中的角色 Zookeeper集群中的节点有三个角色&#xff1a; Leader&#xff1a;处理集群的所有事务请求&#xff0c;集群中只有一个LeaderFollwoer&#xff1a;只能处理读请求&#xff0c;参与Leader选举Observer&#xff1a;只能处理读…...

STM32 MPU配置参数

TXE LEVEL一般只用MPU_TEX_LEVEL0 1 - 1 - 1 -0性能最强&#xff08;TEX - C - B- S&#xff09;. #define MPU_TEX_LEVEL0 ((uint8_t)0x00) #define MPU_TEX_LEVEL1 ((uint8_t)0x01) #define MPU_TEX_LEVEL2 ((uint8_t)0x02) 基于上表进行常用配置 &#xff…...

Kafka概述

目录 1、为什么需要消息队列&#xff08;MQ&#xff09; 2、使用消息队列的好处 3、消息队列的两种模式 4、Kafka 定义 5、Kafka 简介 6、Kafka 的特性 7、Kafka 系统架构 8、Partation 数据路由规则 9、分区的原因 1、为什么需要消息队列&#xff08;MQ&#xff09; …...

OpenHarmony编译构建系统

这篇来聊聊OpenHarmony的编译构建&#xff0c;经过前面的实践&#xff0c;再来看编译构建。 编译构建概述 在官网中提到了&#xff0c;OpenHarmony编译子系统是以GN和Ninja构建为基座&#xff0c;对构建和配置粒度进行部件化抽象、对内建模块进行功能增强、对业务模块进行功能…...

Qt5 编译oracle数据库驱动

库文件 1、Qt源码目录&#xff1a;D:\Qt5\5.15.2\Src\qtbase\src\plugins\sqldrivers\oci 2、oracle客户端SDK: https://www.oracle.com/database/technologies/instant-client/winx64-64-downloads.html 下载各版本中的如下压缩包&#xff0c;一定要版本相同的 将两个压缩包…...

Flask RESTful 示例

目录 1. 环境准备2. 安装依赖3. 修改main.py4. 运行应用5. API使用示例获取所有任务获取单个任务创建新任务更新任务删除任务 中文乱码问题&#xff1a; 下面创建一个简单的Flask RESTful API示例。首先&#xff0c;我们需要创建环境&#xff0c;安装必要的依赖&#xff0c;然后…...

【数据分析】R版IntelliGenes用于生物标志物发现的可解释机器学习

禁止商业或二改转载&#xff0c;仅供自学使用&#xff0c;侵权必究&#xff0c;如需截取部分内容请后台联系作者! 文章目录 介绍流程步骤1. 输入数据2. 特征选择3. 模型训练4. I-Genes 评分计算5. 输出结果 IntelliGenesR 安装包1. 特征选择2. 模型训练和评估3. I-Genes 评分计…...

现有的 Redis 分布式锁库(如 Redisson)提供了哪些便利?

现有的 Redis 分布式锁库&#xff08;如 Redisson&#xff09;相比于开发者自己基于 Redis 命令&#xff08;如 SETNX, EXPIRE, DEL&#xff09;手动实现分布式锁&#xff0c;提供了巨大的便利性和健壮性。主要体现在以下几个方面&#xff1a; 原子性保证 (Atomicity)&#xff…...

在Mathematica中实现Newton-Raphson迭代的收敛时间算法(一般三次多项式)

考察一般的三次多项式&#xff0c;以r为参数&#xff1a; p[z_, r_] : z^3 (r - 1) z - r; roots[r_] : z /. Solve[p[z, r] 0, z]&#xff1b; 此多项式的根为&#xff1a; 尽管看起来这个多项式是特殊的&#xff0c;其实一般的三次多项式都是可以通过线性变换化为这个形式…...

基于鸿蒙(HarmonyOS5)的打车小程序

1. 开发环境准备 安装DevEco Studio (鸿蒙官方IDE)配置HarmonyOS SDK申请开发者账号和必要的API密钥 2. 项目结构设计 ├── entry │ ├── src │ │ ├── main │ │ │ ├── ets │ │ │ │ ├── pages │ │ │ │ │ ├── H…...

五子棋测试用例

一.项目背景 1.1 项目简介 传统棋类文化的推广 五子棋是一种古老的棋类游戏&#xff0c;有着深厚的文化底蕴。通过将五子棋制作成网页游戏&#xff0c;可以让更多的人了解和接触到这一传统棋类文化。无论是国内还是国外的玩家&#xff0c;都可以通过网页五子棋感受到东方棋类…...

图解JavaScript原型:原型链及其分析 | JavaScript图解

​​ 忽略该图的细节&#xff08;如内存地址值没有用二进制&#xff09; 以下是对该图进一步的理解和总结 1. JS 对象概念的辨析 对象是什么&#xff1a;保存在堆中一块区域&#xff0c;同时在栈中有一块区域保存其在堆中的地址&#xff08;也就是我们通常说的该变量指向谁&…...

密码学基础——SM4算法

博客主页&#xff1a;christine-rr-CSDN博客 ​​​​专栏主页&#xff1a;密码学 &#x1f4cc; 【今日更新】&#x1f4cc; 对称密码算法——SM4 目录 一、国密SM系列算法概述 二、SM4算法 2.1算法背景 2.2算法特点 2.3 基本部件 2.3.1 S盒 2.3.2 非线性变换 ​编辑…...

数据库——redis

一、Redis 介绍 1. 概述 Redis&#xff08;Remote Dictionary Server&#xff09;是一个开源的、高性能的内存键值数据库系统&#xff0c;具有以下核心特点&#xff1a; 内存存储架构&#xff1a;数据主要存储在内存中&#xff0c;提供微秒级的读写响应 多数据结构支持&…...

归并排序:分治思想的高效排序

目录 基本原理 流程图解 实现方法 递归实现 非递归实现 演示过程 时间复杂度 基本原理 归并排序(Merge Sort)是一种基于分治思想的排序算法&#xff0c;由约翰冯诺伊曼在1945年提出。其核心思想包括&#xff1a; 分割(Divide)&#xff1a;将待排序数组递归地分成两个子…...