Как сделать строительные леса своими руками

Vue.js Yeoman

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

Основные функции, которые выполняют строительные леса:

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

Развивать свои собственные леса

Здесь и далее генератор, выступающий от имени этого строителя строительных лесов.

Создайте проект модуля узла

Генератор скаффолда йомена по сути является узловым модулем. Чтобы создать генератор строительных лесов йомена, сначала нам нужно создать папку, имя папки должно быть имя-генератора (имя — это имя нашего пользовательского генератора строительных лесов). Это важно, потому что yeoman просматривает файловую систему, чтобы найти доступные генераторы шаблонов.

В только что созданной папке создайте файл package.json и вручную введите следующее содержимое, или вы можете создать файл, запустив npm init в командной строке.

{
  "name": "generator-name",
  "version": "0.1.0",
  "description": "",
  "files": [
    "generators"
  ],
  "keywords": ["yeoman-generator"],
  "dependencies": {
    "yeoman-generator": "^1.0.0"
  }
}

Атрибут name должен начинаться с префикса генератор- , атрибут keywords должен содержать «yeoman-generator» , а поле описания желательно иметь краткое и четкое описание генератора скаффолда. Кроме того, не забудьте включить последнюю версию yeoman-generator в качестве зависимости проекта, которую можно установить, запустив npm install --save yeoman-generator в командной строке.

Структура каталогов

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

При запуске команды yo name в командной строке yeoman по умолчанию сгенерирует содержимое полки генератора лесов в папке приложения.

Генератор подзаготовителя может быть выполнен с помощью yo name: подкоманда в командной строке.

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

|---- package.json
|---- generators/
    |---- app/
        |---- index.js
    |---- router/
        |---- index.js

yoman поддерживает две разные структуры каталогов: ./ и ./generators.

Приведенный выше пример также можно записать так:

|---- package.json
|---- app/
    |---- index.js
|---- router/
    |---- index.js

Следующий шаг

Со структурой каталогов готов полный генератор скаффолдинга.

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

Этот базовый класс можно интегрировать в файл index.js:

var Generator = require('yeoman-generator');

module.exports = class extends Generator {};

Если вы хотите поддерживать среду ES5, статический метод Generator.extend() можно использовать для расширения базового класса и предоставления нового прототипа. Этот метод относится кclass-extend.

Переопределить конструктор

Некоторые функции-генераторы можно вызывать только внутри функции-конструктора, эти специальные методы могут использоваться для управления важным состоянием или не иметь никакого эффекта вне конструктора.

Вот как переопределить конструктор генератора:

module.exports = class extends Generator {
  // The name `constructor` is important here
  constructor(args, opts) {
    // Calling the super constructor is important so our generator is correctly set up
    super(args, opts);

    // Next, add your custom code
    this.option('babel'); // This method adds support for a `--babel` flag
  }
};

Добавить пользовательские функции

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

Таким образом, добавьте несколько методов:

module.exports = class extends Generator {
  method1() {
    this.log('method 1 just ran');
  }

  method2() {
    this.log('method 2 just ran');
  }
};

запустить строительные леса

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

В корневом каталоге проекта строительных лесов (имя-генератора/) введите следующее

npm link

Это установит зависимости и свяжет глобальные модули с локальными файлами. Затем можно запустить генератор строительных лесов, введя свое имя в командной строке.

Среда выполнения скаффолдинга

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

метод - это поведение

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

Хелперы и приватные методы

Поскольку каждый метод-прототип рассматривается как задача, вам может быть интересно, как определить вспомогательный или частный метод, который не будет вызываться автоматически. Есть 3 способа добиться этого:

  1. Префикс имени метода с подчеркиванием
  class extends Generator {
    method1() {
      console.log('hey 1');
    }

    _private_method() {
      console.log('private hey');
    }
  }
  1. Использование методов экземпляра
  class extends Generator {
    constructor(args, opts) {
      // Calling the super constructor is important so our generator is correctly set up
      super(args, opts)

      this.helperMethod = function () {
        console.log('won\'t be called automatically');
      };
    }
  }
  1. Наследовать от родительского генератора
  class MyBase extends Generator {
    helper() {
      console.log('methods on the parent generator won\'t be called automatically');
    }
  }

  module.exports = class extends MyBase {
    exec() {
      this.helper();
    }
  };

жизненный цикл генератора

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

Жизненный цикл — это система очередей с приоритетом.

Порядок выполнения жизненного цикла следующий:

  1. инициализация - функция инициализации
  2. подсказка - этап для получения пользовательского ввода
  3. configuring — сохранить информацию о конфигурации и файлы
  4. default - имя пользовательской функции function, например, method1
  5. написание - Фаза создания структуры каталога проекта
  6. конфликты - унифицированная обработка конфликтов, например, существует ли файл, который должен быть сгенерирован, или нет, перезаписан и т. д.
  7. install - этап установки зависимостей
  8. end - конечный этап генератора

асинхронная задача

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

Самый простой способ — вернуть обещание.

Если вы зависите от асинхронного API, который не поддерживает обещания, мы можем использовать метод this.async(). Вызов метода this.async() возвращает функцию после завершения задачи.

asyncTask() {
  var done = this.async();

  getUserEmail(function (err, name) {
    done(err);
  });
}

Если функция done вызывается с параметром ошибки, жизненный цикл завершится и будет выдано исключение.

Взаимодействие с пользователем

системная подсказка

Системные подсказки — это основной способ взаимодействия генератора скаффолдинга с пользователем. использование модуля системной подсказкиInquirer.js.

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

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

module.exports = class extends Generator {
  prompting() {
    return this.prompt([{
      type    : 'input',
      name    : 'name',
      message : 'Your project name',
      default : this.appname // Default to current folder name
    }, {
      type    : 'confirm',
      name    : 'cool',
      message : 'Would you like to enable the Cool feature?'
    }]).then((answers) => {
      this.log('app name', answers.name);
      this.log('cool feature', answers.cool);
    });
  }
};

записывать пользовательские параметры

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

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

this.prompt({
  type    : 'input',
  name    : 'username',
  message : 'What\'s your GitHub username',
  store   : true
});

аргументы

Параметры берутся прямо из командной строки, например:

yo webapp my-project

В приведенном выше примере my-project является параметром.

Способ определения параметров следующий:

Используйте метод this.argument(name, options), где options — это объект с несколькими ключами и значениями:

  • desc String - описание параметра
  • required Boolean - требуется ли
  • тип String, Number, Array (также может быть пользовательской функцией, возвращающей строку) — type
  • по умолчанию - значение по умолчанию

this.argument(name, options) можно вызывать только внутри конструктора. Также параметр справки недоступен для передачи таких значений, как yo webapp --help.

Пример использования следующий:

module.exports = class extends Generator {
  // note: arguments and options should be defined in the constructor.
  constructor(args, opts) {
    super(args, opts);

    // This makes `appname` a required argument.
    this.argument('appname', { type: String, required: true });

    // And you can then access it later; e.g.
    this.log(this.options.appname);
  }
};

варианты варианты

Опции и параметры очень похожи. Вызывается через генератор.опция(имя, опции). options — это объект с несколькими ключами и значениями со следующими свойствами:

  • desc - описание опции
  • псевдоним - псевдоним
  • type Либо Boolean, String, либо Number (также может быть функцией, возвращающей простую строку) - type
  • по умолчанию - значение по умолчанию
  • hide Boolean - скрывать ли от помощи

Пример использования:

module.exports = class extends Generator {
  // note: arguments and options should be defined in the constructor.
  constructor(args, opts) {
    super(args, opts);

    // This method adds support for a `--coffee` flag
    this.option('coffee');

    // And you can then access it later; e.g.
    this.scriptSuffix = (this.options.coffee ? ".coffee": ".js");
  }
};

выходная информация

Вывод информации через модуль generate.log. Пример использования:

module.exports = class extends Generator {
  myAction() {
    this.log('Something has gone wrong!');
  }
};

Взаимодействие с файловой системой

Среда локации и пути

Файловая функция yoman основана на двух адресных средах на жестком диске, которые являются папками для чтения и записи для самых длительных операций генератора.

целевая среда

Первая среда является целевой средой. Целевая среда — это папка, в которой йомен создает приложение для формирования шаблонов, которое является папкой вашего проекта.

Средой назначения обычно является текущий каталог или ближайшая родительская папка, содержащая файл .yo-rc.json. Файл .yo-rc.json определяет корневой каталог проекта yoman. Этот файл позволяет вашему пользователю запускать команды в подкаталогах.

Путь назначения можно получить с помощью генератора.destinationRoot() или генератора.destinationPath('sub/path').

// Given destination root is ~/projects
class extends Generator {
  paths() {
    this.destinationRoot();
    // returns '~/projects'

    this.destinationPath('index.js');
    // returns '~/projects/index.js'
  }
}

Вы можете вручную изменить путь назначения через generate.destinationRoot('new/path') . Но для простоты обслуживания лучше не изменять путь по умолчанию.

Если вы хотите узнать, где пользователь выполнил команду yo, вы можете получить этот путь через this.contextRoot.

Среда шаблона

Среда шаблонов — это папка, в которой вы храните файлы шаблонов, обычно это папка, из которой вы будете читать и копировать.

Среда шаблона по умолчанию имеет значение ./templates/ , которое можно переопределить с помощью генератора.sourceRoot('new/template/path') .

Путь к шаблону можно получить с помощью генератора.sourceRoot() или генератора.templatePath('app/index.js') .

class extends Generator {
 paths() {
   this.sourceRoot();
   // returns './templates'

   this.templatePath('index.js');
   // returns './templates/index.js'
 }
};

файловая функция

Генератор предоставляет все методы this.fs , this.fsmem-fs editorнапример, вы можете изучить его API самостоятельно.

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

Пример: копирование файла шаблона

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

<html>
  <head>
    <title><%= title %></title>
  </head>
</html>

Копируем файл методом copyTpl.

class extends Generator {
  writing() {
    this.fs.copyTpl(
      this.templatePath('index.html'),
      this.destinationPath('public/index.html'),
      { title: 'Templating with Yeoman' }
    );
  }
}

Запустив генератор, public/index.html будет содержать следующее:

<html>
  <head>
    <title>Templating with Yeoman</title>
  </head>
</html>

Конвертировать выходной файл через поток

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

Во время работы yeoman файл будет обрабатываться потоком виниловых объектов (например, gulp), любой автор генератора может зарегистрировать потоковое преобразование для изменения пути к файлу и содержимого.

Примеры следующие:

var beautify = require('gulp-beautify');
this.registerTransformStream(beautify({indent_size: 2 }));

Обратите внимание, что каждый файл любого типа будет транслироваться. Убедитесь, что конвертер потоков отфильтровывает неподдерживаемые файлы. Такие инструменты, как gulp-if или gulp-filter, помогут нам отфильтровать нелегальные типы файлов.

Вы можете использовать любой плагин gulp в преобразовании потока йомена на этапе написания make-файла.

demo

В соответствии с приведенным выше руководством был разработан генератор каркасов компонентов vue ui на основе yoeman.generator-vueui.

инструкции

npm install -g yo
npm install -g generator-vueui

mkdir vueui-example
cd vueui-example

yo vueui