LoginSignup
7
6

More than 3 years have passed since last update.

Figma PluginをVue.js + TypeScript + Sass + Bulmaで開発する

Posted at

About

Figma Pluginに未来を感じています。

公式ドキュメントには、UIをReactで構築する流れ(Building React)が紹介されています。
しかし、個人的に(会社的に)はVueに慣れていることもあり、以下の環境で構築してみようと試みました。

  • Vue.js
  • TypeScript
  • Sass
  • Bulma

注: Figma Pluginはあまり関係なく、ほぼWebpackの設定の問題ですw

結論

GitHubにコードを置いておきました。

解説: ビルド環境

まず、公式ドキュメントのBundling with Webpackを参考に、Webpackベースのコードベースを構築しました。
公式GitHubにサンプルがあります。

以下は、Bundling with Webpackのコードベースからの差分に関する解説です。

package.json

Vue.js, Sass, Bulmaを使うために必要なパッケージを追加しました。

$ npm install --save vue vue-class-component vue-property-decorator bulma
$ npm install --save-dev node-sass sass-loader vue-loader vue-template-compiler

tsconfig.json

Vue.jsのTypeScript推奨構成に変更しました。

tsconfig.json
{
  "compilerOptions": {
    "target": "es5",
    "strict": true,
    "experimentalDecorators": true,
    "moduleResolution": "node",
    "module": "es2015"
  }
}

webpack.config.js

主な変更点

  • rules
    • vue-loaderの設定を追加
    • ts-loaderのオプションにappendTsSuffixTo: [/\.vue$/]を追加
    • sass-loaderの設定を追加
  • resolve
    • .vueに関する設定を追加
  • plugins
    • VueLoaderPluginを追加
...

const VueLoaderPlugin = require('vue-loader/lib/plugin')

...

module.exports = (env, argv) => ({
  ...

  module: {
    rules: [
      {
        test: /\.vue$/,
        loader: 'vue-loader',
        options: {
          loaders: {
            'scss': 'vue-style-loader!css-loader!sass-loader',
            'sass': 'vue-style-loader!css-loader!sass-loader?indentedSyntax'
          }
        }
      },
      {
        test: /\.tsx?$/,
        loader: 'ts-loader',
        exclude: /node_modules/,
        options: {
          appendTsSuffixTo: [/\.vue$/]
        }
      },
      ...
      {
        test: /\.scss$/,
        loader: [
          { loader: 'style-loader' },
          { loader: 'css-loader' },
          { loader: 'sass-loader' }
        ]
      },
      ...
    ],
  },

  resolve: {
    extensions: ['.tsx', '.ts', '.jsx', '.js', '.vue'],
    alias: {
      'vue$': 'vue/dist/vue.esm.js'
    }
  },

  plugins: [
    ...
    new VueLoaderPlugin()
  ]
})

解説: UIの実装

Reactのサンプルと同じく、指定した数の正方形を描画するRectangle CreatorをVueで実装してみました。

まず、UIのエントリポイントsrc/ui.htmlsrc/ui.tsです。

src/ui.html
<div id="app"></div>
src/ui.ts
import Vue from 'Vue'
import RectangleCreator from './RectangleCreator'
import './ui.scss'

new Vue({
  el: '#app',
  render (h) {
    return h('rectangle-creator')
  },
  components: {
    RectangleCreator
  }
})

src/ui.scssでは、Bulmaを読み込んで変数の設定などを行います。

src/ui.scss
@charset "utf-8";

@import "~bulma/sass/utilities/initial-variables";
@import "~bulma/sass/utilities/functions";

$brand: #18A0FB;
$primary: $brand;

@import "~bulma/bulma";

最後に、BulmaのCSSを使ってRectangle Creatorを書き換えてみます。

src/RectangleCreator.vue
<template>
  <div class="container">
    <h2 class="title is-4">Rectangle Creator</h2>

    <div class="field">
      <label class="label">Count</label>
      <p class="control">
        <input class="input is-small" type="number" v-model="count">
      </p>
    </div>

    <div class="field is-grouped is-grouped-centered">
      <p class="control">
        <button class="button is-primary is-small" @click="create">
          Create
        </button>
      </p>
      <p class="control">
        <button class="button is-small" @click="cancel">
          Cancel
        </button>
      </p>
    </div>
  </div>
</template>

<script lang="ts">
import Vue from 'vue'
import Component from 'vue-class-component'

@Component({
  name: 'RectangleCreator'
})
export default class RectangleCreator extends Vue {
  count: number = 5

  create () {
    parent.postMessage({ pluginMessage: { type: 'create-rectangles', count: this.count } }, '*')
  }

  cancel () {
    parent.postMessage({ pluginMessage: { type: 'cancel' } }, '*')
  }
}
</script>

<style lang="scss">
.container {
  padding: 0.75rem;
}
</style>

実行するとこんな感じ

スクリーンショット 2019-08-22 17.05.17.png

参考: 途中ハマったこと

初期提供のfigma.d.tsが古い問題

Figma Desktop Appでプラグインの初期生成したときに提供されるfigma.d.tsは古い?もので問題があり、コンパイルエラーが発生しました。
(2019/08/22現在)

具体的には、LineHeightのインタフェース定義でエラーになります。

interface LineHeight {
  readonly value: number
  readonly unit: "PIXELS" | "PERCENT"
} | {
  readonly unit: "AUTO"
}

GitHubのサンプルのfigma.d.tsを参考に、型エイリアスに書き換えることで解決しました。

type LineHeight = {
  readonly value: number
  readonly unit: "PIXELS" | "PERCENT"
} | {
  readonly unit: "AUTO"
}
7
6
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
7
6