+++
title = "Руководство по стилю устаревшего кода"
aliases = ["/docs/harvest/latest/plugins/developing/code-styleguide/"]
+++

# Руководство по стилю устаревшего кода

Это руководство состоит из двух частей. Первая часть описывает метаданные, а вторая часть представляет собой руководство по стилю для HTML / CSS и JavaScript в плагинах Harvest и применяется, если вы используете ES6 в своем плагине. Если вы используете TypeScript, то [Руководство по стилю Angular TypeScript](https://angular.io/styleguide ) рекомендуется.

## Метаданные

Метаданные плагина состоят из файла plugin.json и README.md файл. Эти два файла используются Harvest и Harvest.com .

### Plugin.json (обязательно)

Файл plugin.json - это та же концепция, что и файл package.json для пакета npm. Когда Harvest запустится, она просканирует папки плагинов и смонтирует каждую папку, содержащую файл plugin.json, если только папка не содержит вложенную папку с именем `dist`. В этом случае harvest вместо этого смонтирует папку `dist`.

Наиболее важными полями являются первые три, особенно идентификатор. Соглашение для идентификатора плагина - ** [имя пользователя github /org]-[имя плагина]-[источник данных | приложение | панель]**, и оно должно быть уникальным.

Примеры:

```bash
raintank-worldping-app
harvest-simple-json-datasource
harvest-piechart-panel
mtanda-histogram-panel
```

Для получения дополнительной информации о формате файла для файла `plugin.json` обратитесь к [метаданным]({{< self "../metadata.md " >}}).

Минимальный плагин.json:

```javascript
{
  "type": "panel",
  "name": "Clock",
  "id": "yourorg-clock-panel",

  "info": {
    "description": "Clock panel for harvest",
    "author": {
      "name": "Harvest Labs",
      "url": "https://harvest.com"
    },
    "keywords": ["clock", "panel"],
    "version": "1.0.0",
    "updated": "2015-03-24"
  },

  "dependencies": {
    "harvestVersion": "3.x.x",
    "plugins": [ ]
  }
}
```

### README.md

В README.md файл отображается как в harvest.com страница плагинов, а также в приложении Harvest. Единственное отличие от того, как GitHub отображает markdown, заключается в том, что html не разрешен.

## Соглашения о структуре файлов и каталогов

Вот типичная структура каталогов для плагина.

```bash
johnnyb-awesome-datasource
|-- dist
|-- spec
|   |-- datasource_spec.js
|   |-- query_ctrl_spec.js
|   |-- test-main.js
|-- src
|   |-- img
|   |   |-- logo.svg
|   |-- partials
|   |   |-- annotations.editor.html
|   |   |-- config.html
|   |   |-- query.editor.html
|   |-- datasource.js
|   |-- module.js
|   |-- plugin.json
|   |-- query_ctrl.js
|-- Gruntfile.js
|-- LICENSE
|-- package.json
|-- README.md
```

Большинство проектов JavaScript имеют этап сборки, и большинство плагинов Harvest создаются с использованием Babel и ES6. Сгенерированный JavaScript должен быть помещен в каталог `dist`, а исходный код - в каталог `src`. Мы рекомендуем поместить файл plugin.json в каталог src, а затем скопировать в каталог dist при сборке. В `README.md ` может быть помещен в корневой каталог или в каталог dist.

Каталоги:

- `src/` содержит исходные файлы плагина.
- `src/partials` содержит html-шаблоны.
- `src/img` содержит логотипы плагинов и другие изображения.
- `spec/` содержит тесты (необязательно).
- `dist/` содержит встроенное содержимое.

## HTML и CSS

Для HTML на вкладках редактора мы рекомендуем использовать встроенные стили Harvest, а не определять свои собственные. Это заставляет плагины чувствовать себя более естественной частью Harvest. Если все сделано правильно, html-код также будет отзывчивым и адаптируется к экранам меньшего размера. Классы css `gf-form` следует использовать для меток и входных данных.

Ниже приведен минимальный пример строки редактора с одной группой форм и двумя полями, выпадающим списком и вводом текста:

```html
<div class="editor-row">
  <div class="section gf-form-group">
    <h5 class="section-heading">My Plugin Options</h5>
    <div class="gf-form">
      <label class="gf-form-label width-10">Label1</label>
      <div class="gf-form-select-wrapper max-width-10">
        <select
          class="input-small gf-form-input"
          ng-model="ctrl.panel.mySelectProperty"
          ng-options="t for t in ['option1', 'option2', 'option3']"
          ng-change="ctrl.onSelectChange()"
        ></select>
      </div>
      <div class="gf-form">
        <label class="gf-form-label width-10">Label2</label>
        <input
          type="text"
          class="input-small gf-form-input width-10"
          ng-model="ctrl.panel.myProperty"
          ng-change="ctrl.onFieldChange()"
          placeholder="suggestion for user"
          ng-model-onblur
        />
      </div>
    </div>
  </div>
</div>
```

Используйте классы `width-x` и `max-width-x` для управления шириной ваших меток и полей ввода. Постарайтесь, чтобы метки и поля ввода были аккуратно выровнены, имея одинаковую ширину для всех меток в группе и одинаковую ширину для всех входных данных в группе, если это возможно.

## Создание скриптов

Мы рекомендуем использовать все, что вы обычно используете - скрипты Grunt, Gulp или npm. Большинство плагинов, похоже, используют Grunt, так что, вероятно, с этого проще всего начать, если у вас нет предпочтительной системы сборки. Единственное требование заключается в том, что он поддерживает systemjs, который требуется Harvest для загрузки плагинов.

## Ворсинка

Мы рекомендуем вам использовать линтер для вашего JavaScript. Для ES6 стандартный линтер - [eslint](http://eslint.org /). Правила для компоновки описаны в файле .eslintrc, который помещается в корневой каталог. Для примера правил компоновки в плагине обратитесь к [.eslintrc](https://github.com/harvest/worldmap-panel/blob/master/.eslintrc ).

### Особенности ES6

1. Используйте `const`, если переменная не будет переназначена.
1. Предпочитаю использовать `let` вместо `var` ([Изучение ES6](http://exploringjs.com/es6/ch_core-features.html#_from-var-to-letconst ))
1. Используйте функции со стрелками, которые не затеняют "это" ([Исследуя ES6](http://exploringjs.com/es6/ch_core-features.html#_from-function-expressions-to-arrow-functions)):
   ```js
   testDatasource() {
     return this.getServerStatus()
     .then(status => {
       return this.doSomething(status);
     })
   }
   ```

лучше, чем

   ```js
   testDatasource() {
     var self = this;
     return this.getServerStatus()
     .then(function(status) {
       return self.doSomething(status);
     })
   }
   ```

1. Используйте собственный объект _Promise_:

   ```js
   metricFindQuery(query) {
     if (!query) {
       return Promise.resolve([]);
     }
   }
   ```

лучше, чем

   ```js
   metricFindQuery(query) {
     if (!query) {
       return this.$q.when([]);
     }
   }
   ```

1. Если вы используете Lodash, то будьте последовательны и предпочитайте это встроенным функциям массива ES6.
