предисловие
Скаффолдинг вроде vue-cli, react-native-cli и т. д. с которыми мы знакомы, просто нужно ввести простые командыvue init webpack project
, вы можете быстро помочь нам создать первоначальный проект. В реальной работе мы можем настроить собственные леса, чтобы повысить эффективность нашей работы.
Зачем нужны подмости?
- Сократите повторяющуюся работу, больше не нужно дублировать другие проекты и удалять посторонний код или создавать проект и файлы с нуля.
- Динамически создавать структуры проекта, файлы конфигурации и т. д. на основе взаимодействий.
- Совместная работа нескольких человек более удобна, и нет необходимости передавать файлы туда и обратно.
идеи
Чтобы разработать строительные леса, мы должны сначала прояснить свое мышление.Как работают строительные леса? Мы можем извлечь уроки из основных идей vue-cli. vue-cli помещает шаблон проекта в git, а затем загружает различные шаблоны в соответствии с действиями пользователя при запуске и отображает их через механизм шаблонов для создания проекта. Таким образом, шаблон и леса можно разделить, чтобы их можно было поддерживать отдельно.Даже если шаблон изменится, необходимо загрузить только последний шаблон, и последний проект может быть сгенерирован без необходимости обновления пользователем шаблонов. . Затем его можно развивать в соответствии с этой идеей.
сторонняя библиотека
Во-первых, давайте посмотрим, какие библиотеки будут использоваться.
- commander.js, который может автоматически анализировать команды и параметры для обработки команд, введенных пользователями.
- download-git-repo, загрузите и извлеките репозиторий git для загрузки шаблонов проектов.
- Inquirer.js, набор универсальных пользовательских интерфейсов командной строки для взаимодействия с пользователями.
- handlebars.js, механизм шаблонов, который динамически заполняет файл информацией, предоставленной пользователем.
- ora, если процесс загрузки длительный, его можно использовать для отображения анимационного эффекта во время загрузки.
- chalk, вы можете добавить цвет к шрифту терминала.
- log-symbolsи такие значки, как √ или ×, могут отображаться на терминале.
Инициализировать проект
Сначала создайте пустой проект с временным именем okii-cli, затем создайте новый файл index.js, а затем выполните npm init для создания файла package.json. Наконец, установите зависимости, необходимые выше.
npm install commander download-git-repo inquirer handlebars ora chalk log-symbols -S
Обработать командную строку
Node.js имеет встроенную поддержку операций командной строки.Поле bin в package.json может определять имя команды и связанный с ней исполняемый файл. Теперь добавьте содержимое bin в package.json:
{
"name": "okii-cli",
"version": "1.0.0",
"description": "基于node的脚手架工具",
"bin": {
"okii": "index.js"
},
...
}
Затем определите команду инициализации в index.js:
#!/usr/bin/env node
const program = require('commander');
program.version('1.0.0', '-v, --version')
.command('init <name>')
.action((name) => {
console.log(name);
});
program.parse(process.argv);
передачаversion('1.0.0', '-v, --version')
Добавит к команде -v и --version, с этими параметрами можно распечатать номер версии.
передачаcommand('init <name>')
Определите команду init, а name — обязательный параметр, то есть имя проекта.action()
Это поведение будет происходить при выполнении команды init.Здесь выполняется процесс создания проекта, и пока печатается только имя.
На самом деле здесь уже можно выполнить
команда инициализации. Давайте протестируем его и выполним в том же каталоге okii-cli:
node ./okii-cli/index.js init HelloWorld
Вы можете видеть, что инструмент командной строки также распечатываетHelloWorld
, тогда понятно,action((name) => {})
Здесь имя параметра, введите имя проекта, это реализация команды инициализации.
Команда выполнена, и следующим шагом является загрузка шаблона для создания структуры проекта.
Скачать шаблон
download-git-repo поддерживает загрузку репозиториев с Github, Gitlab и Bitbucket, Информацию об использовании каждого из них см. в официальной документации.
Поскольку это проект компании, репозиторий шаблонов размещается на Gitlab, затем в action() выполняется операция по скачиванию шаблона:
#!/usr/bin/env node
const program = require('commander');
const download = require('download-git-repo');
program.version('1.0.0', '-v, --version')
.command('init <name>')
.action((name) => {
download('http://xxxxxx:9999:HTML5/H5Template#master', name, {clone: true}, (err) => {
console.log(err ? 'Error' : 'Success')
})
});
program.parse(process.argv);
download()
Первый параметр — это адрес склада, но он немного другой. Фактический адрес складаhttp://xxxxxx:9999/HTML5/H5Template#master , вы можете видеть, что '/' после номера порта должен быть записан как ':' в параметре, #master представляет имя ветки, разные шаблоны могут быть размещены в разных ветках, и ветку можно легко изменить. Вы можете скачать различные файлы шаблонов. Второй параметр это путь, выше мы создаем прямо под текущим путем
В папке name хранятся шаблоны, или вы можете использовать дополнительные каталоги, такие какtest/${name}
взаимодействие с командной строкой
Функция взаимодействия с командной строкой может задавать вопросы пользователю после того, как пользователь выполнит команду инициализации, получит ввод пользователя и выполнит соответствующую обработку. Это реализовано с помощью inquirer.js.
const inquirer = require('inquirer');
inquirer.prompt([
{
type: 'input',
name: 'author',
message: '请输入作者名称'
}
]).then((answers) => {
console.log(answers.author);
})
Как видно из приведенного здесь примера, вопрос помещается в prompt(), тип вопроса является входным, который является типом ввода, имя является ключом в объекте ответа, сообщение является вопросом, а ответ, введенный пользователем, находится в ответах. Это так просто. Дополнительные настройки параметров см. в официальной документации.
Через взаимодействие с командной строкой пользовательский ввод получается, так что ответ может быть отображен в шаблоне.
шаблон рендеринга
Здесь используйте синтаксис handlebars, чтобы внести некоторые изменения в файл package.json в шаблоне репозитория HTML5/H5Template.
{
"name": "{{name}}",
"version": "1.0.0",
"description": "{{description}}",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "{{author}}",
"license": "ISC"
}
и визуализировать ответ, введенный пользователем, в package.json после завершения загрузки шаблона.
program.version('1.0.0', '-v, --version')
.command('init <name>')
.action((name) => {
inquirer.prompt([
{
name: 'description',
message: '请输入项目描述'
},
{
name: 'author',
message: '请输入作者名称'
}
]).then((answers) => {
download('xxxxx#master',name,{clone: true},(err) => {
const meta = {
name,
description: answers.description,
author: answers.author
}
const fileName = `${name}/package.json`;
const content = fs.readFileSync(fileName).toString();
const result = handlebars.compile(content)(meta);
fs.writeFileSync(fileName, result);
})
})
});
Здесь используется файловый модуль fs из node.js, а шаблон после рендеринга руля перезаписывается в файл.
визуальное благоустройство
После того, как пользователь введет ответ, начните загрузку шаблона, в это время используйте ora, чтобы сообщить пользователю, что идет загрузка.
const ora = require('ora');
// 开始下载
const spinner = ora('正在下载模板...');
spinner.start();
// 下载失败调用
spinner.fail();
// 下载成功调用
spinner.succeed();
Затем используйте мел, чтобы добавить стили к информации о печати, например зеленый для информации об успешном завершении и красный для информации об ошибке, что облегчит пользователям различение, а также сделает отображение терминала более красивым.
const chalk = require('chalk');
console.log(chalk.green('项目创建成功'));
console.log(chalk.red('项目创建失败'));
Помимо добавления цвета к печатным сообщениям, вы можете использовать символы журнала для префикса сообщений такими значками, как √ или ×.
const chalk = require('chalk');
const symbols = require('log-symbols');
console.log(symbols.success, chalk.green('项目创建成功'));
console.log(symbols.error, chalk.red('项目创建失败'));
Полный пример
#!/usr/bin/env node
const fs = require('fs');
const program = require('commander');
const download = require('download-git-repo');
const handlebars = require('handlebars');
const inquirer = require('inquirer');
const ora = require('ora');
const chalk = require('chalk');
const symbols = require('log-symbols');
program.version('1.0.0', '-v, --version')
.command('init <name>')
.action((name) => {
if(!fs.existsSync(name)){
inquirer.prompt([
{
name: 'description',
message: '请输入项目描述'
},
{
name: 'author',
message: '请输入作者名称'
}
]).then((answers) => {
const spinner = ora('正在下载模板...');
spinner.start();
download('http://xxxxxx:9999:HTML5/H5Template#master', name, {clone: true}, (err) => {
if(err){
spinner.fail();
console.log(symbols.error, chalk.red(err));
}else{
spinner.succeed();
const fileName = `${name}/package.json`;
const meta = {
name,
description: answers.description,
author: answers.author
}
if(fs.existsSync(fileName)){
const content = fs.readFileSync(fileName).toString();
const result = handlebars.compile(content)(meta);
fs.writeFileSync(fileName, result);
}
console.log(symbols.success, chalk.green('项目初始化完成'));
}
})
})
}else{
// 错误提示项目已存在,避免覆盖原有项目
console.log(symbols.error, chalk.red('项目已存在'));
}
})
program.parse(process.argv);
Эффект следующий:
После завершения вы можете опубликовать скаффолдинг в npm, установить его глобально с помощью -g и выполнить на своем компьютере.okii init [name]
для инициализации проекта, который завершает простой инструмент создания лесов.