> For the complete documentation index, see [llms.txt](https://takahitomiyamoto.gitbook.io/heroku-basic/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://takahitomiyamoto.gitbook.io/heroku-basic/toc/level-1/next-actions.md).

# Next Actions

## コードフォーマットを実行する

複数人で開発する場合には、全体の品質を保つために、各々が好きなスタイルでコードを書くことを避けるべきです。

{% hint style="success" %}
コードフォーマットツールのデファクトスタンダードである [**Prettier**](https://prettier.io/) を利用し、各ファイルが統一されたフォーマットに修正されることを確認しましょう。
{% endhint %}

ルートディレクトリに `.prettierrc` ファイルを新規作成し、次のコードをコピペします。

{% tabs %}
{% tab title="JSON" %}
{% code title=".prettierrc" %}

```javascript
{
  "printWidth": 80,
  "tabWidth": 2,
  "useTabs": false,
  "semi": true,
  "singleQuote": true,
  "quoteProps": "as-needed",
  "jsxSingleQuote": false,
  "trailingComma": "none",
  "bracketSpacing": true,
  "jsxBracketSameLine": false,
  "arrowParens": "always",
  "requirePragma": false,
  "insertPragma": false,
  "proseWrap": "preserve",
  "htmlWhitespaceSensitivity": "css",
  "endOfLine": "lf",
  "overrides": [
    {
      "files": "*.html",
      "options": { "parser": "lwc" }
    }
  ]
}
```

{% endcode %}
{% endtab %}
{% endtabs %}

`package.json` の `scripts` に `prettier` コマンドを追加します。

{% tabs %}
{% tab title="JSON" %}
{% code title="package.json" %}

```javascript
...

"scripts": {
  "prettier": "prettier \"**/*.{css,html,js,json,md}\" --write --loglevel log",
  "start": "node index.js",
  "test": "node test.js"
},

...
```

{% endcode %}
{% endtab %}
{% endtabs %}

`prettier` をローカルにインストールし、実行します。

{% tabs %}
{% tab title="Console" %}

```bash
npm install --save-dev prettier

npm run prettier

```

{% endtab %}
{% endtabs %}

それぞれのファイルでコードがどのように修正されたのかを確認します。

![VS Code 画面](/files/-MWI7amgxaQrxuI-gxUZ)

{% hint style="info" %}
以後、コードを変更するたびに Prettier を実行することで均一的なフォーマットを維持することを習慣化しましょう。
{% endhint %}

## 静的コード解析を実行する

コードフォーマットを合わせたら、次はコードの書き方にこだわりましょう。せっかくコードを書くのであれば、先人の叡智が詰まった規約に準拠した書き方をお勧めします。潜在的なバグを事前に潰しておくことにも繋がります。

{% hint style="success" %}
JavaScript の静的コード解析ツールのデファクトスタンダードである [**ESLint**](https://eslint.org/) を利用し、コードが規約に違反していないかどうか確認しましょう。
{% endhint %}

ルートディレクトリに `.eslintrc.json` ファイルを新規作成し、次のコードをコピペします。

{% tabs %}
{% tab title="JSON" %}
{% code title=".eslintrc.json" %}

```javascript
{
  "env": {
    "node": true,
    "commonjs": true,
    "es2021": true
  },
  "extends": "eslint:recommended",
  "parserOptions": {
    "ecmaVersion": 12
  },
  "rules": {}
}

```

{% endcode %}
{% endtab %}
{% endtabs %}

`package.json` の `scripts` に `eslint` コマンドを追加します。

{% tabs %}
{% tab title="JSON" %}
{% code title="package.json" %}

```javascript
...

"scripts": {
  "eslint": "eslint *.js --format html --output-file .reports/eslint.html",
  "prettier": "prettier \"**/*.{css,html,js,json,md}\" --write --loglevel log",
  "start": "node index.js",
  "test": "node test.js"
},

...
```

{% endcode %}
{% endtab %}
{% endtabs %}

`eslint` をローカルにインストールし、実行します。

{% tabs %}
{% tab title="Console" %}

```bash
npm install --save-dev eslint

npm run eslint

```

{% endtab %}
{% endtabs %}

それぞれのファイルでコードがどのような警告が表示されるのかを確認します。

![VS Code 画面](/files/-MWIIIsy3x1lbDidWk7R)

また、`.reports` フォルダ内に生成されている `eslint.html` をブラウザで開くと、警告を一覧表示することができます。

![ESLint Report (HTML)](/files/-MWIIZw-4MSkeZ81cRn5)

コードを修正し、警告が消えたことを確認します。

![VS Code 画面](/files/-MWIM0Er-e4GTUrEcASN)

![ESLint Report (HTML)](/files/-MWIMIhV1NBls1CvNOqC)

{% hint style="info" %}
以後、コードを変更するたびに ESLint を実行することで警告の有無を確認し、コードを修正することを習慣化しましょう。なお、コードを修正せずに警告だけを消す方法もありますが、可能な限りコードを修正するようにしましょう。
{% endhint %}

## Lightning Design System を適用する

今回のチュートリアルで作成された画面はとてもシンプルですので、Salesforce の標準的なスタイルを適用してみましょう。

{% hint style="success" %}
もっと詳しく知りたい場合は、公式のチュートリアルを試してみてください。

<https://www.lightningdesignsystem.com/platforms/heroku/>
{% endhint %}

Salesforce Lightning Design System (SLDS) を npm 経由でダウンロードし、`public/assets/` 配下にコピーします。

{% tabs %}
{% tab title="Console" %}

```
npm install @salesforce-ux/design-system --save-dev

cp -r node_modules/@salesforce-ux/design-system/assets/ public/assets/

```

{% endtab %}
{% endtabs %}

SLDS を適用するために、`views/partials/header.ejs` の最下部にコードを追加します。

{% hint style="warning" %}
`views/pages/db.ejs` に追加すると、表示がずれてしまうので注意です。&#x20;
{% endhint %}

{% tabs %}
{% tab title="HTML" %}
{% code title="header.ejs" %}

```markup
<title>Node.js Getting Started on Heroku</title>
<link rel="stylesheet" type="text/css" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script type="text/javascript" src="//maxcdn.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js"></script>
<link rel="stylesheet" type="text/css" href="/stylesheets/main.css" />
<link rel="stylesheet" type="text/css" href="/assets/styles/salesforce-lightning-design-system.css" />

```

{% endcode %}
{% endtab %}
{% endtabs %}

`views/pages/db.ejs` のコードを修正します。長いので、コピペしてください。

{% hint style="info" %}
今回利用するコンポーネントは Cards と Data Tables です。詳しくは公式サイトを参照してください。

* [Cards - With no footer](https://www.lightningdesignsystem.com/components/cards/#With-no-footer)
* [Data Tables - Actionable mode - Column sorting and row selection(s)](https://www.lightningdesignsystem.com/components/data-tables/#Actionable-mode-Column-sorting-and-row-selection\(s\))
  {% endhint %}

{% tabs %}
{% tab title="HTML" %}
{% code title="db.ejs" %}

```markup
<!DOCTYPE html>
<html>
<head>
  <%- include ("../partials/header.ejs") %>
</head>

<body>

<%- include ("../partials/nav.ejs") %>

<div class="container">
<!-- <h2>Database Results</h2> -->
<article class="slds-card">
  <div class="slds-card__header slds-grid">
    <header class="slds-media slds-media_center slds-has-flexi-truncate">
      <div class="slds-media__figure">
        <span class="slds-icon_container slds-icon-standard-account" title="account">
          <svg class="slds-icon slds-icon_small" aria-hidden="true">
            <use xlink:href="/assets/icons/standard-sprite/svg/symbols.svg#account"></use>
          </svg>
          <span class="slds-assistive-text">Database Results</span>
        </span>
      </div>
      <div class="slds-media__body">
        <h2 class="slds-card__header-title">
          <a href="#" class="slds-card__header-link slds-truncate" title="Database Results">
            <span>Database Results</span>
          </a>
        </h2>
      </div>
    </header>
  </div>
  <div class="slds-card__body slds-card__body_inner">
    <!-- <ul>
      <% results.forEach(function(r) { %>
          <li><%= r.id %> - <%= r.name %></li>
      <% }); %>
    </ul> -->
    <table aria-multiselectable="true" class="slds-table slds-table_bordered slds-table_fixed-layout slds-table_resizable-cols" role="grid">
      <thead>
        <tr class="slds-line-height_reset">
          <th class="slds-text-align_right" scope="col" style="width:3.25rem">
            <span id="column-group-header" class="slds-assistive-text">Choose a row</span>
            <div class="slds-th__action slds-th__action_form">
              <div class="slds-checkbox">
                <input type="checkbox" name="options" id="checkbox-unique-id-1465" value="checkbox-unique-id-1465" tabindex="0" aria-labelledby="check-select-all-label column-group-header" />
                <label class="slds-checkbox__label" for="checkbox-unique-id-1465" id="check-select-all-label">
                  <span class="slds-checkbox_faux"></span>
                  <span class="slds-form-element__label slds-assistive-text">Select All</span>
                </label>
              </div>
            </div>
          </th>
          <th aria-label="id" aria-sort="none" class="slds-is-resizable slds-is-sortable" scope="col">
            <a class="slds-th__action slds-text-link_reset" href="#" role="button" tabindex="0">
              <span class="slds-assistive-text">Sort by: </span>
              <div class="slds-grid slds-grid_vertical-align-center slds-has-flexi-truncate">
                <span class="slds-truncate" title="id">id</span>
                <span class="slds-icon_container slds-icon-utility-arrowdown">
                  <svg class="slds-icon slds-icon-text-default slds-is-sortable__icon " aria-hidden="true">
                    <use xlink:href="/assets/icons/utility-sprite/svg/symbols.svg#arrowdown"></use>
                  </svg>
                </span>
              </div>
            </a>
            <div class="slds-resizable">
              <input type="range" aria-label="id column width" class="slds-resizable__input slds-assistive-text" id="cell-resize-handle-2668" max="1000" min="20" tabindex="0" />
              <span class="slds-resizable__handle">
                <span class="slds-resizable__divider"></span>
              </span>
            </div>
          </th>
          <th aria-label="name" aria-sort="none" class="slds-is-resizable slds-is-sortable" scope="col">
            <a class="slds-th__action slds-text-link_reset" href="#" role="button" tabindex="0">
              <span class="slds-assistive-text">Sort by: </span>
              <div class="slds-grid slds-grid_vertical-align-center slds-has-flexi-truncate">
                <span class="slds-truncate" title="name">name</span>
                <span class="slds-icon_container slds-icon-utility-arrowdown">
                  <svg class="slds-icon slds-icon-text-default slds-is-sortable__icon " aria-hidden="true">
                    <use xlink:href="/assets/icons/utility-sprite/svg/symbols.svg#arrowdown"></use>
                  </svg>
                </span>
              </div>
            </a>
            <div class="slds-resizable">
              <input type="range" aria-label="name column width" class="slds-resizable__input slds-assistive-text" id="cell-resize-handle-2669" max="1000" min="20" tabindex="0" />
              <span class="slds-resizable__handle">
                <span class="slds-resizable__divider"></span>
              </span>
            </div>
          </th>
          <th class="" scope="col" style="width:3.25rem">
            <div class="slds-truncate slds-assistive-text" title="Actions">Actions</div>
          </th>
        </tr>
      </thead>
      <tbody>
        <% results.forEach(function(r) { %>
          <tr aria-selected="false" class="slds-hint-parent">
            <td class="slds-text-align_right" role="gridcell">
              <div class="slds-checkbox">
                <input type="checkbox" name="options" id="checkbox-<%= r.id %>" value="checkbox-<%= r.id %>" tabindex="0" aria-labelledby="check-button-label-01 column-group-header" />
                <label class="slds-checkbox__label" for="checkbox-<%= r.id %>" id="check-button-label-<%= r.id %>">
                <span class="slds-checkbox_faux"></span>
                <span class="slds-form-element__label slds-assistive-text">Select item <%= r.id %></span>
              </label>
            </div>
          </td>
          <th scope="row">
            <div class="slds-truncate" title="id">
              <a href="#" tabindex="0"><%= r.id %></a>
            </div>
          </th>
          <td role="gridcell">
            <div class="slds-truncate" title="name"><%= r.name %></div>
          </td>
          <td role="gridcell">
            <button class="slds-button slds-button_icon slds-button_icon-border-filled slds-button_icon-x-small" aria-haspopup="true" tabindex="0" title="More actions">
              <svg class="slds-button__icon slds-button__icon_hint slds-button__icon_small" aria-hidden="true">
                <use xlink:href="/assets/icons/utility-sprite/svg/symbols.svg#down"></use>
              </svg>
              <span class="slds-assistive-text">More actions</span>
            </button>
          </td>
        </tr>
        <% }); %>
      </tbody>
    </table>
  </div>
  <footer class="slds-card__footer"></footer>
</article>
</div>

</body>
</html>

```

{% endcode %}
{% endtab %}
{% endtabs %}

表示するデータを増やすために、Heroku Postgres にテストデータを複数件インサートします。

{% tabs %}
{% tab title="Console" %}

```
heroku pg:psql

insert into test_table values (2, 'hello world');
insert into test_table values (3, 'hello heroku');
insert into test_table values (4, 'hello salesforce');
insert into test_table values (5, 'hello ohana');

exit

```

{% endtab %}
{% endtabs %}

Heroku アプリをローカルで実行します。

{% tabs %}
{% tab title="Console" %}

```
heroku local web

```

{% endtab %}
{% endtabs %}

<http://localhost:5000/db> にアクセスして、画面のスタイルが変わっていることを確認しましょう。

#### 変更前

![変更前](/files/-MWIQrVzf0CIkeJs7STM)

#### 変更後

![変更後](/files/-MWImCX4rbBeU-wl-3lT)

確認が終わったら、Heroku にデプロイして終了です。

{% tabs %}
{% tab title="Console" %}

```
git add .
git commit -m "Lv.1 completed"
git push heroku main

```

{% endtab %}
{% endtabs %}

一通りの手順はわかりましたか？他の画面についても、色々試してみてください。
