LoginSignup
14
11

More than 3 years have passed since last update.

[W.I.P.] 【実況】Vue の 50 倍の速度が出るらしい「Svelte」のライブラリ「Sapper」を使って人生初のポートフォリオを作ってみる

Last updated at Posted at 2020-01-25

前提として,
1. GitHub にリポジトリを作っただけの段階で記事を書き始めています。
2. Svelte を触ったことは一度もありません。ドキュメントも今から読みます。
3. 2日以内を目標に GitHub Pages に公開するまで随時更新します。
4. (2020/02/01) 2日以内とはなんだったのか状態ですが,前述の通り公開までは随時更新します :bow:

目次

0. はじめに - Svelte って何
1. 動機
2. 実装

0. はじめに - Svelte って何?

あなたは Svelte をご存知ですか? 私は2日前にはじめて知りました :neutral_face:

公式サイトには次のように説明があります。

Svelte is a radical new approach to building user interfaces. Whereas traditional frameworks like React and Vue do the bulk of their work in the browser, Svelte shifts that work into a compile step that happens when you build your app.

Instead of using techniques like virtual DOM diffing, Svelte writes code that surgically updates the DOM when the state of your app changes.

"Svelte・Cybernetically enhanced web apps" from https://svelte.dev

:rolling_eyes:「ほーん(Google 翻訳つかお)」

グーグル先生「Svelte は、ユーザーインターフェイスを構築するための根本的な新しいアプローチです。 React や Vue のような従来のフレームワークはブラウザーで大部分の作業を行いますが、Svelte はその作業をアプリのビルド時に発生するコンパイルステップに移行します。 仮想 DOM 差分のような手法を使用する代わりに、Svelte はアプリの状態が変化したときに外科的に DOM を更新するコードを記述します。」

:yum:「よくわからんけど
 『React や Vue は仮想 DOM 越しに JavaScript を動かすからブラウザに負荷がかかって重い』
 『仮想 DOM は遅いから使わないようにしたぜ』
 『ついでにコンパイルのときに最適化もかけてやるぜ』
 みたいな話かな(ふんいきでものを言っています)」

1. 動機

2日前に Qiita でこういった記事を見かけまして,Vue 好きの私1としては「Vue の 50 倍!?」「構文は Vue ライク!?」「これは試さなければ!!!」という感じで Svelte 使って何か作ることにしました

ReactとVueを改善したSvelteというライブラリーについて
ベンチマークでReactの35倍、Vueの50倍速いです。
image

ToDo アプリみたいな完成しても使わないものは作ってる途中で飽きちゃうので, ちょうどポートフォリオサイトを何で作るか悩んでいたので,自分のポートフォリオサイトを作ることにしました :laughing:

2. 実装

前述のとおりこれからやって行きます(ここまで:2020/01/26 04:37:42)

2.1 Svelte インストール

とりあえず公式ドキュメントのここを参考に, GitHub で作ったリポジトリを clone して,
degit コマンドを使ってテンプレを作りました。

$ npx degit sveltejs/template svelte-app
u-sho@~/github/u-sho/svelte-app (master=)$ npx degit sveltejs/template app
npx: 32個のパッケージを3.88秒でインストールしました。
> cloned sveltejs/template#master to app

u-sho@~/github/u-sho/svelte-app (master %=)$ mv app/* ./

u-sho@~/github/u-sho/svelte-app (master *%=)$ mv app/.
./          ../         .gitignore  

u-sho@~/github/u-sho/svelte-app (master *%=)$ mv app/.gitignore ./

u-sho@~/github/u-sho/svelte-app (master *%=)$ git add .

u-sho@~/github/u-sho/svelte-app (master +=)$ git commit -m ":tada: initial commit"

公式は npm を推してくるけど私は yarn 派です

u-sho@~/github/u-sho/svelte-app (master >)$ yarn

u-sho@~/github/u-sho/svelte-app (master *>)$ yarn dev

dev モードの初期画面です。port が 5000 なのが配慮してる感じが出てて嬉しい

スクリーンショット 2020-01-26 5.06.37.png

これもコミット&プッシュしたところでリポジトリ名を svelte-app から portfolio に変えました(ここまで:2020/01/26 05:50:39)
該当コミット時のリポジトリツリーはこちら (追加:2020/01/28 05:22:22)

:thinking: Qiita 書くのに時間かかりすぎてるなあ

2.2 方針転換

React に対する Next のように,Svelte には Sapper というライブラリがあるそうです。
とにかく速く実装を終えたいので,今回はこれを使うことにしました :muscle_tone4:

もう夜も終わりそうなので,一旦寝て,夜から再会したいと思います(ここまで:2020/01/26 06:13:35)

2.3 Sapper インストール

公式ドキュメントにしたがってインストールしていきます。

webpack しか使ったことがないですが,公式が rollup を推してくるので rollup でやってみます :yum:

$ npx degit "sveltejs/sapper-template#rollup" sapper-app
u-sho@~/github/u-sho/portfolio (master=)$ rm -r ./*

u-sho@~/github/u-sho/portfolio (master *=)$ npx degit "sveltejs/sapper-template#rollup" sapper-app
npx: 32個のパッケージを5.789秒でインストールしました。
> cloned sveltejs/sapper-template#rollup to sapper-app

u-sho@~/github/u-sho/portfolio (master %=)$ rm -r node_modules/

# 以前のプロジェクト(2.1で入れたやつ)の dotfiles を消して sapper-app/* のファイルを親 (portfolio/*) に移動

公式は npm 推しっぽいですが,package-lock.json が読めないので yarn を使います。

local serve するついでに package.jsonnamedescription も適当に書き換えました。

u-sho@~/github/u-sho/portfolio (master *%=)$ yarn

u-sho@~/github/u-sho/portfolio (master *%=)$ yarn dev

初期画面です。見知らぬおじさんが両手でサムズアップです。人間味がありますね(?)
port が 3000 番なのは Next.js を意識しているのでしょうか(?)

画面収録-2020-01-28-5.31.24.gif

ここでコミットしたら GitHub から security alert が飛んできました。

スクリーンショット 2020-01-28 6.16.44.png

どうも serialize-javascript というパッケージのバージョンが古くて,XSS の危険性があるらしいです
直さねば・・・(ここまで:2020/01/28 06:23:39)

2.3.1 security alert の解消

GitHub によると serialize-javascript を ^2.1.1 にバージョンアップする必要があるようです
package.json で直接インストール(依存)しているパッケージの中にはなかったので yarn.lock を漁ります

yarn.lock
 rollup-plugin-terser@^4.0.4:
   version "4.0.4"
   resolved "https://registry.yarnpkg.com/rollup-plugin-terser/-/rollup-plugin-terser-4.0.4.tgz#6f661ef284fa7c27963d242601691dc3d23f994e"
   integrity sha512-wPANT5XKVJJ8RDUN0+wIr7UPd0lIXBo4UdJ59VmlPCtlFsE20AM+14pe+tk7YunCsWEiuzkDBY3QIkSCjtrPXg==
   dependencies:
     "@babel/code-frame" "^7.0.0"
     jest-worker "^24.0.0"
     serialize-javascript "^1.6.1"
     terser "^3.14.1" 

serialize-javascript は ^1.6.1 で指定されているので,メジャーバージョンを上げなければなりません。

serialize-javascript のみアップデートすると, rollup-plugin-terser が serialize-javascript v2 で廃止された機能を使っている場合を考えないといけません。これは確認がとてもめんどくさいので,rollup-plugin-terser のリリース一覧でヤバイ変更がなさそうなことを確認して,rollup-plugin-terser のバージョンを上げました(ここまで:2020/01/28 07:26:21)

該当コミット

$ yarn add --dev rollup-plugin-terser

2.4 エディタの設定 editorconfig

普段インデントにはスペースを使っているのですが,Sapper のテンプレはタブ文字を使っていたので,これに合わせて .editorconfig を書きます2

.editorconfig
# editorconfig.org
root = true

[*]
indent_style = tab
indent_size = 2
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = false

[*.md]
trim_trailing_whitespace = false

該当コミットはこちら

これでタブとスペースが入り混じった悲しいイン(シ)デントになることは避けられました :clap:

2.5 Sass の導入

この記事 を参考にして SCSS で書けるようにしました。

「SCSS ってなんぞ?」という方は こちらの記事 をどうぞ

また,ここから実際にコードをいじっていくので develop ブランチとして切り分けました :tada:

2.5.1 Sass (SCSS) の設定

u-sho@~/github/u-sho/portfolio (master=)$ git switch -c develop

u-sho@~/github/u-sho/portfolio (develop)$ yarn add --dev autoprefixer node-sass svelte-preprocess

該当コミットはこちらです

(追記:2020/02/05 17:45:14)
svelte-preprocess-sass を使ったり,やり方は色々あるようです

2.5.2 テンプレートの style を CSS から SCSS に変更

次のような変更を加えて,書き方を SCSS チックにしました。

*.svelte
-<style>
+<style lang="scss">

また,src/styles/global.scss をつくり,_layout.svelte でそれを @import させています。

スクリーンショット 2020-02-01 19.00.28.png

yarn dev で,ちゃんとスタイルがあたっていることを確認して コミット

2.6 VS Code の設定

私はフロントのコードを書くときは VS Code を使うことにしているので,その設定をしていきます。

2.6.1 拡張機能の設定

前項の Sass 導入にあたって,syntax hilight がきれいに当たらなかったので,先に挙げた記事
にしたがって SCSS Style Tag という拡張機能を入れました。

ここで,普段 Svelte.js を書かない私は,このリポジトリでしか使っていない拡張機能が増えてきたことに気付きました。

手作業で管理するのはめんどくさい ので,.vscode/extensions.json に最低限必要そうな拡張機能をメモすることにしました。

.vscode/extensitons.json
extensions.json
{
    "recommendations": [
        // coding style
        "DavidAnson.vscode-markdownlint",
        "EditorConfig.EditorConfig",
        // commit message
        "benjaminadk.emojis4git",
        // svelte
        "JamesBirtles.svelte-vscode",
        "fivethree.vscode-svelte-snippets",
        // scss
        "sissel.scss-style-tag",
    ]
}

該当コミットはこちら (ここまで:2020/02/01 21:06:23)

2.6.2 その他の設定

(以下 2020/02/05 18:19:55 追加分)

.vscode/settings.json も書いていきます

.vscode/settings.json
settings.json
{
  /* Validation */
  "css.validate": false,
  "scss.validate": true,
  "eslint.validate": [
    "javascript",
    "javascriptreact",
    "html"
  ],
  /* others */
  "files.associations": {
    "*.svelte": "html",
  },
  /* Markdown */
  "markdownlint.config": {
    "no-trailing-spaces": true,   // MD009 default
    "no-multiple-blanks": {       // MD012
      "maximum": 2
    },
    "line-length": false,         // MD013
    "commands-show-output": true, // MD014 default
    "blanks-around-headers": {    // MD022
      "lines_above": 2,
      "lines_below": 1
    },
    "single-h1": true,            // MD025 default
    "fenced-code-language": true, // MD040 default
    "first-header-h1": true,      // MD041 default
  },
}

Markdown の lint を拡張機能で実現しています
CSS の代わりに SCSS を使うので,そのように設定しています

(以上 2020/02/05 18:19:55 追加分)

2.7 CI の構築 (GitHub Actions)

GitHub Actions を使って CI / CD 環境を構築していきます
やっと日本語でドキュメントが読める :joy:

2.7.1 テストの導入

Sapper テンプレートに入っていたテストライブラリ Cypress を使ってみます

テンプレには,UI テストがちょっとだけ書いてあるので,それを動かしてみます

$ yarn add --dev cypress
$ yarn test

テスト結果

yarn run-p --race dev cy:run の実行結果

上の画像は,yarn test (yarn run-p --race dev cypress run) の実行結果です

テスト項目の「has the correct <h1>」,「navigates to /about」,「navigates to /blog」をクリアしていることがわかります

yarn run-p --race dev cy:open の実行結果

上の動画は,yarn run-p --race dev cypress open の実行結果です(ファイルサイズ削減のため2.5倍速にしています)

GUI が立ち上がってわかりやすくテストの実行やその結果の閲覧ができます

いい感じ!!

2.7.2 テストの自動化

GitHub Actions を使って,テストを自動化していきます

まずは .github フォルダを作るところからです3

$ mkdir .github
$ mkdir .github/workflows
$ touch .github/workflows/test-and-build.yml

pull_request push (一人なので PR を出す必要性がなかった) したタイミングでテストとビルドが走るようにします

CI 環境は以下です

機能 バージョン 理由
OS ubuntu-latest 手元の mac で動くことは確認できるため,あとで他の PC から編集できるように(本当は CentOS が嬉しいけどセルフホストするサーバーがない)
node.js 12.x LTS のうち最新のもの

コードはこんな感じ
test-and-build.yml
name: Test and Build

on: push

jobs:
  test-build:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v1
      - uses: actions/setup-node@v1
        with:
          node-version: '12.x'
      - name: install dependencies
        run: yarn --frozen-lockfile
      - name: test
        run: yarn test
      - name: sapper export static files
        run: yarn export

依存関係をインストールするときに,ローカルのものと異なると困るので,--frozen-lockfileyarn.lock に書かれたバージョンを使うようにしてます

あと次いでにビルドが通るかどうかも一応チェックしてます

これを push します

スクリーンショット 2020-02-05 12.50.42.png

スクリーンショット 2020-02-05 12.51.18.png

CI がちゃんと動くと嬉しい :laughing:

自分で GitHub Actions の設定をするのがはじめてだったので (CI 構築自体2回目),手戻りが多く発生してしまい,該当コミットと言えるものはないです :bow_tone1:
記事には載せているので,上の折り畳みを開いて確認してください(ここまで:2020/02/05 13:08:01)

2.7.3 cache を利用する

時間がかかる依存関係のインストールを cache を使って高速化します(正直する必要があるほど遅くないですが,GitHub さんのサーバーの負担を気持ち分減らすためです)

yarn での cache 利用のサンプル - GitHub

公式にやり方が紹介されていたので,これをそのまま使いました

スクリーンショット 2020-02-05 14.07.52.png

cache を使う前は install dependencies ステップにかかる時間は25-27秒でした :cry:

スクリーンショット 2020-02-05 14.22.27.png

cache 利用直後は18秒に改善しました :clap:

該当コミットはこちら (ここまで:2020/02/05 14:33:15)

参考

英語サイト

日本語サイト

主な変更履歴

  • 2020/01/26 05:50:39 インストールまで
  • 2020/01/26 05:53:55 sirv-cli の使いどころが思ったよりなかったのでタイトルを編集しました
  • 2020/01/26 06:13:35 Sapper がいいらしいので Sapper を使うことにしました
  • 2020/01/28 06:23:39 Sapper のインストール
  • 2020/01/28 07:26:21 security alert の解消
  • 2020/02/01 21:06:23 Sass の導入と VS Code の拡張機能の管理
  • 2020/02/05 13:08:01 Cypress + GitHub Actions で CI の構築
  • 2020/02/05 14:33:15 CI での依存関係のインストールに cache を利用する
  • 2020/02/05 18:19:55 VS Code の設定ファイル

  1. nuxt-create-app の TypeScript 対応が待ちきれなかったので Nuxt+TypeScript のテンプレート を作ったりしています 

  2. s/\t/\s\s/g 全部スペースに置換してもいいんですが,テンプレがタブ文字ということは,Sapper Community では「タブ派」がマジョリティなのかなと思い揃えることにしました。 

  3. touch コマンドはファイル作成コマンドじゃないぞ」というのは全くもってその通りです。ファイルの最終更新日時を変更するコマンドの用途外使用です(これでおk) 

14
11
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14
11