[Практическое занятие] Создайте строительные леса корпоративного уровня за 15 минут

JavaScript

1 Слова, написанные впереди

Настройка скаффолдинга для проверки вашего уровня nodejs, инженерных способностей и способности проектирования сервисов инструментов является незаменимым процессом для продвижения переднего плана.

В процессе разработки кли автор исследует популярные кли и формирует лучшие практики.Эта статья направлена ​​на то, чтобы реализовать основные функции в кратчайшие сроки, раскрыть основные принципы и предоставить демо-склад для изучения и обсуждения всем желающим.

Чтение всей статьи занимает около 10 минут, а создание cli на основе этого руководства занимает около 15 минут.

список складов:Статья в блоге | Scaffolding — глобальный пакет команд | Scaffolding — Пакет плагинов шаблона | Scaffolding — сборка пакетов плагинов

2 Прототип строительных лесов

На самом деле изначальное предназначение строительных лесов — предоставить базовый шаблон для лучших практик, поэтомукопия шаблонаэто его основная функция

Несколько лет назад я написал минималистичные строительные леса, которые должны были быть сделаны

  1. npm опубликовать глобально установленный пакет
  2. При выполнении команды получить сжатый пакет на моем облачном сервисе и разархивировать его в текущую папку

С помощью одной команды я могу создать предустановленный полный каталог проекта, что очень удобно и эффективно.

Думаю, это следует рассматривать как прототип строительных лесов.

3 Леса для рассмотрения

Приведенный выше прототип строительных лесов может хорошо служить личным нуждам, но, в конце концов, он слишком сух и рудиментарен, и для того, чтобы стать общепризнанным инструментом, его необходимо усовершенствовать.

хорошо известныйvue-cli create-react-app @tarojs/cli umiСамая основная функция: сначала придумайте несколько столбцовВарианты вопросов,ПотомПредоставьте шаблон для вашего нового проектаи установите зависимости, затем предоставьтеотладочная сборкаЗаказ

Да, основной частью является эта идея, но если вы хотите сделать масштабируемый и удобный для пользователя, вам необходимо учитывать следующие требования:

  • Шаблоны поддерживают версию управления
  • Поддержка расширения нового шаблона
  • Автоматически обнаруживать обновления версий
  • Создание персонализированных шаблонов в соответствии с выбором пользователя
  • Дружественный пользовательский интерфейс
  • Функция сборки независима и может варьироваться в зависимости от шаблона (например, различать H5/PC/weapp/RN)
  • Совместные проекты с участием нескольких человек для обеспечения стабильных результатов сборки

Выглядит немного большим объемом информации, но на самом деле это не малопонятно, мы смотрим на намерение их установить

3.1 Шаблоны поддерживают управление версиями

Например, пользователь создал проект по шаблону версии 1.0.0, а через полгода он итеративно обновился до версии 2.0.0. Нам все еще нужно найти версию v1.0.0, потому что старые пользователи не хотят или неудобны для обновления.

Как и мой предыдущий прототип скаффолдинга, упаковать шаблон в сжатый пакет и выложить на облачный сервер не представляется возможным, после обновления он будет полностью заменен.

Репозиторий npm естественным образом поддерживает управление версиями, поэтому публикация шаблонов в npm естественным образом решает эту проблему.(Для проектов без открытого исходного кода вы можете рассмотреть возможность создания складов самостоятельно или частных складов)

3.2 Поддержка расширения новых шаблонов

Например, наш скаффолдинг изначально поддерживает шаблоны H5.

По прошествии полугода, по мере развития бизнеса, требуется поддержка шаблона для апплета WeChat.

На этом этапе нам не нужно разрабатывать дополнительный cli, но пусть cli с самого начала будет поддерживать расширения, что соответствует принципу открытого и закрытого дизайна.

3.3 Автоматически определять обновления версий

npm предоставляет несколько команд для определения версии пакета, например, выnpm view react versionвернуть16.9.0, дайте знать последнюю версию

Таким образом можно определить, устанавливает ли пользователь в данный момент последнюю версию, и пользователю будет предложено обновить

3.4 Создание персонализированных шаблонов в соответствии с выбором пользователя

Хотя шаблон предназначен для единства, необходимо поддерживать различия в единстве и может предоставлять дифференцированную поддержку пользователями запросов, например:

Результаты этих запросов повлияют на наш окончательный шаблон, например, в зависимости от того, выберет ли TypeScript один из двух предустановленных шаблонов, вставит ли «введение проекта», введенное пользователем, в поле описания package.json и т. д.

3.5 Дружественный пользовательский интерфейс

Соответствующие форматы, цвета, шрифты, панели рисования и т. д. обеспечивают хорошую обратную связь с пользователями.

Далее будут представлены некоторые часто используемые библиотеки для предоставления этих функций.

3.6 Независимая функция сборки, может варьироваться в зависимости от шаблона

Мы обычно используем WebPack для сборки/отладки.Для разных шаблонов есть большая разница в процессах сборки, нам нужно поддерживать разные сборки для разных шаблонов.

Поэтому возможность сборки тоже вынесена в отдельный пакет npm, а его пакет сборки можно указать в шаблоне

3.7 Совместные проекты с участием нескольких человек могут обеспечить стабильные результаты строительства

Поскольку существует несколько версий, нам нужны ограничения, чтобы вывод всех участников проекта был согласованным.

Его основной принцип заключается в следующем: для тех факторов, которые могут привести к различиям, мы включаем их в проект и позволяем записи в хранилище git, чтобы добиться того же самого, так что теперь популярны скаффолдинги, такие какumi taro, все будетВозможности сборки локализованы в локальных проектах, который будет подробно объяснен позже

4 три типа лесов пакетов

Архитектура скаффолдинга, проверенная на практике и отвечающая вышеуказанным требованиям, на самом деле очень проста, во-первых, мы разделим ее на три типа npm-пакетов:

Мешок Функция Место установки Примечание
глобальный пакет команд Подобно мозгу, отвечающему за реагирование на глобальные команды и планирование глобальный путь к пакету глобальная установка, предоставление глобальных команд
Пакет плагинов шаблона Инициализировать шаблон, скопированный проектом некоторый условный путь, например~/.maoda Шаблоны можно масштабировать вместе с бизнесом
Построить пакет плагинов Предоставляет возможности сборки (веб-пакета) в рамках проекта(В настоящее время эта схема используется в основных строительных лесах) Разные шаблоны могут использовать один и тот же пакет сборки или разные

Примечание. При создании пакета подключаемого модуля многие каркасы в первые дни помещали его за пределы проекта, например, в общей ситуации.Преимущество заключается в том, что несколько проектов могут повторно использовать набор возможностей веб-пакета, но также выявляются недостатки, то есть в проекте совместной разработки с несколькими людьми. Поскольку пакет подключаемого модуля сборки не включен в проект и не может быть включен в репозиторий git, возникают некоторые непредсказуемые различия.

Его отношения планирования следующие:

5 Глобальный командный пакет

О теории я говорил раньше, а теперь начинаю строить ее формально

Функция глобального пакета команд: отвечает за получение глобальных команд и планирование.

Например, демо-шаблон cli, который я сделалcli-tpl

npm i cli-tpl -g
# 或 yarn global add cli-tpl

После глобальной установки он предоставляетdcliЗаказ(назовите как хотите)Команда имеет следующие типичные особенности:

Раскрытые глобальные команды указываются Bin в Package.json, пожалуйста, обратитесь к моей демонстрации

Заказ Эффект
dcli install [pkgName] Установите «пакет плагинов шаблона», чтобы~/.maodaПуть, если он был установлен и выполнен, он попросит обновить до последней версии, например, установитьdcli install gen-tpl
dcli init Инициализируйте новый проект с помощью шаблона, который позволит вам выбрать один из установленных шаблонов после выполнения.
dcli build Выполнить в корневом каталоге проекта(Или напишите в скрипты проекта), попробуйте прочитать «пакет плагинов сборки», от которого зависит проект, и выполните сборку
dcli dev а такжеdcli buildАналогично, только для отладки

5.1 Некоторые сторонние пакеты приправ, которые стоит собрать в cli-разработке

важность имя пакета Функция
необходимо minimist Разбирать пользовательские команды и разбирать process.argv на объекты
необходимо fs-extra Расширение библиотеки fs для поддержки промисов.
необходимо chalk Позвольте вам console.log слова с цветом, например, зеленые слова в случае успеха
необходимо import-from Точно так же требуют, но поддерживает указанный каталог, поэтому вы можете пересекать каталог проекта, например, как глобальный пакет, предназначенный для цитата в пути проекта
необходимо resolve-from То же, что и выше, только require.resolve
необходимо inquirer Спрашивайте пользователей и записывайте результаты обратной связи, артефакт взаимодействия с интерфейсом
необходимо yeoman-environment [Core] используется для выполнения «пакета подключаемых модулей шаблона», который будет подробно описан позже.
глазурь на торте easy-table Аналогично console.table, выводит красивую таблицу
глазурь на торте ora Обеспечить погрузку хризантем
глазурь на торте semver Предоставьте сравнение версий
глазурь на торте figlet console.log выводит красивый большой логотип
глазурь на торте cross-spawn Кроссплатформенный child_process (под Windows/Mac)
глазурь на торте osenv Кроссплатформенная системная информация
глазурь на торте open Откройте приложение на разных платформах, например, в Chrome при отладке.

5.2 Разбор и распределение команд

Анализ и распределение команд является основной функцией «глобального пакета команд», и этот процесс относительно прост. Вы также можете напрямую просмотреть складcli-tpl (полная функциональность сжата примерно до 300 строк кода)

  1. Решение об обновлении версии cli:
    • Сначала получите версию в этом package.json
    • пройти сноваnpm view cli-tpl versionКоманда для запроса последней версии текущей библиотеки npm
    • Сравнение двух делает вывод и напоминает пользователю об обновлении
  2. Разбирать пользовательские команды
    • Получите фактическую команду, выполненную пользователем, через process.argv[2], напримерdcli installдоступныйinstall (Официальная версия рекомендует использовать minimist для разбора параметров)
  3. команда процесса
    • Например, команда install динамически отображается через requireinstall.jsфайл для обработки логики
    • Примечание: требуется поддерживает динамические имена, такие какrequire('./scripts/' + command)Таким образом, если командаinstallто отображение выполняетсяscript/install.jsдокумент

Далее, давайте рассмотрим четыре основные команды, в основном:

Заказ Эффект
install Помогите пользователям установить/обновить «пакет подключаемых модулей шаблона»
init Помогите пользователю инициализировать проект и скопировать шаблон
build Вызовите «сборку пакета плагинов» в проекте, чтобы помочь пользователям собрать веб-пакет.
dev Помогите пользователям запустить devServer для отладки

Далее описывается процесс реализации и действие каждой команды по отдельности:

5.3 installКоманда: установить «пакет плагина шаблона»

установить означает загрузить этот пакет плагинов шаблона на жесткий диск, здесь я сделал демонстрационный пакет с минимальными функциямиgen-tpl (подробнее позже)чтобы помочь объяснить

dcli install gen-tpl

Основной поток обработки выглядит следующим образом:

  1. Сначала определите, находится ли каталог кэша жесткого диска~/.maodaОн уже установленgen-tplМешок
    • Если нет, установите его следующим(эквивалентно~/.maodaВыполните установку npm в каталоге)
    • Если есть и версия младшая, то предложит обновиться
    • Если есть, и версия самая последняя, ​​то действовать не будет
  2. Процесс установкиexecSync('npm i gen-tpl@latest -S', { cwd: '~/.maoda' })

Мы можем принять соглашение для имени «пакет плагина шаблона», то есть иметь фиксированный префикс, такой какgen-xxx

5.4 initКоманда: выберите «пакет плагинов шаблона», чтобы инициализировать новый проект.

Это высокочастотная и основная функция строительных лесов.

dcli init

будут распределены для выполненияscript/init.jsФайл, смотрим на него логически

  1. Запрос каталога кэша на жестком диске~/.maodaвнизpackage.jsonфайл, прочитайте егоdependaciesполе, получите установленный "пакет плагинов шаблона"
    • Если ни один из них не установлен, пользователю будет предложено сначала установить
  2. Позвольте пользователю выбрать набор шаблонов
    • использоватьinqueryБиблиотека инициирует диалог, перечисляет установленные шаблоны и позволяет пользователю выбирать, например, как на картинке выше.gen-pc gen-h5 gen-tpl
  3. Запустите процесс инициализации шаблона
    • Например, пользователь выбираетgen-tplДля этого шаблона используйтеyeoman-environmentЭта библиотека выполняет пакет в каталоге кеша~/.maoda/gen-tpl/index.js
    • Примечание. Это эквивалентно выполнению двух ссылок на файлы js в разных каталогах с использованием того, что было сказано ранее.import-fromэта библиотека
  4. При выполнении «пакета плагинов шаблона» запускается обычный процесс копирования шаблона.(Расширить позже)

Здесь имя пакета используется непосредственно как опция.Чтобы продемонстрировать более интуитивно, описание пакета обычно используется как опция, которая является более удобной, напримерgen-pcПакет может быть описан как生成PC模板

5.5 buildКоманда: выполнить сборку в проекте

dcli build

  1. Определить каталог проекта
    • Каталог проекта — это каталог выполнения, полученный с помощью process.cwd().
  2. Прочтите плагин сборки, используемый проектом
    • Прочитайте файл конфигурации, согласованный в проекте, в этой демонстрации этоmaoda.js (используя обычную конфигурацию,类似 webpack.config.js .babelrc .prettierrc)
    • читатьmaoda.jsсерединаbuilderэлемент конфигурации(I.e. Указанный пакет плагина сборки), например, в этой демонстрации он указан какbuild-tpl
    • Прочитайте пользовательскую конфигурацию веб-пакета, если таковая имеется(Конвенция — это поле webpackCustom, которое позже будет объединено/переопределено в конфигурацию веб-пакета по умолчанию)
  3. Использовать указанный пакет подключаемого модуля сборки для упаковки веб-пакета
    • Определить, был ли установлен проектbuild-tpl
    • Если он не установлен, выполните его по пути в проектеnpm install (или добавление пряжи, вот небольшой трюк, чтобы определить, использует ли пользователь npm или пряжу в соответствии с типом файла блокировки в пользовательском проекте)
    • Установлено, выполнить напрямуюbuild-tpl

Обычно мы используем конфигурационный файл для указания "сборки пакета плагинов", либо его можно указать прямо в команде, например dcli build --builder=build-h5; последнее часто подходит для набора кодов для упаковки различных результатов, таких как Jingdong Taro cli

Все к этому привыклиnpm run build yarn build, только в нашем шаблонеpackage.jsonДобавьте строку:

{
    "script": {
++      "build": "dcli build"
    }
}

5.6 devКоманда: запустить devServer для отладки

Аналогичен сборке, но с другой конфигурацией веб-пакета, здесь опущено

6 пакетов плагинов для шаблонов

Основная функция: предоставить папку шаблона + копию папки. Вот также пример проектаgen-tpl (всего 50 строк кода)

Процесс обработки выглядит следующим образом:

  1. Спрашивайте пользователей и получайте отзывы об ответах
    • Например, как называется проект, опишите ваш проект, использовать ли TypeScript, использовать ли Sass/Less/Stylus и т. д.
  2. Согласно ответу пользователя, скопируйте соответствующий шаблон, разделите две копии
    • Прямая копия, прямое копирование папки/файла в пакете подключаемого модуля шаблона в каталог пользовательского проекта.
    • Заполните копию шаблона, заполните ответ пользователя на соответствующую позицию документа, аналогично WebpackHTMLPlugin, ejs, например, добавивname: <%= packageName %>наполненныйname: 我的工程
  3. Выполнить установку зависимостей npm в проекте

[Ключевой момент тут] Вроде бы процессов довольно много, но на самом деле можно использовать только одно готовое колесо, т.е.yeoman-generator, это помогает нам инкапсулировать эти процессы, нам нужно только наследовать базовый класс и написать несколько предустановленных функций жизненного цикла, что ошеломляет.(Подробности см. в репозитории шаблонов)

module.exports = class extends Generator {
  // 【问询环节】
  prompting() {
    return this.prompt([
      {
        type: 'input',
        name: 'appName',
        message: '请输入项目名称:',
      },
      {
        type: 'list',
        choices: ['Javascript', 'TypeScript'],
        name: 'language',
        message: '请选择项目语言',
        default: 'TypeScript',
      },
    ]).then(answers => {
      this.answers = answers
    })
  }
  
  // 【模板拷贝】
  writing() {
    // 从模板路径拷贝到工程路径
    this.fs.copy(this.templatePath(), this.destinationPath())
  }

  // 【安装依赖】
  install() {
    this.installDependencies()
  }

  end() {
    this.log('happy coding!')
  }
}

Очевидно, что «пакет плагинов шаблона» экспортирует класс, нам нужно передать «глобальный пакет команд», упомянутый выше.yeoman-environmentначать:

// 【节选自 全局命令包 init 命令,略修改以增加可读性】
yoemanEnv.register(resolveFrom('./maoda', 'gen-tpl'), 'gen-tpl')
yoemanEnv.run('gen-tpl', (e, d) => {
  d && this.console('happy coding', 'green')
})

То же самое относится и к вышеупомянутомуresolve-fromпакет для разрешения ссылок между каталогами

yeoman представляет собой относительно полную экосистему.Пакет подключаемого модуля шаблона можно создать с помощью глобальной команды yo, предоставленной yeoman, но это не обязательно, поэтому я не буду здесь ее расширять.

7 Соберите пакет плагина

Также мы предоставляем шаблон для сборки пакетов плагиновbuild-tpl (20 строк кода, запускаем webpack), конфигурация вебпака пустая, можно настроить в процессе разработки

Ядром создания пакета подключаемого модуля является возможность веб-пакета.Возможности веб-пакета не будут обсуждаться здесь.Здесь будет описана только взаимосвязь вызова.

кdcli buildНапример, после того, как «глобальный пакет команд» получает команду сборки, он запускает «сборку пакета плагинов».

importFrom(process.cwd(), 'build-tpl')

Да, это так просто,import-fromБиблиотеки могут охватывать файловые каталоги, указывая файлы, которые используют определенный каталог;Глобальный пакет может напрямую выполнять пакет каталога проекта.Эффект такой же, как и в рамках того же проектаrequire('build-tpl')Такой же

Здесь также можно использовать библиотеку import-cwd.

Пакет подключаемого модуля сборки build-tpl отвечает за слияние встроенного webpack.config.js с пользовательским webpackCustom в пользовательском проекте, а затем за выполнение процесса webpack.

Конечно, инструмент сборки не обязательно должен использовать веб-пакет, например, вы можете выбрать накопительный пакет или создать набор инструментов самостоятельно при сборке кода апплета, такого как Taro.

8 Написано в конце

Автор считает, что только при достаточном упрощении можно понизить порог вхождения и укрепить память, поэтому в случае с данной статьей на зрелых строительных лесах производятся сплошные удаления, а также удаляются части, увеличивающие нагрузку на память, и сохраняется только суть и ядро, чтобы быстро смоделировать в уме строительные леса уровня предприятия.

Также предоставляет поддержку 3-компонентных репозиториев/пакетов npm для повышения работоспособности.

Для справки и фактического развития нам необходимо продолжать конкретизировать его плоть и кровь, включая, помимо прочего:

  • Обработка исключений (например, некоторые пограничные случаи)
  • Часть конфигурации веб-пакета нуждается в улучшении(webpack.config в этой демонстрации пуст)
  • Язык интерфейса может быть более дружелюбным и продвижением
  • Расширьте дополнительные команды в соответствии с потребностями бизнеса, такие как удаление пакетов, публикация cdn и т. д.

Адрес блога статьи:GitHub.com/iMaoDa/Это-Фа…Критика и поправки приветствуются