비계는 왜 필요한가요? 비계를 만드는 방법? 다음 기사에서는 노드에서 스캐폴딩을 구축하는 단계를 소개합니다. 모든 사람에게 도움이 되기를 바랍니다.
새 mycli
폴더를 만들고(파일 이름은 사용자 정의 가능) 새 bin
파일 아래에 index.js
라는 새 bin 파일을 만듭니다. 이 index.js
가 항목 파일입니다. 를 <code>index.js
파일의 헤더에 추가합니다. #!/usr/bin/env node 코드 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
将脚手架全局命令链接到全局,终端打印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
:镂空字体样式index.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 <framwork>', '设置框架', getFramwork) } const createProgress = function (program) { program.command('create <progress> [other...]') .alias('crt') .description('创建项目') .action((progress, arg) => { console.log(progress, arg); }) } myhelp(program); createProgress(program); program.parse(process.argv) // 补充 .parse() // 作用就是解析,参数就是要解析的字符串,一般使用时参数就是用process.argv,就是用户输入参数
执行全局命令mycli
即可输出所有命令~~
download
(repository, destination, options, callback)repository
:下载地址destination
:下载路径options
:配置项 {clone:true}callback
:下载后的回调#!/usr/bin/env node const 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
文件
inquirer 是一个常用的交互式终端用户界面集合。 简单来说 inquirer 是可以让我们很方便的做各种终端交互行为的一个库。
inquirer 主要提供了三个方法方便我们注册问题
#!/usr/bin/env node const 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()
在用户输入答案之后,开始下载模板,这时候使用 ora
来提示用户正在下载中。
注意:注意版本不同引入方式不同,这里用ora
(版本5.4.1) ,chalk
package.json
을 생성합니다. 이때, bin 구성 객체가 있을 것입니다. 키 값은 전역 스캐폴딩 이름이고, 값은 항목 파일 bin 파일의 index.js
경로입니다. 🎜🎜🎜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)
mycli
가 인쇄되면 연결이 성공한 것입니다. 🎜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()
#!/usr/bin/env node console.log("adas"); require("../lib/commander/index.js")
commander
: 명령줄 도구로, 명령줄 명령을 읽고 사용자가 무엇을 원하는지 알 수 있습니다🎜🎜 inquirer</ code>: 사용자에게 아름다운 인터페이스와 질문을 제기할 수 있는 방법을 제공하는 대화형 명령줄 도구🎜🎜<code>download-git-repo
: 원격 창고 다운로드를 담당하는 원격 템플릿 도구 다운로드 템플릿 프로젝트 🎜🎜 분필
: 명령줄 출력 스타일을 수정하고, 명확하고 직관적인 색상을 통해 정보와 오류 로그를 구별하는 데 사용되는 색상 플러그인 🎜🎜ora
: 로딩 표시에 사용 효과는 프런트 엔드 페이지의 로딩 효과와 유사합니다. 템플릿 다운로드와 같이 시간이 많이 걸리는 작업의 경우 로딩 효과가 사용자에게 진행 중임을 알려줄 수 있습니다. 인내심을 갖고 기다려 주세요🎜🎜figlet
: 빈 글꼴 스타일🎜 🎜index.js
에 배치됩니다.commander.js
는 노드의 명령줄 프로그램을 빌드하는 데 사용되는 도구로, 사용자 정의 지침을 사용하여 노드 스크립트를 실행할 수 있습니다. 글로벌 명령줄. 원래는 스크립트가 위치한 파일의 루트 디렉터리에 있는 node xxx.js
를 통해서만 스크립트를 실행할 수 있었습니다. Commander를 통해 명령줄 프로그램을 빌드한 후에는 어떤 디렉터리에서든 실행할 수 있습니다. 데스크탑과 같은 사용자 디렉토리와 같은 사용자 정의 명령을 직접 입력하면 스크립트를 직접 실행하는 것이 더 쉽습니다. 🎜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 <framork> [other...]', '设置框架', getFramwork) } const createProgress = function (program) { program.command('create <progress> [other...]') .alias('crt') .description('创建项目') .action((progress, arg) => { init(); }) } const downloadUrl = function (program) { program.command('download <url> [...other]') .description('下载内容') .action((url, ...args) => { console.log(args); downloadFun(url, args[1].args[1]) }) } myhelp(program); downloadUrl(program); createProgress(program) program.parse(process.argv)
mycli
를 실행하면 모든 명령이 출력됩니다~~🎜🎜🎜다운로드</code >(저장소, 대상, 옵션, 콜백)🎜🎜<code>저장소
: 다운로드 주소🎜🎜대상
: 다운로드 경로🎜🎜옵션
: 구성 항목 { clone: true}🎜🎜callback
: 다운로드 후 콜백🎜🎜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
mycli
를 실행하면 xxx
파일이 생성된 것을 볼 수 있습니다. 파일🎜 🎜🎜< h4 data -id="heading-5">2.3 Inquirer(명령 상호작용)🎜🎜inquirer🎜는 일반적으로 사용되는 대화형 터미널 사용자 인터페이스 모음입니다. 간단히 말해서 🎜inquirer🎜는 다양한 터미널 대화형 동작을 쉽게 수행할 수 있게 해주는 라이브러리입니다. 🎜🎜inquirer는 질문 등록을 용이하게 하기 위해 주로 세 가지 방법을 제공합니다.🎜🎜🎜🎜prompt(questions) => promise🎜 이 방법은 터미널 상호 작용의 핵심 방법입니다. 프롬프트 방법을 실행하면 터미널에 대화형 명령 인터페이스가 시작됩니다. - 프롬프트 메소드는 🎜questions🎜 배열을 전달해야 합니다. 질문 배열에는 각 질문이 개체 형태로 포함됩니다. 질문의 특정 구조 필드의 의미는 나중에 소개됩니다. - 프롬프트 메소드의 반환 값은 promise 개체이고 promise.then에서 받은 반환 값은 🎜answers🎜 개체입니다. Answers 개체에는 이전 질문에 대한 답변의 데이터 결과가 포함됩니다. 🎜🎜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;
ora<를 사용하세요. /code>를 입력하면 사용자에게 다운로드 중이라는 메시지가 표시됩니다. 🎜🎜참고: 버전마다 소개 방법이 다릅니다. 여기서는 <code>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)
镂空文字调试器地址:地址
figle
t旨在完全实现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()
bin/index.js
#!/usr/bin/env node console.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 <framork> [other...]', '设置框架', getFramwork) } const createProgress = function (program) { program.command('create <progress> [other...]') .alias('crt') .description('创建项目') .action((progress, arg) => { init(); }) } const downloadUrl = function (program) { program.command('download <url> [...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 教程!
위 내용은 비계는 왜 필요한가? 노드에 스캐폴딩을 구축하는 단계에 대한 자세한 설명의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!