為什麼需要腳手架?詳解node建造鷹架的步驟
為什麼需要鷹架?怎麼搭建鷹架?以下這篇文章介紹node建置鷹架的步驟,希望對大家有幫助!
1 為什麼需要腳手架
- 根據互動動態產生專案結構和設定檔等。
- 使用者透過指令互動的方式下載不同的模版
- 經過模版引擎渲染自訂專案模版
- 模版變動,只需更新模版即可,不需要使用者更新鷹架【相關教學推薦:nodejs影片教學、程式設計教學】
#2 建置步驟
-
檔案新建#新建
mycli資料夾(可自訂檔案名稱),下方新建
bin文件,
bin index.js - ,這個
index.js
程式碼就是入口文件,
index.js文件頭加入
#!/usr/bin/env node
產生
- 文件,此時會有個bin配置對象,key值即為全域腳手架名稱,value是入口文件bin文件的
- index.js
路徑。
npm init -y npm install
登入後複製
- mycli
- 即連結成功。
<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class='brush:php;toolbar:false;'>//命令可以将一个任意位置的npm包链接到全局执行环境,从而在任意位置使用命令行都可以直接运行该npm包。 npm link</pre><div class="contentsignin">登入後複製</div></div>
- 安裝依賴
commander
:命令列工具,有了它我們就可以讀取命令列命令,知道使用者想要做什麼了 inquirer
:互動式命令列工具,提供使用者一個漂亮的介面和提出問題流的方式download-git-repo
:下載遠端模板工具,負責下載遠端倉庫的模板項目chalk
:顏色插件,用來修改命令列輸出樣式,透過顏色區分info、error 日誌,清晰直覺
npm install commander inquirer@8.2.5 download-git-repo chalk@4.1.2 ora@5.4.1 figlet handlebars
ora
:用來顯示載入中的效果,類似前端頁面的loading 效果,像下載範本這種耗時的操作,有了loading 效果可以提示使用者正在進行中,請耐心等待
figlet :鏤空字體樣式注意:下方程式碼都放在bin檔案
index.js
2.1 commander.js概述
#commander.js是一個工具,用來建立node的命令列程序,使得能夠使用自訂指令在全域命令列運行node腳本。本來我們只能在腳本所在檔案的根目錄裡透過
運行腳本,透過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
即可輸出所有指令~~
#2.2 download-git-repo
-
#download
(repository, destination, options, callback) repository
:下載位址destination
:下載路徑
options
:設定項{clone:true}
:下載後的回呼
#!/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檔案
#2.3 Inquirer(指令互動)- inquirer 是一個常用的互動式終端使用者介面集合。簡單來說 inquirer 是可以讓我們很方便的做各種終端互動行為的一個函式庫。 inquirer 主要提供了三個方法方便我們註冊問題
該方法就是終端交互的核心方法,運行prompt 方法即告訴終端啟動互動式命令介面。 - prompt 方法需要傳入一個 questions
數組, questions 數組包含物件形式的各個 question. question 的具體結構字段含義在後文介紹。 - prompt 方法的回傳值是 promise 對象,promise.then 接收的回傳值是
對象,answers 物件包含前面所有問題回答的資料結果。
#!/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()
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(镂空文字)
镂空文字调试器地址:地址
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 教程!
以上是為什麼需要腳手架?詳解node建造鷹架的步驟的詳細內容。更多資訊請關注PHP中文網其他相關文章!

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)