React の String Style CSS におけるセミコロン戦略

# この記事は何か？

最近個人開発に力を入れており、CSS は String Style で記述しています。
3ヶ月ほど開発してきて知見が溜まってきたので、現時点での自分のベストプラクティスとして記事を書くことにしました。

といっても内容はしょうもないです。
「CSS の末尾のセミコロンは付けたほうが良いの？付けなくてもいいの？」という内容です。
タイトルに壮大そうな「戦略」という言葉を使っていますが、ようするに付けのるか付けないのかということです。

個人開発で実際に使用している CSS ライブラリは [linaria](https://github.com/callstack/linaria) です。
フロントエンドには React を採用しており、爆速動作を謳う linaria が面白そうなので導入しました。

# セミコロンは付けよう

結論として、セミコロンは付けましょう。

以上です。
本記事は役目を終えました。

結論だけ言われても困ると思うので、ここから先で補足を説明していきます。

# そもそも String Style CSS とは？

文字列で CSS を記述する形式のことです。
実際は正式名称を知らないので、もしご存知の方がいれば教えていただきたいです 🙏

`String Style` という言葉は Emotion のドキュメントから拾ってきました。
[The css Prop - String Styles](https://emotion.sh/docs/css-prop#string-styles)

### CSS スタイルの記述の仕方

String Style では、以下のような形で CSS を記述することができます。

```javascript
const positioin = css`
  position: absolute;
  top: 200px;
  left: 300px;
`
```

CSS-in-JS で有名な Emotion や 今回導入した linaria では、 `css` プロップスに値を渡すことにより CSS を適用できます。

```javascript
const MyComponent: VFC<Props> = (props) => {
  return <div css={position}>hello</div>
}
```

Emotion では直接書くほうが一般的かも知れませんね。

```javascript
const MyComponent: VFC<Props> = (props) => {
  return (
    <div 
      css={css`
        position: absolute;
        top: 200px;
        left: 200px;
      `}
    >
      hello
    </div>
  )
}
```

### linaria の stlye タグ

余談ですが、linaria では `css` タグも利用できるのですが、 `styled` タグを使用する方がより一般的です。
`styled` を利用すると、 CSS 適用済みのタグを生成するような感覚でスタイルを適用できます。

[linaria - The styled tag](https://github.com/callstack/linaria/blob/master/docs/BASICS.md#the-styled-tag)

```javascript
const MyComponent: VFC<Props> = (props) => {
  return (
    <Position>
      <p>hello</p>
    </Position>
  )
}

const Position = styled.div`
  position: absolute;
  top: 200px;
  left: 300px;
`
```

# なぜセミコロンを付けたほうが良いのか？

自分は省略できるものは省略したい派です。
もちろん可読性などの場合によりますが、それでもフォーマットとしては省略したほうが見やすいと感じます。

以下のように、個人開発でもしばらくはセミコロンを省略して書いていました。

```javascript
const position = ｃss`
  position: absolute
  top: 200px
  left: 300px
`
```

ではなぜ省略しないほうが良いのか？
それは 2つ のケースにおいて、セミコロンを付与しないとコードフォーマット時に期待しない挙動となるためです。

### ①コメントが書けない

セミコロンを付けないと、 CSS の中にコメントを記述する事ができません

具体的には、以下のコードではエラーが発生します。

```javascript
const position = ｃss`
  position: absolute
  /* コメント */
  top: 200px
  left: 300px
`
```

```javascript
Compiled with problems:

...

Module build failed (from ./node_modules/postcss-loader/dist/cjs.js):
SyntaxError

(194:6) /path/to/MyComponent.tsx Missed semicolon
```

セミコロンがないよと言われていますね。
おそらく改行周りの解釈が上手く行かないのだと思います。

#### セミコロンがなくてもコメントを書けるパターン

この章は余談です。
実はセミコロンがなくてもコメントを書けるパターンが 2つ あります。

1. css タグの 1行目 に記述
1. 属性の末尾に記述

1 は以下のようなパターンです。

```javascript
const position = ｃss`
  /* コメント */
  position: absolute
  top: 200px
  left: 300px
`
```

2 は以下のようなパターンです。

```javascript
const position = ｃss`
  position: absolute
  top: 200px /* コメント */
  left: 300px
```

#### なぜ改行後のコメントが解釈されないのか？

ではなぜ改行後のコメントが解釈されないのでしょうか？
何らかの理由により仕様で禁止しているのでしょうが、正直理由がわかりません。

CSS の値を改行しても記述可能であるという点はヒントな気がします。
以下の文字列は有効です。

```javascript
const position = ｃss`
  position:
   absolute
  top: 200px
  left: 300px
```

ですがコメントのリテラル `/* */` が出現した時点でスルーすれば良いので、改行が決定打となる理由が思いつきません。

###　② CSS のアットマークルールをフォーマットしてしまう

2個目は、セミコロンなしで記述すると CSS の [アットマークルール](https://developer.mozilla.org/ja/docs/Web/CSS/At-rule) をフォーマットしてしまう点です。

例えば次の animation を書いたとします。

```javascript
const open = css`
  animation: 0.3s ease-in open

  @keyframes open {
    from {
      height: 0px
    }

    to {
      height: 100px
    }
  }
`
```

この CSS をフォーマットすると以下のようになります。

```javascript
const open = css`
  animation: 0.3s ease-in open @keyframes open {
    from {
      height: 0px
    }

    to {
      height: 100px
    }
  }
`
```

なぜ、、、
ここでも上手く改行を解釈してくれません。

`animation` 行の末尾にセミコロンを付与すれば意図せぬフォーマットは防げます。

以上がセミコロン付けない戦略を採用した場合のデメリットです。
これらを回避するには都度セミコロンを付与する必要があるのですが、それだったら全部に付けて統一感をもたせたほうがメリットが大きいと感じました。

# 終わりに

割とどうでも良い内容を長々と書いてしまいましたが、そういうのもたまには好きです。
どなたかのお役に立てたら幸いです。