svelte material ui の導入

# svelte material ui の導入

svelte版のmaterial uiである｡smuiを導入しようとしたがrollupの設定をいじったり､追加のパッケージを導入したりで面倒そうなので､ここにまとまることとする｡

## ファイル構成

今回は以下のような構成で作成する

    root
    └─public
    │ └─grobal.css
    │ └─index.html
    ├─src
    │ └─component - svelte componentを入れます
    │ ├─theme
    │ │ └─_smui-theme.scss
    │ ├─App.scss
    │ ├─App.svelte
    │ └─main.js
    ├─package.json
    └─rollup.config.js

## 必要なパッケージ

* svelte (svelteそのもの)

* serve (開発用:ローカルサーバを立てる)

* rollup (モジュールバンドラー)

* @rollup/plugin-commonjs (commonjs->ESModuleコンバーター)

* @rollup/plugin-node-resolve (サードパーティ製のモジュールを使うにあたって､Node resolution algorithmを使ってモジュールを見つける)

* rollup-plugin-livereload (開発用:ファイルの更新を検知してリロードする)

* rollup-plugin-postcss (バンドルする際にpostcss->cssにコンパイルする)

* rollup-plugin-svelte (svelteコンポーネントをコンパイルする)

* rollup-plugin-terser (JSをバンドルするときに軽量化する)

* node-sass (smuiのスタイルはSassで書かれているので必要)

smuiはすべてのコンポーネントを一括ダウンロードしてもいいし､必要なものだけ個別にダウンロードすることもできます｡

### rollup.config.jsの設定

```js:rollup.config.js
import svelte from 'rollup-plugin-svelte'
import resolve from '@rollup/plugin-node-resolve'
import cjs from '@rollup/plugin-commonjs'
import postcss from 'rollup-plugin-postcss'
import livereload from 'rollup-plugin-livereload'
import { terser } from 'rollup-plugin-terser'

const production = !process.env.ROLLUP_WATCH

const options = {
  svelte: {
    dev: !production,
    emitCss: true,
  },
  resolve: {
    browser: true,
    dedupe: importee => importee === 'svelte' || importee.startsWith('svelte/')
  },
  cjs: {},
  postcss: {
    extract: true,
    minimize: true,
    use: [['sass', { includePaths: ['./src/theme', './node_modules'] }]]
  }
}

export default {
  input: 'src/main.js',
  output: {
    soucemap: false,
    file: 'public/build/bundle.js',
    format: 'iife',
    name: 'app'
  },
  plugins: [
    svelte(options.svelte),
    resolve(options.resolve),
    cjs(),
    postcss(options.postcss),
    !production && serve(),
    !production && livereload('public'),
    production && terser
  ],
  watch: { cleanScreen: false }
}

function serve() {
  let started = false
  return {
    writeBundle() {
      if (!started) {
        started = true
        require('child_process').spawn('npm', ['run', 'start', '--', '--dev'], {
          stdio: ['ignore', 'inherit', 'inherit'],
          shell: true
        })
      }
    }
  }
}
```

各種オプションの設定です｡

**rollup-plugin-svelte**

emitCss: postcssなどで処理するためにCSSを生成したいので､trueにします

**@rollup/plugin-node-resolve**

このプラグインはcommonjsプラグインを使った際､インストールされたcommonjsパッケージを解決するために使います｡([rollup-plugin-commonjs](https://github.com/rollup/plugins/tree/master/packages/commonjs)のページに書いてありました｡)

browser: アプリはブラウザで動かすものなのでtrueにします｡

dedupe(重複解決): ここの設定の意味はよく分かっていません

**@rollup/plugin-commonjs**

デフォルトの設定のまま使います

**rollup-plugin-postcss**

extract: cssの抽出設定です｡jsファイルと同じ場所に抽出されます｡

minimize: cssを軽量化します

use: sassとかlessとかを使えるようにするものです｡smuiはsassを使っているので､sassにします｡またsassファイルの場所を指定しています｡

## Usage

SMUIの使用方法を見てみましょう

1. バンドルするためにはsassプロセッサーが必要です(svelteのプリプロセッサではなくsassプロセッサーです｡)｡SMUIはindex.jsでインポートしたsassファイルをコンパイルする必要があるためです｡またsvelteファイルでsassやcssをインポートする必要はないでのsvelte preprocessorは必要ではありません｡

2. sassがあるパスに`_smui-theme.scss`を作る必要があります｡これはMDCテーマ変数を設定するためのファイルです｡何も書かなければデフォルト設定を使います｡デモファイルに設定をしているのでそちらを参照してください｡

3. material icon, roboto, roboto monoを使う場合はインクルードしてください｡

## src側の設定

### smui-themeの作成

smuiにテーマを適用させるために`thmeme/_smui-theme.scss`を作成してください｡中身は何も書かなくてもOKです｡その場合デフォルトのテーマが適用されます｡これを作っておかないとエラーが出ます｡

### App.scssの作成

### App.svelteの作成

コンポーネントはここに読み込むようにしましょう｡

### main.jsの作成

```js:main.js
// 出力するためのJSファイルです
import './App.scss'
import App from './App.svelte'

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

export default app
```

## public側の設定

### index.html

```html:index.html
<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>SMUI sample</title>

    <!-- favicon -->
    <link rel="shortcut icon" href="/favicon.png" type="image/png" />

    <!-- font & css -->
    <link rel="stylesheet" href="/global.css" />
    <link rel="stylesheet" href="/build/bundle.css" />
    <link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons" />
    <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,600,700" />
    <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto+Mono" />

    <script defer src="/build/bundle.js"></script>
  </head>
  <body></body>
</html>
```

### global.css

すべてのコンポーネントに適用するスタイルはここに書きます｡

## 開発スタート

すべての準備が整いました｡では､ターミナルで`npm run dev`として開発を初めましょう! お疲れさまでした!!

次回は実際にSMUIのコンポーネントをつかってコンポーネントを作ってみようと思います｡

## 参考

こちらのリポにあるrollupの設定ファイルをパクりながら作りました｡
[sveltejs/tempate](https://github.com/sveltejs/template](https://github.com/sveltejs/template))
[smui-example-rollup](https://github.com/hperrin/smui-example-rollup](https://github.com/hperrin/smui-example-rollup))