Maison > Article > interface Web > Pourquoi un échafaudage est-il nécessaire ? Explication détaillée des étapes pour construire un échafaudage dans node
Pourquoi un échafaudage est-il nécessaire ? Comment construire un échafaudage ? L'article suivant présente les étapes de construction d'un échafaudage sur Node. J'espère qu'il sera utile à tout le monde !
Créez un nouveau dossier mycli
(le nom du fichier peut être personnalisé) et créez un nouveau bin
ci-dessous, Créez un nouveau fichier bin
appelé index.js
Ce index.js
est le fichier d'entrée Ajouter. à l'en-tête du fichier <code>index.js
. #!/usr/bin/env node code 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
À ce stade, il y aura un objet de configuration bin. La valeur clé est le nom global de l'échafaudage et la valeur est le chemin index.js
du fichier bin du fichier d'entrée. 🎜🎜🎜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)🎜🎜🎜🎜 🎜Liez la commande globale d'échafaudage à la commande globale Si le terminal imprime
mycli
, le lien est réussi. 🎜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()🎜🎜🎜Dépendances d'installation🎜🎜🎜
#!/usr/bin/env node console.log("adas"); require("../lib/commander/index.js")🎜🎜
commander
: outil de ligne de commande, avec lequel nous pouvons lire les commandes de ligne de commande et savoir ce que l'utilisateur veut faire🎜🎜 demandeur code> : Un outil de ligne de commande interactif qui offre aux utilisateurs une belle interface et un moyen de soulever des questions🎜🎜<code>download-git-repo
: Téléchargez l'outil de modèle à distance, responsable du téléchargement des entrepôts distants. Projet de modèle 🎜🎜 chalk
: plug-in de couleur, utilisé pour modifier le style de sortie de la ligne de commande, distinguer les informations et les journaux d'erreurs grâce à la couleur, clair et intuitif 🎜🎜ora
: utilisé pour afficher le chargement L'effet est similaire à l'effet de chargement de la page frontale. Pour les opérations fastidieuses telles que le téléchargement de modèles, l'effet de chargement peut rappeler à l'utilisateur qu'il est en cours. Veuillez patienter🎜🎜figlet
. : style de police creux🎜 🎜index.js
pour le débogagecommander.js
est un outil utilisé pour créer le programme de ligne de commande d'un nœud, permettant l'utilisation d'instructions personnalisées pour exécuter des scripts de nœud sur la ligne de commande globale. À l'origine, nous ne pouvions exécuter le script que via node xxx.js
dans le répertoire racine du fichier où se trouve le script. Après avoir construit le programme en ligne de commande via Commander, nous pouvons l'exécuter dans n'importe quel répertoire. comme le bureau, comme le répertoire utilisateur, entrez simplement la commande personnalisée directement pour exécuter le script directement, ce qui est plus simple. 🎜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)🎜Exécutez la commande globale
mycli
pour afficher toutes les commandes~~🎜🎜🎜télécharger
(dépôt, destination, options, rappel)🎜🎜dépôt
: adresse de téléchargement🎜🎜destination
: chemin de téléchargement🎜🎜options
: élément de configuration { clone: true}🎜🎜callback
: rappel après téléchargement🎜🎜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🎜Exécutez
mycli
et vous verrez un fichier xxx
généré sous le fichier🎜 🎜🎜2.3 Inquirer (interaction avec les commandes)🎜🎜inquirer🎜 est une collection d'interfaces utilisateur de terminaux interactifs couramment utilisées. En termes simples, 🎜inquirer🎜 est une bibliothèque qui nous permet d'effectuer facilement divers comportements interactifs de terminal. 🎜🎜inquirer fournit principalement trois méthodes pour nous faciliter l'enregistrement des questions🎜🎜🎜🎜prompt(questions) => promise🎜Cette méthode est la méthode principale de l'interaction du terminal. L'exécution de la méthode prompt indique au terminal de démarrer l'interface de commande interactive. - La méthode prompt doit passer dans un tableau 🎜questions🎜. Le tableau questions contient chaque question sous forme d'objets. La signification des champs de structure spécifiques de la question sera présentée plus tard. - La valeur de retour de la méthode prompt est un objet de promesse, et la valeur de retour reçue par promise.then est l'objet 🎜answers🎜. L'objet de réponses contient les résultats des données des réponses à toutes les questions précédentes. 🎜🎜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<.> pour inviter l'utilisateur à télécharger. 🎜🎜Remarque : Notez que différentes versions ont des méthodes d'introduction différentes. Ici, nous utilisons <code>ora
(version 5.4.1), chalk
(version 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 教程!
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!