Svelte + Sapper + TypeScript + TailwindCSS + Svelte Material UI

Svelte Material UIを追加

前回のTailwindCSS対応にSvelte Material UIを追加する。

ここまでの作業

www.axon.jp

Svelte Material UIと関連パッケージを追加

$ yarn add -D svelte-material-ui rollup-plugin-postcss node-sass

テーマ用の空のscssを作成

$ mkdir src/theme && touch src/theme/_smui-theme.scss

typesにsmuiを追加

typings/@smui/index.d.ts

declare module "@smui/button";
declare module "@smui/card";
declare module "@smui/checkbox";
declare module "@smui/chips";
declare module "@smui/common";
declare module "@smui/data-table";
declare module "@smui/dialog";
declare module "@smui/drawer";
declare module "@smui/fab";
declare module "@smui/floating-label";
declare module "@smui/form-field";
declare module "@smui/icon-button";
declare module "@smui/image-list";
declare module "@smui/line-ripple";
declare module "@smui/linear-progress";
declare module "@smui/list";
declare module "@smui/menu";
declare module "@smui/menu-surface";
declare module "@smui/notched-outline";
declare module "@smui/paper";
declare module "@smui/radio";
declare module "@smui/ripple";
declare module "@smui/select";
declare module "@smui/slider";
declare module "@smui/snackbar";
declare module "@smui/switch";
declare module "@smui/tab";
declare module "@smui/tab-bar";
declare module "@smui/tab-indicator";
declare module "@smui/tab-scroller";
declare module "@smui/textfield";
declare module "@smui/top-app-bar";

tsconfig.jsonのtypingに@smuiを追加

tsconfig.json

{
  ...
  "compilerOptions": {
    "types": ["svelte", "node", "@sapper", "@smui"],  // @smuiを追記
    ...
  }
}

rollup.config.jsを修正

rollup.config.js

import postcss from "rollup-plugin-postcss"; // 追加
...
const postcssOptions = () => ({ // 追加
  extensions: [".scss", ".sass"],
  extract: false,
  minimize: true,
  use: [
    [
      "sass",
      {
        includePaths: [
          "./src/theme",
          "./node_modules",
        ],
      },
    ],
  ],
});
...

export default {
  client: {
    ...
    plugins: [
      ...
      typescript({sourceMap: !production}),
      postcss(postcssOptions()), // 追加
      ...
    ],
  },
  ...
  server: {
    ...
    plugins: [
      ...
      typescript({sourceMap: !production}),
      postcss(postcssOptions()), // 追加
      ...
    ],
  },
}
...

サンプルコード

src/routes/index.svelteを編集

<script lang="ts">
  import { title } from "../models/common";
  import Button from "@smui/button"; // 追加
</script>
...
<Button variant="raised">Button</Button> <!-- 追加 -->

リップル妨害の解除とアウトライン削除のスタイルを追加

stypes/tailwindcss

/* 追加のスタイルはここに記述 */
...

/* ripple妨害の解除とアウトライン削除 */
*,
*::before,
*::after {
  border-width: unset;
  border-style: unset;
  border-color: unset;
}
button:focus {
  outline: unset;
  outline: unset;
}
img {
  border-style: none;
}

.card-container {
  user-select: none !important;
}

CSSファイルを生成

static/global.cssを生成

$ yarn postcss styles/tailwind.css -o static/global.css

Svelte + Sapper + TypeScript + TailwindCSS

TailwindCSSを追加

前回の外部TypeScriptファイル対応に加えTailwindCSSを追加する。

ここまでの作業

www.axon.jp

TailwindCSSとPostCSS-CLiと関連パッケージをインストール

postcss-purgecssはNODE_ENVにproductionを指定し不要なセレクタを除いたCSSファイルを生成するように設定するために使用します。

$ yarn add -D tailwindcss postcss-cli
$ yarn add @fullhuman/postcss-purgecss
// 設定ファイルを生成
$ npx tailwindcss init

読み込み用CSSファイルを作成

styles/tailwind.cssをもとにstatic/global.cssが生成される。必要であればデフォルトのglobal.cssの内容はtailwind.cssの末尾に追記しておく。

$ mkdir styles

./styles/tailwind.css

@tailwind base;
@tailwind components;
@tailwind utilities;

/* 追加のスタイルはここに記述 */

PostCSS CLiの設定ファイルを追加

postcss.config.js

const tailwindcss = require("tailwindcss");
const purgecss = require("@fullhuman/postcss-purgecss")({
  content: ["./src/**/*.svelte", "./src/**/*.html"],
  defaultExtractor: (content) => content.match(/[A-Za-z0-9-_:/]+/g) || [],
});

module.exports = {
  plugins: [
    tailwindcss("./tailwind.config.js"),
    ...(process.env.NODE_ENV === "production" ? [purgecss] : []),
  ],
};

CSSファイルを生成

static/global.cssを生成

$ yarn postcss styles/tailwind.css -o static/global.css

サンプルコード

src/routes/index.svelteを編集

...
<h1 class="text-blue-500">Great success!</h1>

Svelte + Sapper + TypeScript (2)

外部TypeScriptファイル対応

前回のSvelteファイル内のTypeScript対応に加え外部TypeScriptファイルに記述できるように設定する。

ここまでの作業

www.axon.jp

TypeScript環境のパッケージをインストール

$ yarn add -D @rollup/plugin-typescript

ルートにtsconfig.jsonを作成

./tsconfig.json

{
  "extends": "@tsconfig/svelte/tsconfig.json",
  "include": ["src/**/*","src/node_modules"],
  "exclude": ["node_modules/*","__sapper__/*","public/*"],  
  "compilerOptions": {
    "types": ["svelte", "node", "@sapper"],
    "typeRoots": ["typings"],
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "strict": true
  }
}

rollup.config.jsを修正

./rollup.config.js clientとserverのplugins/svelteの後にtypescriptを追加

...
import typescript from '@rollup/plugin-typescript'; // 追加
...
const production = mode === "production"; // 追加
...
export default {
  client: {
    ...
    plugins: [
      svelte({
        ...
      }),
      typescript({sourceMap: !production}), // 追加
      ...
    ],
  },
  ...
  server: {
    ...
    plugins: [
      svelte({
        ...
      }),
      typescript({sourceMap: !production}), // 追加
      ...
    ],
  },
}

typingsにsapperを追加

$ mkdir -p typings/@sapper

typings/@sapper/index.d.ts

declare module "@sapper/app";
declare module "@sapper/server";
declare module "@sapper/service-worker";

client.js,server.jsファイルをtsファイルに変更

拡張子をjsからtsに変更

$ mv src/client.js src/client.ts
$ mv src/server.js src/server.ts

rollup.config.jsを編集

  client: {
    // input: config.client.input(),
    input: config.client.input().replace(/\.js$/, '.ts'), // 編集
  ...
  },
  server: {
    // input: config.server.input(),
    input: config.server.input().server.replace(/\.js$/, '.ts'), // 編集
  ...
  },

server.ts内で必要な定義をインストール

$ yarn add @types/polka @types/compression

server.tsのエラーを修正

src/server.ts

  // .listen(PORT, err => {
  .listen(PORT, (err: any) => {

サンプルコード

src/models/common.tsを作成

export const title:string = "TypeScript File";

src/routes/index.svelteを編集

<script lang="ts">
  import {title} from '../models/common';
</script
...
<h1>Great success!</h1>
<div>{title}</div>

注意:tsファイル新規作成時はnodeの再起動が必要

Svelte + Sapper + TypeScript (1)

SvelteファイルのTypeScript対応

Sapperテンプレートを使用したSvelteファイル内でTypeScriptを記述できるように設定をする。

Sapperのテンプレートを取得してパッケージをインストール

$ npx degit sveltejs/sapper-template#rollup sapper-typescript
$ cd sapper-typescript
$ yarn
$ yarn dev

TypeScript関連パッケージをインストール

公式に従ってTypeScript関連パッケージをインストール

$ yarn add -D @tsconfig/svelte typescript svelte-preprocess svelte-check

rollup.config.jsを修正

clientとserverのplugins/svelteにpreprocessを追加

./rollup.config.js

...
import autoPreprocess from "svelte-preprocess"; // 追加
...

export default {
  client: {
    ...
    plugins: [
      svelte({
        preprocess: autoPreprocess(), // 追加
        ...
      }),
      ...
    ],
  },
  ...
  server: {
    ...
    plugins: [
      svelte({
        preprocess: autoPreprocess(), // 追加
        ...
      }),
      ...
    ],
  },
...
}

サンプルコード

<script lang="ts">
  let title: string = "TypeScript";
</script
...
<h1>Great success!</h1>
<div>{title}</div>

VSCodeの拡張機能 REST Clinet をもっと便利に使う

下記公式に書いてありますがREST Clientで変数を利用する書き方

github.com

変数に値を保持して利用する

普通に変数にURLを保持しておいて使い回す。

@baseUrl = http://127.0.0.1:5000/api

###
{{baseUrl}}/values 

APIの戻り値を保持して利用する

loginの戻り値がJSONで内部にTokenがある場合。 loginという名前でAPIを定義しておいてauthTokenという変数にレスポンスのTokenを保持する。 loginのリクエストを送信した時点でauthToken変数が有効になる。

@baseUrl = http://127.0.0.1:5000/api

###
# @name login
POST {{baseUrl}}/login HTTP/1.1
content-type: application/json

{
    "loginId":"loginId",
    "password":"pass",
}
###
@authToken = {{login.response.body.$.token}}

APIの戻り値を保持して利用する

先ほど取得した変数を使用する。

GET {{baseUrl}}/authorized_method HTTP/1.1
content-type: application/json
Authorization: Bearer {{authToken}} 

nvimでCコーディング

Ctags と vim-clang で定義へ移動

ctagsをインストール
$ sudo apt-get install ctags
deinファイルにvim-tagsを追加

~/.vim/rc/nvim/dein.toml

[[plugins]]]
repo = 'szw/vim-tags'
ctagsのパスを追加
$ which ctags
/usr/bin/ctags
initVimに追記

~/.config/nvim/init.vim

let g:vim_tags_project_tags_command = "/usr/bin/ctags -R {OPTIONS} {DIRECTORY} 2>/dev/null"
let g:vim_tags_gems_tags_command = "/usr/bin/ctags -R {OPTIONS} `bundle show --paths` 2>/dev/null"

vim-clang でコード補完

deinファイルにvim-clangを追加

~/.vim/rc/nvim/dein.toml

[[plugins]]]
repo = 'justmao945/vim-clang'

Chromebook Linux(Crostini)でVSCodeのターミナル起動エラーを回避する

ChromebookLinuxアプリを使用していて、外部にターミナルを表示する処理があった場合にCrostiniではターミナルが表示できないためエラーになってしまいます。
回避するためにKonsoleのインストールとxtermのシンボリックリンクに設定しておきました。

$ sudo apt-get install konsole
$ sudo ln -s /usr/bin/konsole /usr/bin/xterm

VSCodeC++デバッグをしている時に外部ターミナルが開かれるのですが、そのときにエラーになっていたのを回避できました。