⚠️ Эта статья является первой подписанной статьей сообщества Nuggets, и ее перепечатка без разрешения запрещена.
предисловие
Настоящая битва фронтенд-инжиниринга дошла до третьей статьи, в первых двух статьях были построены простые строительные леса React и предварительно доступный инструмент CLI соответственно.
После того, как основные строительные леса завершены, мы можем приступить к разработке управления шаблонами.Ведь в реальных условиях набор строительных лесов далек от удовлетворения потребностей.Мы будем сталкиваться с различными бизнес-сценариями, и для этих сценариев могут быть нестандартные строительные леса.
Так как же нам управлять этими лесами?
особенности дизайна
если каждый разРазработка новых строительных лесов или обновление шаблоновЕсли вам нужно снова обновить CLI, хотя стоимость невелика, учащиеся, разрабатывающие шаблон, должны уведомить учащихся, разрабатывающих CLI, об обновлении, а учащиеся, использующие шаблон, должны дождаться разработки CLI. прежде чем они смогут его использовать, что увеличивает стоимость промежуточной связи.
Во-вторых, для студентов, изучающих бизнес-развитие, может потребоваться только один или несколько типов шаблонов.Если CLI представляет собой большую и всеобъемлющую коллекцию шаблонов, для этих студентов сложно быстро выбрать шаблоны для создания проектов, потому что им это нужно. также требуется время, чтобы выбрать то, что вы хотите из множества шаблонов.
Итак, наша цель — разработатьПользовательская конфигурация и обновляемые шаблоныФункциональный инструмент командной строки.
Поскольку это настраиваемая конфигурация, пользователям необходимо вручную добавлять, удалять и обновлять информацию о часто используемых шаблонах локально, и в то же время им необходимо иметь возможность динамически извлекать эти шаблоны, а не загружать их все время, что старая локальная версия.
В соответствии с вашими потребностями вы можете просто спроектировать схему функций шаблона нашего интерфейса командной строки:
- Адрес, по которому необходимо сохранить исходный код шаблона
- Извлеките другой код шаблона в соответствии с выбором пользователя
- Сохраните шаблон локально
фактическое развитие
Затем в соответствии с приведенными выше дизайнерскими идеями мы можем шаг за шагом разработать необходимые функции.
Функция адреса локального сохранения шаблона
Первый шаг, если нам нужно сохранить некоторую информацию о шаблоне локально, нам нужно диалоговое взаимодействие, чтобы помочь пользователю ввести нужную нам информацию, чтобы мы могли выбратьinquirerэта библиотека инструментов.
Inquirerjs
представляет собой набор инструментов, используемых для реализации интерактивного интерфейса командной строки. Это помогает нам добиться интерактивного общения с пользователями, например, задать вопрос пользователю, пользователь дает нам ответ, и мы делаем что-то в соответствии с ответом пользователя, типичные приложения, такие какplop
и другие инструменты генератора.
В общем, чтобы вытащить код, нам нужно знать введенный пользователем адрес шаблона (необходимое условие для вытягивания соответствующего шаблона через URL), псевдоним шаблона (удобно для поиска пользователями), описание шаблона (удобно для понимания пользователями информация о шаблоне)
Таким образом, информация о шаблоне, которую необходимо сохранить, включает адрес, псевдоним и описание, что может облегчить нам управление соответствующим шаблоном в будущем. Пример кода выглядит следующим образом:
import inquirer from 'inquirer';
import { addTpl } from '@/tpl'
const promptList = [
{
type: 'input',
message: '请输入仓库地址:',
name: 'tplUrl',
default: 'https://github.com/boty-design/react-tpl'
},
{
type: 'input',
message: '模板标题(默认为 Git 名作为标题):',
name: 'name',
default({ tplUrl }: { tplUrl: string }) {
return tplUrl.substring(tplUrl.lastIndexOf('/') + 1)
}
},
{
type: 'input',
message: '描述:',
name: 'desc',
}
];
export default () => {
inquirer.prompt(promptList).then((answers: any) => {
const { tplUrl, name, desc } = answers
addTpl(tplUrl, name, desc)
})
}
пройти черезinquirer
Соответствующая информация была получена, но из-за различных ситуаций, таких как перезагрузка компьютера, неудобно хранить данные в кеше.Этот инструмент CLI является излишним, если он использует базу данных для хранения, поэтому информация может храниться непосредственно в json файл способ локального хранения.
Пример кода выглядит следующим образом:
import { loggerError, loggerSuccess, getDirPath } from '@/util'
import { loadFile, writeFile } from '@/util/file'
interface ITpl {
tplUrl: string
name: string
desc: string
}
const addTpl = async (tplUrl: string, name: string, desc: string) => {
const cacheTpl = getDirPath('../cacheTpl')
try {
const tplConfig = loadFile<ITpl[]>(`${cacheTpl}/.tpl.json`)
let file = [{
tplUrl,
name,
desc
}]
if (tplConfig) {
const isExist = tplConfig.some(tpl => tpl.name === name)
if (isExist) {
file = tplConfig.map(tpl => {
if (tpl.name === name) {
return {
tplUrl,
name,
desc
}
}
return tpl
})
} else {
file = [
...tplConfig,
...file
]
}
}
writeFile(cacheTpl, '.tpl.json', JSON.stringify(file, null, "\t"))
loggerSuccess('Add Template Successful!')
} catch (error) {
loggerError(error)
}
}
export {
addTpl,
}
Здесь нам нужно принять простое решение о том, следует ли сохранять или обновлять шаблон:
- Определить, существует ли в данный момент файл кеша tpl.Если файл кеша есть, то его нужно объединить с текущей информацией шаблона.Если его нет, то нужно создать файл и сохранить полученную информацию.
- Если в настоящее время есть файл кеша, вам необходимо
name
Считается, что он был закэширован. Если он закэширован, он будет определен в соответствии сname
для обновления соответствующей информации шаблона.
Далее давайте продемонстрируем использованный эффект.
Следуя предыдущим шагам, после создания CLI запуститеfe-cil add tpl
Можно получить следующие результаты:
Затем в соответствующем пути вы можете увидеть, что эта информация о шаблоне была кэширована.
Как и выше, мы выполнили простую функцию локального добавления и изменения информации о шаблоне, и удаление также является аналогичной операцией, которую можно разработать в соответствии с вашими реальными потребностями.
Скачать шаблон
После сохранения шаблона нам нужно выбрать соответствующий шаблон для загрузки.
доступна загрузкаdownload-git-repoКак плагин, загружаемый CLI, это очень полезный плагин, который поддерживает загрузку соответствующего шаблона без клона, что очень подходит для нашего проекта.
download-git-repo
Это библиотека инструментов для загрузки репозитория git.Он предоставляет два метода: сокращенный и прямой: прямая загрузка URL.Он также предоставляет функцию прямой загрузки кода и клонирования git, который очень прост в использовании.
Так же при скачивании шаблонов нам нужно показать пользователю текущий список сохраненных шаблонов, который здесь тоже нужно использовать.inquirer
инструмент.
- использовать
inquirer
Создайте список для выбора интерактивного режима, прочитайте локальный список шаблонов и позвольте пользователю выбрать нужный шаблон.
export const selectTpl = () => {
const tplList = getTplList()
const promptList = [
{
type: 'list',
message: '请选择模板下载:',
name: 'name',
choices: tplList && tplList.map((tpl: ITpl) => tpl.name)
},
{
type: 'input',
message: '下载路径:',
name: 'path',
default({ name }: { name: string }) {
return name.substring(name.lastIndexOf('/') + 1)
}
}
];
inquirer.prompt(promptList).then((answers: any) => {
const { name, path } = answers
const select = tplList && tplList.filter((tpl: ITpl) => tpl.name)
const tplUrl = select && select[0].tplUrl || ''
loadTpl(name, tplUrl, path)
})
}
- использовать
download-git-repo
Скачайте соответствующий шаблон
export const loadTpl = (name: string, tplUrl: string, path: string) => {
download(`direct:${tplUrl}`, getCwdPath(`./${path}`), (err: string) => {
if (err) {
loggerError(err)
} else {
loggerSuccess(`Download ${name} Template Successful!`)
}
})
}
Но вот вопрос, если вы выберетеdirect
режиме, то вместо обычного git-адреса загружается почтовый адрес, тогда наш указанный выше адрес недействителен, поэтому нам нужно выполнить преобразование уровня адреса перед официальной загрузкой кода.
Сначала посмотрите на правила извлечения, обычный адрес git:https://github.com/boty-design/react-tpl
, а фактический адрес загрузки в github:https://codeload.github.com/boty-design/react-tpl/zip/refs/heads/main
, вы можете видеть, что по сравнению с обычной ссылкой на github имя домена и ссылка изменились, но должно быть имя проекта и имя команды, чтобы мы могли хранитьboty-design/react-tpl
Выньте его для облегчения сборки позже.
const { pathname } = new URL(tplUrl)
if (tplUrl.includes('github.com')) {
reTpl.org = pathname.substring(1)
reTpl.downLoadUrl = 'https://codeload.github.com'
}
Как и в приведенном выше коде, синтаксический анализtplUrl
получилpathname
Это информация, которая нам нужна, и когда мы загрузим шаблон, мы сможем снова собрать ссылку для скачивания.
Как показано на рисунке выше, мы можем загрузить общедоступный шаблон в локальный, что удобно для студентов, чтобы нормально развиваться, но на данный момент все еще есть проблема, то есть указанная выше ветка является основной веткой, а не каждый шаблон есть эта ветка, управляемость Жалко, так как же заставить все ветки проекта выборочно скачивать.
Github Api
Для открытых, не частных проектов в Github вы можете пропустить этап авторизации токена и напрямую использовать Github Api для получения соответствующей информации.
Таким образом, для решения упомянутых выше проблем мы можем использовать возможности, предоставляемые Github Api.
Ссылка для получения веткиhttps://api.github.com/repos/boty-design/react-tpl/branches
, мы можем использовать PostMan, чтобы проверить, возвращает ли он результаты, которые нам обычно нужны, до начала разработки.
Как вы можете видеть выше, мы уже можем получить нужную информацию о ветке через Github Api.
Если возникает следующая ошибка, не беда, просто гитхаб ограничивает частоту доступа
В ответ на вышеуказанные проблемы нам нужно контролировать частоту, использовать условные запросы или использовать токены для запроса Github Api, чтобы избежать, но с учетом шаблонов общая частота запросов не очень высока, но мне это нужно при разработке Такая проблема возникает только после постоянных запросов на тестирование.Если вам интересно, вы можете попробовать другие решения самостоятельно.
Оптимизация кода филиала
После предварительного исследования Github Api следующим шагом является инкапсуляция полученной информации.Например, когда есть только одна ветка, пользователь может напрямую загрузить шаблон.Если запрашивается несколько веток, ветка должна отображаться для позвольте пользователю свободно выбрать соответствующую ветвь для загрузки шаблона, и общая схема бизнес-процесса показана выше.
Основной логический код выглядит следующим образом:
export const selectTpl = async () => {
const prompts: any = new Subject();
let select: ITpl
let githubName: string
let path: string
let loadUrl: string
try {
const onEachAnswer = async (result: any) => {
const { name, answer } = result
if (name === 'name') {
githubName = answer
select = tplList.filter((tpl: ITpl) => tpl.name === answer)[0]
const { downloadUrl, org } = select
const branches = await getGithubBranch(select) as IBranch[]
loadUrl = `${downloadUrl}/${org}/zip/refs/heads`
if (branches.length === 1) {
loadUrl = `${loadUrl}/${branches[0].name}`
prompts.next({
type: 'input',
message: '下载路径:',
name: 'path',
default: githubName
});
} else {
prompts.next({
type: 'list',
message: '请选择分支:',
name: 'branch',
choices: branches.map((branch: IBranch) => branch.name)
});
}
}
if (name === 'branch') {
loadUrl = `${loadUrl}/${answer}`
prompts.next({
type: 'input',
message: '下载路径:',
name: 'path',
default: githubName
});
}
if (name === 'path') {
path = answer
prompts.complete();
}
}
const onError = (error: string) => {
loggerError(error)
}
const onCompleted = () => {
loadTpl(githubName, loadUrl, path)
}
inquirer.prompt(prompts).ui.process.subscribe(onEachAnswer, onError, onCompleted);
const tplList = getTplList() as ITpl[]
prompts.next({
type: 'list',
message: '请选择模板:',
name: 'name',
choices: tplList.map((tpl: ITpl) => tpl.name)
});
} catch (error) {
loggerError(error)
}
}
В приведенном выше коде мы видим, что RXJS используется для динамического рендеринга интерактивных задач, потому что в некоторых случаях существует только одна ветвь проекта шаблона. Если нам нужно, чтобы пользователь каждый раз выбирал ветку, это избыточно и громоздко, поэтому фиксированное взаимодействие на основе вопросов больше не применимо.Нам нужно использовать RXJS для динамического добавления вопроса запрашивающего и оценки возможности выбора ветка отображается по количеству приобретенных веток. , чтобы улучшить взаимодействие с пользователем.
напиши в конце
во-первыхРазработка корпоративного интерфейса командной строки, мы вместе создали предварительную полку CLI, предоставив базовые функции, такие как сборка и проверка Eslint.
во-вторыхПользовательские React Scaffolding и обновления CLIВ , давайте создадим простую структуру React и используем CLI, чтобы взять на себя модуль разработки шаблона и предоставить такие функции, как расширение конфигурации сборки, чтобы завершить интеграцию базового инструмента шаблона CLI.
В этой статье мы используем каркас из предыдущей статьи в качестве шаблона и дополнительно трансформируем CLI, чтобы CLI мог позволить пользователям настраивать шаблоны, отвечающие их собственным потребностям и привычкам.
После этих трех статей в CLI уже есть следующие функции:
CLI-команды | Функции |
---|---|
fe-cli eslint | Проверка текущего проекта с помощью Eslint |
fe-cli webpack | Построить с текущим проектом Webapck |
fe-cli rollup | Построить с помощью Rollup текущий проект |
fe-cli git init | Инициализировать проект git локально (в настоящее время поддерживает некоторые функции GitLab) |
fe-cli add tpl | Добавить пользовательские шаблоны |
fe-cli init tpl | Инициализируйте добавленный шаблон в локальном |
Весь интерфейс командной строки будет разработан в соответствии с требованиями первой статьи и постепенно будет строиться как универсальный и трансформируемый инструмент, который может стать практическим справочником для студентов.
В следующей статье CLI будет разработан на основе модулей, подобных инструментам.
Весь код проекта загружен наадрес проекта, Заинтересованные студенты могут вытащить ссылку, и соответствующие коды всех последующих столбцов будут размещены в единомBOTY DESIGN середина.