Как и большинство людей, много работающих в области front-end разработки, я признаю, что независимо от того, с каким фреймворком, набором библиотек или инструментов вы работаете, в конечном итоге вы повторяете множество файлов, особенно в современных компонентно-ориентированных фреймворках, таких как React, Angular и Vue.js.
Они обычно становятся очень разными, но почти всегда начинаются с одного и того же базового скелета, который впоследствии наращивается. Написано много конвейерного кода, и время потрачено впустую.
Что у нас есть?
Есть несколько существующих решений этих проблем, но они обычно не очень гибкие, или привязаны к одной библиотеке или реализации. Давайте рассмотрим несколько примеров.
- Сниппеты IDE, такие как расширения/конфигурации простых сниппетов VS Code, очень полезны. По сути, вы можете либо использовать конфигурационные JSON-файлы для быстрого добавления сниппетов в ваш код, либо использовать расширения, которые просто заполняют их за вас.
В этом есть свои преимущества, так как вы можете начать вводить «префикс» сниппета и нажать кнопку Tab быстро добавлять небольшие фрагменты кода. Вы также можете заранее определить точки остановки, по которым можно перемещаться с помощью клавиш Tab после вставки фрагмента, и вставлять аргументы, имена методов и т.д.
Это хорошо, но только для небольших фрагментов. Когда вам нужно создать целый компонент, состоящий из нескольких файлов, вам придется создавать несколько файлов самостоятельно, называть их соответствующим образом и вставлять разные фрагменты в каждый файл.
-
Некоторые библиотеки NPM предоставляют способы создания файлов на основе шаблонов, но из того, что я видел.
- они привязаны к конкретным бегункам задач, библиотекам или фреймворкам
- их сложно устанавливать и настраивать
- объединить весь ваш стек будет непросто
Войдите: Simple Scaffold
Прочитайте документацию по Simple Scaffold
Я был разочарован этим, и все, чего я хотел, это иметь различные наборы файлов, которые я мог бы генерировать, просто копируя их в предопределенные структуры каталогов, и заполнять их некоторыми переменными данными.
Например: На работе я создаю много компонентов React. Недавно мы перешли на однофайловую структуру компонентов для запуска компонентов; но у нас есть разные типы компонентов, которые мы хотим генерировать в зависимости от контекста, например, разное содержимое файлов для контейнеров страниц и компонентов общего назначения.
Будучи сыт по горло вариантами, я создал этот небольшой пакет NPM, который делает именно это, причем очень просто и быстро. Просто поместите свои файлы куда хотите, используйте инструмент CLI или пакет для импорта — и все готово. Он сохраняет структуру входных каталогов/файлов, заменяя маркеры руля внутри имен каталогов/файлов и содержимого файлов.
Простой пример: Посты Jekyll
Создавать посты на Jekyll очень просто! Однако мне все еще не хватало немного — я должен каждый раз вручную добавлять дату? О, черт. А как насчет имени идентификатора файла и заголовка? Мой excerpt_separator
?
Поэтому я сделал простейший скрипт на Ruby (чтобы вписаться в тему Jekyll) для запуска Simple Scaffold CLI с некоторыми пользовательскими параметрами.
#!/usr/bin/env ruby
require "json"
SCAFFOLD_DIR = "scaffold_templates"
*name = ARGV
data = { dateFmt: "yyyy-MM-dd", fullDateFmt: "yyyy-MM-dd HH:mm:ss XX" }
puts `
npx simple-scaffold@latest "#{name.join(" ")}"
--templates #{SCAFFOLD_DIR}/**/*
--output _drafts
--overwrite true
--create-sub-folder false
--data '#{JSON.dump(data)}'
`
puts 'Done'
Давайте быстро пробежимся по этому сценарию:
- Строки 1-7 — настройка локальных параметров, таких как база каталогов шаблонов и некоторые переменные для передачи в шаблоны.
- Строки 9-16 — мы передаем параметры через вызов оболочки (back-ticks в ruby), и сразу запускаем npx.
Locals передаются в Handlebars и могут быть использованы как в именах файлов/каталогов, так и в содержимом файлов.
Теперь мне оставалось только создать место для моих шаблонов и добавить в него шаблон:
- scaffold_templates/
-- {{now dateFmt}}-{{kebabCase name}}.md
И заполнить его некоторыми основными сообщениями:
---
layout: post
title: "{{ startCase name }}"
date: {{ now fullDateFmt }}
excerpt_separator: <!-- more -->
categories:
---
Post content goes here
И вуаля! Запускаем скрипт, вместе с именем:
./scaffold.rb "Billy Jean is not my lover"
Генерирует следующую структуру файлов:
- _posts/
-- 2019-03-06-billy-jean-is-not-my-lover.markdown
---
layout: post
title: 'Billy Jean is not my lover'
date: 2019-03-06 16:43:38 +0200
excerpt_separator: <!-- more -->
categories:
---
Post content goes here
Вы можете сделать больше
Используйте тот же подход и подумайте, для чего вы могли бы создать генераторы с минимальными усилиями. Компоненты React или Vue? Вы можете собрать каждый из них в папку со всеми импортами, экспортами, базовыми реквизитами и т.д., выстроив их в ряд с именем вашего компонента.
Добавьте скрипт в ваш package.json
, пару файлов, и все готово:
package.json
{
"gen:component": "npx simple-scaffold@latest -t scaffold_templates/react-component -o src/components -s true -w true '{"className": "myClassName","author": "Chen Asraf"}'"
}
scaffold_templates/react-component/{{pascalCase name}}.tsx
/**
* Author: {{ author }}
* Date: {{ now "yyyy-MM-dd" }}
*/
import React from 'react'
import { ComponentProps } from 'utils/types'
export interface {{pascalCase name}}Props extends ComponentProps {
className?: string
}
export default {{camelCase name}}: React.FC<{{pascalCase name}}Props> = (props) => {
return (
<div className="{{className}}">{{camelCase name}} Component</div>
)
}
scaffold_templates/react-component/index.ts
export * from './{{pascalCase name}}'
Выполнение npm run gen:component MyComponent
быстро сгенерирует ваши новые компоненты:
src/components/MyComponent/MyComponent.tsx
/**
* Author: Chen Asraf
* Date: 2022-08-10
*/
import React from 'react'
import { ComponentProps } from 'utils/types'
export interface MyComponentProps extends ComponentProps {
className?: string
}
export default MyComponent: React.FC<MyComponentProps> = (props) => {
return (
<div className="myClassName">MyComponent Component</div>
)
}
src/components/MyComponent/index.ts
export * from './MyComponent'
Зачем останавливаться на этом? Создавайте целые шаблоны приложений тем же методом — создайте свое приложение-шаблон, добавьте все библиотеки и замените название приложения на {{name}}
. Вот и все! Вы можете запустить этот пакет с входными данными из любых локальных файлов и вывести их в (или как) ваш следующий проект.
Ознакомьтесь с документацией по этой ссылке!