【Svelte】SvelteとTypeScriptとFirebaseで個人開発するための土台を作る
はじめに
Svelteコンポーネントの中でアプリ開発をする分には特に問題なかったのですが、CSSをモジュールとして外に切り出す設定方法やFirebaseとの連携などでReact, Vue.jsと異なる点があったので後続の方が少しでもこの記事で躓きがなくなればと思いメモします。
セットアップ
Vscodeの拡張を利用しないとリンターが効かないのでSvelteを始めるには拡張機能でSvelte for VS Code
をインストールする必要がありました。また、添付しているドキュメントにも記載されている通り、settings.jsonに次のコードを記載する必要があリます。
"[svelte]": {
"editor.defaultFormatter": "svelte.svelte-vscode"
},
{
"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の順になります。
dotenv
FirebaseのAPIキーを.envに登録してprocess.env.NODE_ENV
で使いたかったのですが、Rollupのプラグインを使う必要がありました。使用するパッケージは下記の2つです。
※@rollup/plugin-replace
は最終的に出力する内容にたいして置換を実行してくれます。
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),
}),
// ...
トラブルシューティング
Rollup plugin-replace: preventAssignment set to "false"
もし上記エラー文言が出た際は次のようなオプションを追加することで回避することができます。次のイシューを参考に解決しました。
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をバンドルする方法があまり散見しなかったです。
※ドキュメント参照
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
]
}
import './reset.scss'
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ではできない模様。下記の記事を参考に実装することができました。
image
assets/iconディレクトリ配下にあるIconをsvelteコンポーネント内で呼び出すことができませんでした。インポートさせるために@rollup/plugin-imageを使ってimageを読み込む必要があります。
※ @rollup/plugin-image
はSVGだけでなくJPG, PNG, GIF, WebP filesをインポートすることができます。
トラブルシューティング
- 型エラーが発生する際の対処法
TypeScriptを使用しているため方エラーが発生しました。下記で解決しました。
declare module '*.svg' {
const content: any;
export default content;
}
ルーティング
アプリを作るときは必ずと言っていいほど必要なルーティング機能ですが、実装するのに時間がかかり記事を作成しました。個人開発で使用したsvelte-routingに関しての記事になりますのでお時間ありましたらご覧ください。
下記の記事内でも触れていますがnpmトレンド的にルーティングはsvelte-routingを選択して問題なさそうな気がします。
さいごに
ここまでご覧いただいてご理解いただけたかと思いますが、Rollup(そもそものモジュールバンドラー)に関する理解がまるで追いついていないことが躓いた原因でした。私と同じように「モジュールバンドラー??」な方は先にRollupのキャッチアップをしてみると良いかもしれません。
Svelteのアプリを作ると初期の段階で必要最低限のsvelteを含むバンドルプラグインが実装されていて、すぐに開発を進めることができます。しかし、今回の私のようにsassやimageやdotenvなどを使用する際は適宜プラグインを追加してバンドルできる環境を作る必要があります。
下記はRollup公式でのプラグインの使い方についてガイドラインが載っています。
Rollupがサポートしているプラグインは下記で参照することができます。
補足
一応公式としてwebpackのテンプレートも用意しているようなので、Rollupに慣れていない人はwebpackをバンドルツールとして選択するのも良いかと思います。
SvelteはデフォルトでRollupをモジュールバンドラーとして採用しており、これはSvelteの製作者Rich Harrisさん
がRollupの開発者であることが起因しているのかもしれません。そのため、これから情報として出てくるのはRollupを基準としたものが豊富になるかもしれません。
以上、駆け足になりましたが最後までご覧いただきありがとうございました。この記事が少しでも誰かの助けになりましたら幸いです。
Discussion