📑

【Svelte】SvelteとTypeScriptとFirebaseで個人開発するための土台を作る

2022/06/10に公開

はじめに

Svelteコンポーネントの中でアプリ開発をする分には特に問題なかったのですが、CSSをモジュールとして外に切り出す設定方法やFirebaseとの連携などでReact, Vue.jsと異なる点があったので後続の方が少しでもこの記事で躓きがなくなればと思いメモします。

セットアップ

Vscodeの拡張を利用しないとリンターが効かないのでSvelteを始めるには拡張機能でSvelte for VS Codeをインストールする必要がありました。また、添付しているドキュメントにも記載されている通り、settings.jsonに次のコードを記載する必要があリます。

settings.json
 "[svelte]": {
     "editor.defaultFormatter": "svelte.svelte-vscode"
   },
.prettierrc
{
  "useTabs": false,
  "semi": true,
  "trailingComma": "all",
  "singleQuote": true,
  "tabWidth": 2,
  "svelteSortOrder": "options-scripts-markup-styles",
  "svelteStrictMode": true,
  "svelteBracketNewLine": false,
  "svelteAllowShorthand": false,
  "svelteIndentScriptAndStyle": false
}

svelteSortOrder上記のように設定するとscript→html→styleの順になります。

https://marketplace.visualstudio.com/items?itemName=svelte.svelte-vscode

dotenv

FirebaseのAPIキーを.envに登録してprocess.env.NODE_ENVで使いたかったのですが、Rollupのプラグインを使う必要がありました。使用するパッケージは下記の2つです。

https://www.npmjs.com/package/@rollup/plugin-replace

https://www.npmjs.com/package/dotenv

@rollup/plugin-replaceは最終的に出力する内容にたいして置換を実行してくれます。

rollup.config.js
import replace from '@rollup/plugin-replace';
import dotenv from 'dotenv';
dotenv.config();
// ...
plugins: [
    replace({
      'process.env.API_KEY': JSON.stringify(process.env.API_KEY),
      'process.env.AUTH_DOMAIN': JSON.stringify(process.env.AUTH_DOMAIN),
      'process.env.PROJECT_ID': JSON.stringify(process.env.PROJECT_ID),
      'process.env.STORAGE_BUCKET': JSON.stringify(process.env.STORAGE_BUCKET),
      'process.env.MESSAGING_SENDER_ID': JSON.stringify(
        process.env.MESSAGING_SENDER_ID,
      ),
      'process.env.APP_ID': JSON.stringify(process.env.APP_ID),
    }),
// ...

https://www.donielsmith.com/blog/2020-05-11-how-to-use-dotenv-with-svelte-3/

トラブルシューティング

Rollup plugin-replace: preventAssignment set to "false"

もし上記エラー文言が出た際は次のようなオプションを追加することで回避することができます。次のイシューを参考に解決しました。

https://github.com/sveltejs/sapper-template/issues/302

rollup.config.js
import replace from '@rollup/plugin-replace';
import dotenv from 'dotenv';
dotenv.config();
// ...
plugins: [
    replace({
      preventAssignment: true, // 追加
      'process.env.API_KEY': JSON.stringify(process.env.API_KEY),
      'process.env.AUTH_DOMAIN': JSON.stringify(process.env.AUTH_DOMAIN),
      'process.env.PROJECT_ID': JSON.stringify(process.env.PROJECT_ID),
      'process.env.STORAGE_BUCKET': JSON.stringify(process.env.STORAGE_BUCKET),
      'process.env.MESSAGING_SENDER_ID': JSON.stringify(
        process.env.MESSAGING_SENDER_ID,
      ),
      'process.env.APP_ID': JSON.stringify(process.env.APP_ID),
    }),
// ...

Sass

svelteコンポーネント外に切り出したsassファイルをバンドルする方法がわからず躓きました。調査をしてもsvelteコンポーネントのstyleタグをsassで書く手法が散見したため実装が遅れてしまいました。下記プラグインを使用します。

SvelteでSassを使う時はsvelte-preprocessを使用するケース多く見受けられsvelteコンポーネント外のSassをバンドルする方法があまり散見しなかったです。

https://www.npmjs.com/package/rollup-plugin-scss

※ドキュメント参照

rollup.config.js
import scss from 'rollup-plugin-scss'

export default {
  input: 'input.js',
  output: {
    file: 'output.js',
    format: 'esm'
  },
  plugins: [
    scss() // will output compiled styles to output.css
  ]
}

entry.js
import './reset.scss'
main.ts

import App from './App.svelte';
import './assets/scss/app.scss';

const app = new App({
  target: document.body,
  props: {
    ready: false,
  },
});

export default app;

トラブルシューティング

  • 動的にCSSを実装することができない時はどうすれば良いのか?

ReactアプリではできたのにSvelteではできない模様。下記の記事を参考に実装することができました。

https://zenn.dev/mouse_484/scraps/b5306933034466

image

assets/iconディレクトリ配下にあるIconをsvelteコンポーネント内で呼び出すことができませんでした。インポートさせるために@rollup/plugin-imageを使ってimageを読み込む必要があります。

https://www.npmjs.com/package/@rollup/plugin-image

※ @rollup/plugin-imageはSVGだけでなくJPG, PNG, GIF, WebP filesをインポートすることができます。

トラブルシューティング

  • 型エラーが発生する際の対処法

TypeScriptを使用しているため方エラーが発生しました。下記で解決しました。

https://stackoverflow.com/questions/44717164/unable-to-import-svg-files-in-typescript

src/@types/custom.d.ts
declare module '*.svg' {
  const content: any;
  export default content;
}

ルーティング

アプリを作るときは必ずと言っていいほど必要なルーティング機能ですが、実装するのに時間がかかり記事を作成しました。個人開発で使用したsvelte-routingに関しての記事になりますのでお時間ありましたらご覧ください。

下記の記事内でも触れていますがnpmトレンド的にルーティングはsvelte-routingを選択して問題なさそうな気がします。

https://zenn.dev/shuuuuuun/articles/f58391e617b2bc

さいごに

ここまでご覧いただいてご理解いただけたかと思いますが、Rollup(そもそものモジュールバンドラー)に関する理解がまるで追いついていないことが躓いた原因でした。私と同じように「モジュールバンドラー??」な方は先にRollupのキャッチアップをしてみると良いかもしれません。

Svelteのアプリを作ると初期の段階で必要最低限のsvelteを含むバンドルプラグインが実装されていて、すぐに開発を進めることができます。しかし、今回の私のようにsassやimageやdotenvなどを使用する際は適宜プラグインを追加してバンドルできる環境を作る必要があります。

下記はRollup公式でのプラグインの使い方についてガイドラインが載っています。
https://rollupjs.org/guide/en/#using-plugins

Rollupがサポートしているプラグインは下記で参照することができます。
https://github.com/rollup/awesome

補足

一応公式としてwebpackのテンプレートも用意しているようなので、Rollupに慣れていない人はwebpackをバンドルツールとして選択するのも良いかと思います。

https://github.com/sveltejs/template-webpack

SvelteはデフォルトでRollupをモジュールバンドラーとして採用しており、これはSvelteの製作者Rich HarrisさんがRollupの開発者であることが起因しているのかもしれません。そのため、これから情報として出てくるのはRollupを基準としたものが豊富になるかもしれません。

以上、駆け足になりましたが最後までご覧いただきありがとうございました。この記事が少しでも誰かの助けになりましたら幸いです。

Discussion