Возможно, вы использовали множество инструментов для построения скаффолдинга. Вы когда-нибудь задумывались, как написать скаффолдинг, который принадлежит вам?
Инструменты формирования зависимостей
commander.jsинструмент командной строки
download-git-repoскачать код репозитория git
chalkУлучшение стиля вывода командной строки
Inquirer.jsвзаимодействие с командной строкой
oraЭффект загрузки командной строки
Строительство проекта
Инициализировать проект
Выполнить после создания каталога проектаnpm init
Следуйте инструкциям, чтобы завершить проект инициализации.
Установить зависимости
Установите зависимости скаффолдинга, о которых мы упоминали выше, и выполнитеnpm install chalk commander download-git-repo inquirer ora --save
Заканчивать
Установить.
Структура проекта
После инициализации проекта создайтеbin
документы иcommands
документ. Файл bin — это каталог ввода исполняемых команд, а commands отвечает за запись некоторых командных взаимодействий.
файл react-cli в каталоге bin
#!/usr/bin/env node
process.env.NODE_PATH = __dirname + '/../node_modules/'
const { resolve } = require('path')
const res = command => resolve(__dirname, '../commands/', command)
const program = require('commander')
program.version(require('../package').version )
program.usage('<command>')
program.command('init')
.option('-f, --foo', 'enable some foo')
.description('Generate a new project')
.alias('i')
.action(() => {
require(res('init'))
})
if(!program.args.length){
program.help()
}
создать этоreact-cli.js
Это исполняемый файл ввода команды, который определяет команду «инициализация».После выполнения команды он перейдет в каталог команд, чтобы найти соответствующую команду.init.js
документ
файл init в каталоге команд
const {prompt} = require('inquirer')
const program = require('commander')
const chalk = require('chalk')
const download = require('download-git-repo')
const ora = require('ora')
const fs = require('fs')
const path = require('path')
const option = program.parse(process.argv).args[0]
const defaultName = typeof option === 'string' ? option : 'react-project'
const tplList = require(`${__dirname}/../templates`)
const tplLists = Object.keys(tplList) || [];
const question = [
{
type: 'input',
name: 'name',
message: 'Project name',
default: defaultName,
filter(val) {
return val.trim()
},
validate(val) {
const validate = (val.trim().split(" ")).length === 1
return validate || 'Project name is not allowed to have spaces ';
},
transformer(val) {
return val;
}
}, {
type: 'list',
name: 'template',
message: 'Project template',
choices: tplLists,
default: tplLists[0],
validate(val) {
return true;
},
transformer(val) {
return val;
}
}, {
type: 'input',
name: 'description',
message: 'Project description',
default: 'React project',
validate (val) {
return true;
},
transformer(val) {
return val;
}
}, {
type: 'input',
name: 'author',
message: 'Author',
default: 'project author',
validate (val) {
return true;
},
transformer(val) {
return val;
}
}
]
module.exports = prompt(question).then(({name, template, description, author}) => {
const projectName = name;
const templateName = template;
const gitPlace = tplList[templateName]['place'];
const gitBranch = tplList[templateName]['branch'];
const spinner = ora('Downloading please wait...');
spinner.start();
download(`${gitPlace}${gitBranch}`, `./${projectName}`, (err) => {
if (err) {
console.log(chalk.red(err))
process.exit()
}
fs.readFile(`./${projectName}/package.json`, 'utf8', function (err, data) {
if(err) {
spinner.stop();
console.error(err);
return;
}
const packageJson = JSON.parse(data);
packageJson.name = name;
packageJson.description = description;
packageJson.author = author;
var updatePackageJson = JSON.stringify(packageJson, null, 2);
fs.writeFile(`./${projectName}/package.json`, updatePackageJson, 'utf8', function (err) {
if(err) {
spinner.stop();
console.error(err);
return;
} else {
spinner.stop();
console.log(chalk.green('project init successfully!'))
console.log(`
${chalk.bgWhite.black(' Run Application ')}
${chalk.yellow(`cd ${name}`)}
${chalk.yellow('npm install')}
${chalk.yellow('npm start')}
`);
}
});
});
})
})
1.program.parse(process.argv)
Параметры, переданные при выполнении init, могут быть проанализированы.Мы можем получить этот параметр как имя каталога, созданного проектом.Если этот параметр не передается, установите для него имя каталога по умолчанию.
2.Интерактивные вопросы и ответы в командной строке
-
question
Массив настроен на интерактивные команды, и каждый объект в массиве соответствует проблеме при выполнении команды -
type
для типа вопроса,name
Для имени вопроса пользователь, который может получить вопрос через имя, позже вводит ответ. -
message
подсказки к вопросам -
default
предоставлять ответ пользователю по умолчанию, когда он не вводит -
validate
Метод может проверить содержимое, введенное пользователем. Если он возвращает true, проверка пройдена. Если он неверен, он может вернуть соответствующий строковый текст подсказки. -
transformer
После того, как пользователь вводит ответ на вопрос, соответствующий ответ отображается на позиции вопроса, и требуется возвращаемое значение, а возвращаемая строка является отображаемым содержимым.специальная документация
3.Обратный звонок по окончании вопросов и ответов
- Параметр в методе приглашения представляет собой объект, из которого вы можете получить содержимое пользовательского ввода, определяемое именем вопроса.
- В соответствии с содержимым, введенным пользователем, для него может быть сгенерирован шаблон загрузки, который используется здесь.
download-git-repo
Инструмент для загрузки кода репозитория git - Первым параметром метода загрузки является местоположение загружаемого репозитория кода.Если это репозиторий кода GitHub, вам нужно только написать имя пользователя и имя проекта, например
'Hzy0913/react-template'
То есть загрузить код мастера склада.Если вам нужно переключить соответствующую ветку, добавьте название соответствующей ветки после адреса склада, например'Hzy0913/react-template#complete'
. - Вторым параметром метода загрузки является имя файла сгенерированного файла загрузки. Я сохраняю его в каталоге выполнения команды. В имени файла используется имя, введенное пользователем. Например, параметр
'./projectName'
, Для генерации соответствующего имени файла в текущем каталоге выполняют команду. -
ora
Модуль может генерировать вращающийся значок для нас при загрузке.Первый параметр, передаваемый методом ora, — это подсказка при ожидании и создании экземпляра.Вызовите метод start() для объекта экземпляра, чтобы запустить вращающуюся анимацию и подсказку, и метод stop() останавливается. - После загрузки шаблона его необходимо
package.json
Файл генерирует определяемый пользователем входной контент, узлыfs
модульныйreadFileметод может помочь нам получить содержимое сгенерированного файла,writeFileтогда вы можете написать контент - После окончательного завершения вы можете использовать консольный метод на панели командной строки, чтобы дать некоторые подсказки,
chalk
Модули могут помочь нам украсить наш вывод.
Пример кода скаффолдинга в статье можно увидетьbuild-react-cli
Тестирование и выпуск инструмента
- В процессе написания неизбежно тестирование локально, потому что сам проект является инструментом node, мы можем выполнить его в каталоге проекта.
node bin/react-cli
бегать. - Конечно, эту команду нельзя использовать после публикации, в это время перед публикацией добавьте
package.json
серединаbin
Object, Key — имя, исполняемое сценарием, а Value — каталог выполнения, например"bin": {"build-react": "bin/react-cli"}
, что эквивалентно выполнению при входе в build-reactnode bin/react-cli
Команда, когда мы устанавливаем скаффолдинг глобально, содержимое объекта bin может стать глобальной исполняемой командой. - Публикация пакетов npm.Публиковать пакеты npm очень просто.После регистрации учетной записи npm вы можете войти в систему локально и выполнить ее в каталоге проекта.
npm publish
Вы можете опубликовать его. Обратите внимание, что имя пакета не может совпадать с именем в существующем npm. Его необходимо изменять каждый раз, когда выпускается новая версия пакета.package.json
Номер версии в опубликованном пакете можно удалить только в течение 24 часов.
Наконец, я рекомендую два инструмента для создания лесов, которые я пишу.
Сверхпростое междоменное, внешнее и внутреннее решение LiveNode для междоменного разделения