为什么需要脚手架?详解node构建脚手架的步骤

为什么需要脚手架?怎么搭建脚手架?下面本篇文章介绍一下node构建脚手架的步骤,希望对大家有所帮助!

为什么需要脚手架?详解node构建脚手架的步骤

1 为什么需要脚手架

根据交互动态生成项目结构和配置文件等。用户通过命令交互的方式下载不同的模版经过模版引擎渲染定制项目模版模版变动,只需更新模版即可,不需要用户更新脚手架 【相关教程推荐:nodejs视频教程、编程教学】

2 构建步骤

新建mycli文件夹(可自定义文件名),下方新建bin文件,bin文件新建index.js,这个index.js就是入口文件,index.js文件头部加入#!/usr/bin/env node代码

生成package.json文件,此时会有个bin配置对象,key值即为全局脚手架名称,value是入口文件bin文件的index.js路径。

    npm init -y    npm install

为什么需要脚手架?详解node构建脚手架的步骤

将脚手架全局命令链接到全局,终端打印mycli即链接成功。

//命令可以将一个任意位置的npm包链接到全局执行环境,从而在任意位置使用命令行都可以直接运行该npm包。npm link

安装依赖

  npm install commander inquirer@8.2.5 download-git-repo chalk@4.1.2 ora@5.4.1 figlet handlebars

commander:命令行工具,有了它我们就可以读取命令行命令,知道用户想要做什么了inquirer: 交互式命令行工具,给用户提供一个漂亮的界面和提出问题流的方式download-git-repo:下载远程模板工具,负责下载远程仓库的模板项目chalk:颜色插件,用来修改命令行输出样式,通过颜色区分 info、error 日志,清晰直观ora:用于显示加载中的效果,类似于前端页面的 loading 效果,像下载模板这种耗时的操作,有了 loading 效果可以提示用户正在进行中,请耐心等待figlet :镂空字体样式

注意:下方代码都放在bin文件index.js进行调试

2.1 commander.js概述

commander.js是一个工具,用来构建node的命令行程序,使得能够使用自定义指令在全局命令行运行node脚本。本来我们只能在脚本所在文件的根目录里通过node xxx.js运行脚本,通过commander构建命令行程序后,就能在任意一个目录里,比如桌面,比如用户目录,直接输入自定义的那个指令,就能直接运行脚本,更加简便。

#!/usr/bin/env node//就是解决了不同的用户node路径不同的问题,可以让系统动态的去查找node来执行你的脚本文件。//node.js内置了对命令行操作的支持,在 package.json 中的 bin 字段可以定义命令名和关联的执行文件。const program = require("commander")program.version('1.1.0')function getFramwork (val) {  console.log(val);}const myhelp = function (program) {  program.option('-f --framwork ', '设置框架', getFramwork)}const createProgress = function (program) {  program.command('create  [other...]')    .alias('crt')    .description('创建项目')    .action((progress, arg) => {      console.log(progress, arg);    })}myhelp(program);createProgress(program);program.parse(process.argv)// 补充.parse()// 作用就是解析,参数就是要解析的字符串,一般使用时参数就是用process.argv,就是用户输入参数

执行全局命令mycli即可输出所有命令~~

image.png

2.2 download-git-repo

download(repository, destination, options, callback)repository:下载地址destination:下载路径options:配置项 {clone:true}callback:下载后的回调

#!/usr/bin/env nodeconst download = require('download-git-repo');download('direct:https://gitlab.com/flippidippi/download-git-repo-fixture.git', "xxx", { clone: true }, (err) => {  console.log(err ? 'Error' : 'Success')})

执行mycli即可看到文件下生成一个xxx文件

image.png

2.3 Inquirer(命令交互)

inquirer 是一个常用的交互式终端用户界面集合。 简单来说 inquirer 是可以让我们很方便的做各种终端交互行为的一个库。

Kimi智能助手 Kimi智能助手

超强AI写作助手,一键总结20w字长文,支持批量文档上传,多端同步内容不怕丢失。论文综述、文档速读、脚本小说创作,统统交给Kimi!实时联网搜索,给你最智能清晰的解答。

Kimi智能助手 1671 查看详情 Kimi智能助手

inquirer 主要提供了三个方法方便我们注册问题

prompt(questions) => promise该方法就是 终端交互的核心方法,运行 prompt 方法即告诉终端启动 交互式命令界面。 – prompt 方法需要传入一个 questions 数组, questions 数组包含对象形式的各个 question. question 的具体结构字段含义在后文介绍。 – prompt 方法的返回值是一个 promise 对象,promise.then 接收的返回值是 answers 对象,answers 对象包含前面所有问题回答的数据结果。

#!/usr/bin/env nodeconst inquirer = require("inquirer")function getUsername() {  return inquirer    .prompt([      {        type: "input",        name: "progress",        message: "请输入项目名称",        default: "progress",        filter(input) {          return input.trim()        },        validate(input) {          return input.length > 0        },      },    ])    .then((answer) => {      console.log(answer)    })}function getFramework() {  return inquirer    .prompt([      {        type: "list",        name: "framework",        choices: [          "express",          new inquirer.Separator(),          "koa",          new inquirer.Separator(),          "egg",        ],        message: "请选择你所使用的框架",      },    ])    .then((answer) => {      console.log(answer)    })}function getSelect() {  return inquirer    .prompt([      {        type: "checkbox",        name: "userndasde",        choices: [          { name: "pr", disabled: true },          { name: "oa", checked: true },          "gg",        ],        message: "需要的验证格式",        // default: ["oa"],      },    ])    .then((answer) => {      console.log(answer)    })}async function init() {  await getSelect()  await getUsername()  await getFramework()}init()

2.4 ora and chalk(美化)

在用户输入答案之后,开始下载模板,这时候使用 ora 来提示用户正在下载中。

注意:注意版本不同引入方式不同,这里用ora(版本5.4.1) ,chalk(版本4.1.2)

const ora = require("ora")const chalk = require("chalk")const spinner = ora("Loading unicorns").start()spinner.text = chalk.blue("下载中~~~~~~")setTimeout(() => {  spinner.succeed(chalk.red("下载成功!"))  spinner.fail("下载失败!")  spinner.warn("警告!")}, 2000)

2.5 figlet(镂空文字)

镂空文字调试器地址:地址

figlet旨在完全实现JavaScript中的FIGfont规范。它可以在浏览器和Node.js中工作。

用法

figlet.text( description,{options},callback(err,data){}) 这个是异步的会被

参数

description:需要格式化的字符串

options:参数配置

Font:字体,Default value:Standard;horizontalLayout:布局,Default value:default; Values:{default,full,fitted};verticalLayout:垂直布局, Default value:default; Values:{defalut,full,fitted,controlled smushing,universal smushing};Width:宽度;whitespaceBreak:换行(Boolean); Default value:false

callback(err,data):回调

const figlet = require("figlet")const chalk = require("chalk")//简单函数function handleAsync(params) {  const JAVASCRIPT = figlet.textSync(    "NODEJS",    {      font: "big",      horizontalLayout: "fitted",      verticalLayout: "controlled smushing",      width: 600,      whitespaceBreak: true,    },    function (err, data) {      if (err) {        console.log("Something went wrong...")        console.dir(err)        return      }      console.log(data)    }  )  console.log(chalk.blue.bold(JAVASCRIPT))}handleAsync()

image.png

总结

创建一个完整的脚手架

目录结构:

为什么需要脚手架?详解node构建脚手架的步骤

bin/index.js
#!/usr/bin/env nodeconsole.log("adas");require("../lib/commander/index.js")
lib/commonder/index.js
const program = require("commander")const init = require('../inquirer/index');const downloadFun = require("../core/download.js");program.version('1.1.0')function getFramwork (val) {  console.log(val);}const myhelp = function (program) {  program.option('-f --framwork  [other...]', '设置框架', getFramwork)}const createProgress = function (program) {  program.command('create  [other...]')    .alias('crt')    .description('创建项目')    .action((progress, arg) => {      init();    })}const downloadUrl = function (program) {  program.command('download  [...other]')    .description('下载内容')    .action((url, ...args) => {      console.log(args);      downloadFun(url, args[1].args[1])    })}myhelp(program);downloadUrl(program);createProgress(program)program.parse(process.argv)

lib/core/action.js (package.json重写)

const fs = require('fs');const path = require("path");const handlebars = require("handlebars");  function modifyPackageJson (options) {    let downloadPath = options.projectName;    const packagePath = path.join(downloadPath, 'package.json');    console.log(packagePath, "packagePath");        //判断是否存在package.json文件    if (fs.existsSync(packagePath)) {      let content = fs.readFileSync(packagePath).toString();            //判断是否选择了eslint      if (options.isIslint) {        let targetContent = JSON.parse(content);        content = JSON.stringify(targetContent);        targetContent.dependencies.eslint = "^1.0.0";        console.log("content", content);      }            //写入模板      const template = handlebars.compile(content);      const param = { name: options.projectName };      const result = template(param);            //重新写入package.json文件      fs.writeFileSync(packagePath, result);      console.log('modify package.json complate');    } else {      throw new Error('no package.json');    }  }  module.exports = modifyPackageJson

lib/core/download.js

  const download = require('download-git-repo');  const ora = require("ora");  const chalk = require("chalk");  const figlet = require("figlet");  const modifyPackageJson = require("./action")    function handleAsync (params) {    const JAVASCRIPT = figlet.textSync('JAVASCRIPT', {      font: 'big',      horizontalLayout: 'fitted',      verticalLayout: 'controlled smushing',      width: 600,      whitespaceBreak: true    }, function (err, data) {      if (err) {        console.log('Something went wrong...');        console.dir(err);        return;      }      console.log(data);    });    console.log(chalk.blue.bold(JAVASCRIPT));  }    const downloadFun = (url, option) => {    const spinner = ora("Loading unicorns").start()    spinner.text = chalk.blue("下载中");        download(url, option.projectName, { clone: true }, function (err) {      if (err) {        spinner.fail("下载失败!");        handleAsync()      } else {        spinner.succeed(chalk.red("下载成功!"))        console.log(chalk.blue(`cd ${option.projectName}`))        console.log(chalk.red("npm install"))        console.log(chalk.yellow(`npm run dev`))        modifyPackageJson(option)        handleAsync()      }    })  }  module.exports = downloadFun;

inquire/index.js 注意frameworkConfig写自己的gitlab仓库地址

  const inquirer = require("inquirer");  const downloadFun = require("../core/download.js");  const frameworkConfig = {    front: "https://gitlab.com/flippidippi/download-git-repo-fixture.git",    manager: "https://gitlab.com/flippidippi/download-git-repo-fixture.git"  }  const config = {};    function getFramework () {    return inquirer.prompt([      {        type: 'list',        name: 'framework',        choices: ["front", "manager"],        message: "请选择你所使用的框架"      }    ]).then((answer) => {      return answer.framework;    })  }    function getProjectName () {    return inquirer.prompt([      {        type: 'input',        name: 'projectName',        message: '项目名称',        filter (input) {          return input.trim();        },      }    ]).then((answer) => {      console.log(answer, "FDsfs");      return answer.projectName;    })  }    function getIsEslint () {    return inquirer.prompt([      {        type: 'confirm',        name: 'isIslint',        message: '是否使用eslint校验格式?'      }    ]).then((answer) => {      return answer.isIslint;    })  }    async function init () {    config.projectName = await getProjectName();    config.framework = await getFramework();    config.isIslint = await getIsEslint();    let url = config.framework == "front" ? frameworkConfig.front : frameworkConfig.manager;    downloadFun("direct:" + url, config);  }  module.exports = init;

更多node相关知识,请访问:nodejs 教程!

以上就是为什么需要脚手架?详解node构建脚手架的步骤的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/541998.html

赞 (0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
java框架在人工智能应用中的优势有哪些?
上一篇 2025年11月9日 15:42:01
上海交通大学人工智能研究院副院长刘燕京一行到访郑州外国语学校航空港校区
下一篇 2025年11月9日 15:42:06

相关推荐

  • sublime怎么配置eslint_sublime ESLint插件配置教程

    sublime怎么配置eslint_sublime ESLint插件配置教程sublime怎么配置eslint_sublime ESLint插件配置教程sublime怎么配置eslint_sublime ESLint插件配置教程sublime怎么配置eslint_sublime ESLint插件配置教程

    首先安装Node.js和ESLint,通过npm全局或项目内安装并初始化配置;接着在Sublime Text中使用Package Control安装SublimeLinter及SublimeLinter-eslint插件;然后根据需要在设置中配置ESLint可执行文件路径;再添加”&#8…

    2026年9月24日 • 用户投稿
    100
  • sublime怎么配置TypeScript自动编译_sublime集成TypeScript编译环境步骤

    sublime怎么配置TypeScript自动编译_sublime集成TypeScript编译环境步骤sublime怎么配置TypeScript自动编译_sublime集成TypeScript编译环境步骤sublime怎么配置TypeScript自动编译_sublime集成TypeScript编译环境步骤sublime怎么配置TypeScript自动编译_sublime集成TypeScript编译环境步骤

    首先安装Node.js和TypeScript,再在Sublime Text中创建自定义构建系统:1. 通过npm全局安装TypeScript并验证版本;2. 在Sublime中新建Build System,配置tsc编译命令、文件匹配规则及工作目录;3. 保存为TypeScript.sublime-…

    2026年9月24日 • 用户投稿
    000
  • sublime怎么配置js prettier自动格式化_Sublime集成Prettier实现JS代码自动格式化

    sublime怎么配置js prettier自动格式化_Sublime集成Prettier实现JS代码自动格式化sublime怎么配置js prettier自动格式化_Sublime集成Prettier实现JS代码自动格式化sublime怎么配置js prettier自动格式化_Sublime集成Prettier实现JS代码自动格式化sublime怎么配置js prettier自动格式化_Sublime集成Prettier实现JS代码自动格式化

    首先安装Node.js和Prettier,再通过Package Control安装JsPrettier插件,配置prettier_cli_path、node_path及auto_format_on_save为true,确保保存时自动格式化JS代码。 Sublime Text 虽然轻量,但通过插件可以…

    2026年9月24日 • 用户投稿
    800
  • VS Code微服务开发:Docker与Kubernetes集成

    VS Code通过Docker扩展实现本地容器化开发,支持自动生成Dockerfile、一键构建镜像及devcontainer环境一致性;2. Kubernetes扩展可连接集群并管理资源,结合Bridge to Kubernetes实现本地调试与集群网络集成;3. 使用Skaffold自动化构建部…

    2026年9月24日
    100
  • VSCode主题开发:创建动态色彩主题的进阶技术解析

    动态主题需通过外部插件监听系统事件实现,核心是利用vscode.themeColor API响应主题切换,结合语义化作用域与Semantic Highlighting精准控制配色逻辑,实现智能自适应视觉体验。 想让VSCode主题随环境自动切换色彩?动态主题不只是换个配色那么简单。核心在于理解VSC…

    2026年9月23日
    500
  • 如何在mysql中使用连接池提升并发

    连接池通过复用数据库连接减少开销,提升高并发下系统性能;需根据语言选择HikariCP、SQLAlchemy等组件,合理配置最大连接数、空闲连接等参数,并结合数据库优化与监控调优以充分发挥效果。 在高并发场景下,频繁创建和销毁数据库连接会带来显著的性能开销。MySQL本身不直接提供连接池功能,但可以…

    2026年9月23日
    300
  • 嵌入式Linux开发-根文件系统本地挂载

    嵌入式Linux开发-根文件系统本地挂载嵌入式Linux开发-根文件系统本地挂载嵌入式Linux开发-根文件系统本地挂载嵌入式Linux开发-根文件系统本地挂载

    引言 前一篇文章介绍了根文件系统的制作与nfs网络挂载,本文将探讨如何通过本地挂载根文件系统来完成系统启动。本地挂载通常用于产品发布阶段,并且分为两种操作方式。 第一种方式:在PC机上制作好文件映像rootfs.img,然后通过uboot加载并直接烧写到EMMC中。这种方法最便捷,适用于产品批量生产…

    2026年9月23日 • 用户投稿
    300
  • 构建VSCode多媒体编程界面与实时音视频处理

    答案:VSCode通过配置Node.js、Python扩展及FFmpeg等工具,结合OpenCV、PyAudio等框架,可构建高效音视频处理环境。1. 安装Python和Node.js支持,启用Pylance、Jupyter插件提升数据处理体验;2. 配置终端与Code Runner实现脚本一键执行…

    2026年9月22日
    100
  • rm -rf 误删文件?别急,或许有救!

    rm -rf 误删文件?别急,或许有救!rm -rf 误删文件?别急,或许有救!rm -rf 误删文件?别急,或许有救!rm -rf 误删文件?别急,或许有救!

    立即采取行动! 在生产环境中,我们应尽量避免进行风险操作。但如果不慎犯错,如何挽救呢?让我分享一个故事:上周我为了打包一个应用,需要整理Ubuntu 16.04上的线上数据,不小心删除了一个数据文件,幸而最终有惊无险,现记录如下。 extundelete 我的恢复计划主要依赖于一个工具——extun…

    2026年9月22日 • 用户投稿
    000
  • Linux系统中文件属性和权限实战操作

    Linux系统中文件属性和权限实战操作Linux系统中文件属性和权限实战操作Linux系统中文件属性和权限实战操作Linux系统中文件属性和权限实战操作

    —–原本今天的文章是昨天晚上就要更新的,但是由于昨天晚上下班回到住的地方,发现停电了,所以就没写成。今天是在上一篇文章–linux系统中文件类型的基础上,继续进行深入的学习。好了,直接开干。 一、文件的操作权限: 1、在这之前我想还是很有必要介绍对文件的操作权限(…

    2026年9月22日 • 用户投稿
    300
  • 使用本地HTML文件运行JavaScript脚本失败的原因及解决方案

    本文旨在帮助开发者理解在没有Web服务器的情况下,直接通过浏览器打开本地HTML文件时,JavaScript脚本可能无法正常运行的原因,并提供相应的解决方案。文章将深入探讨浏览器安全策略、相对路径问题以及如何正确引入和执行JavaScript脚本,确保你的HTML、CSS和JavaScript代码能…

    2026年9月21日
    100
  • PHPComposer怎么安装_PHPComposer依赖管理工具安装与使用指南

    PHPComposer是PHP的依赖管理工具,类似npm或pip。需先安装PHP,再下载并验证composer-setup.php,执行安装生成composer.phar,推荐全局安装至/usr/local/bin/composer,运行composer –version验证。使用com…

    2026年9月21日
    100
  • mysql如何实现后台管理系统

    答案:基于MySQL的%ignore_a_1%需设计用户、权限、日志等表结构,通过后端语言实现安全的CRUD接口与JWT认证,前端展示数据并控制权限,确保系统安全稳定。 实现一个基于 MySQL 的后台管理系统,核心是构建一个安全、稳定、可扩展的系统架构,将数据库作为数据存储层,配合后端语言和前端界…

    2026年9月21日
    200
  • VSCode的扩展推荐是怎么工作的?

    VSCode的扩展推荐基于用户行为和项目环境智能生成,当你打开.py文件时会推荐Python相关工具,打开.ts、.vue等文件则触发对应语言插件;系统通过分析package.json、requirements.txt等依赖文件识别技术栈,推荐Docker、ESLint等匹配扩展;同时记录常用操作如…

    2026年9月20日
    000
  • VSCode的侧边栏图标代表什么?

    资源管理器(文件夹图标)用于管理项目文件结构,支持新建、重命名、删除和拖拽操作;2. 搜索(放大镜图标)实现全局文本查找与替换,支持正则表达式及范围筛选;3. 源代码管理(分支图标)集成Git功能,可查看变更、提交代码并同步远程仓库;4. 运行和调试(虫子图标)支持断点调试、变量监控及多语言启动配置…

    2026年9月20日
    000
  • 如何为VSCode添加自定义主题?

    可通过安装扩展、手动添加JSON文件或使用Yeoman生成器创建主题。首先安装现成主题扩展并从颜色主题列表中选择应用;其次将自定义主题JSON文件放入用户themes目录后在命令面板中启用;最后可用yo code生成项目开发发布主题,需编辑配色文件并预览效果。 为 VSCode 添加自定义主题有几种…

    2026年9月20日
    000
  • edge浏览器无法打开本地HTML文件或显示空白怎么办_Edge浏览器打开本地HTML文件失败解决方法

    1、检查文件路径并选择Edge打开,确保路径为纯英文;2、在edge://flags中启用“Allow file access from files”;3、使用开发者工具排查资源加载错误;4、通过命令行启动Edge绕过安全限制;5、推荐使用npx live-server搭建本地服务器运行HTML文件…

    2026年9月20日
    000
  • VSCode的扩展推荐是基于什么?

    答案是VSCode根据文件类型、项目配置、用户行为和社区流行度智能推荐扩展。打开.py文件时提示Python扩展,存在package.json则推荐JS工具,频繁格式化代码会推荐Prettier,安装ESLint后可能推荐Prettier,高评分和官方扩展优先展示。 VSCode的扩展推荐主要基于你…

    2026年9月20日
    000
  • mysql如何实现用户注册功能

    答案:通过MySQL创建用户表并结合后端逻辑实现注册功能。首先在MySQL中创建包含用户名、密码、邮箱等字段的users表,确保唯一性约束;后端接收%ignore_a_1%提交的注册数据,对密码加密(如SHA256或bcrypt),使用参数化查询将数据安全存入数据库;前端通过表单或AJAX发送注册请…

    2026年9月13日
    200
  • 如何利用VSCode的配置文件(Launch.json)环境变量来管理不同环境的配置?

    通过配置launch.json中的多个调试环境并结合.env文件,可高效管理开发、测试、生产等不同环境的运行参数。 在使用 VSCode 进行开发时,launch.json 文件是调试配置的核心。通过合理利用环境变量和配置文件分离,可以轻松管理不同环境(如开发、测试、生产)的运行参数。 理解 lau…

    2026年9月13日
    000

发表回复

登录后才能评论
关注微信