LoginSignup
50
31

More than 3 years have passed since last update.

Nuxt.js+Figma+Storybookでデザイン重視なチーム開発を!

Last updated at Posted at 2020-12-18

アプリ開発をチームで行う際、エンジニアとデザイナーのコミュニケーション問題はこれまで大きな課題とされてきました。
最近は色々なサービスが出ているため、チーム内コミュニケーションは改善されつつあるものの未だベストな方法を模索している方は少なくないでしょう。
この記事ではデザイナーとエンジニアが仲良く開発できるようになるためのヒントが共有できればと思っています。

はじめに

NTTドコモの熊川です。
これはNTTドコモR&D Advent Calendar 2020の19日目の記事です。
普段はIoTクラウドの研究開発やその周辺アプリの開発、データ分析、これらのアセットを用いたビジネス化検討を行っています。
今回はWebアプリ開発で人気のフレームワークのNuxt.js、プロトタイプ開発ツールで最近急浮上中のFigma、そしてUIコンポーネントカタログ化ツールのStorybookを用いた開発方法についてご紹介します。

なぜNuxt.js、Figma、Storybook?

Nuxt.js

Nuxt.jsとはVue.jsのWeb開発フレームワークであり、
- SPA(Single Page Application)
- SSR(Server Side Rendering)
- SSG(Static Site Generation)
をものすごく簡単に構築できる優れものです。
また、デフォルトでフロントサイドはVue.js、サーバサイドがNode.js(Express)で動作するため、Webアプリを開発する上での環境は予め揃っています。
最近ではデータ分析✕Webの界隈でFlaskやDjangoが使われることもありますが、小・中規模の一般的なWebサイトをさくっと開発したいのであればNuxt.jsを使うことをおすすめします。
この理由はいくつかありますが、Nuxt.jsの設計基盤であるMVVMはRailsのMVCやDjangoのMTVに比べて初心者にも扱いやすいことや、SPAやSSRへの対応が非常に簡単であることが挙げられます。
ちなみに東京都の新型コロナ対策サイトもNuxt.jsが使われているようです。
まだ触ったことがない方はこの際に一度試してみてはいかがでしょうか。

Figma

ここ最近プロトタイピングツールとしてFigmaの人気が上がっています。
その特徴はなんと言ってもクラウド上で同時編集が可能な点です。
またSketchのファイルをインポートできるので、SketchからFigmaに移行するユーザも増えていきそうですね。

Storybook

StorybookはReactやVueベースで扱うことのできるUIコンポーネントカタログ化ツールです。
UIコンポーネントカタログ化ツールは作成したUIのコンポーネントのデザインをチーム全体に共有しやすくすることが可能です。
そのためデザイナーとエンジニアの密な情報共有にはもちろん、フロントエンドエンジニアの育成をしたいときにも有用です。
扱い方ですが、Nuxt.js内でStorybookアドオンを追加して使用することになるのでエンジニアサイドで準備する必要があります。

上記3つのアセット組合せ時の全体像

スクリーンショット 2020-12-03 15.45.57.png

とある日の現場...

えんじにあ「ほれ、これが仕様書、アプリデザイン頼むで」

でざいなー「突然やな。OKやで」

(数分後)

でざいなー「とりあえずFigmaでカンプ作ったわ」
※ 下記デザインはFigmaのデフォルトで用意してあるサンプルです
スクリーンショット 2020-12-02 22.50.38.png

えんじにあ「爆速やな!ええ感じやん!わいもぼちぼち開発始めるか」

えんじにあ「ちなわいの開発環境はこんな感じや」

$ npm -v
6.14.4

$ node -v
v12.16.3

Nuxt.jsアプリ作成

えんじにあ「まずはnuxt.jsでさくっとアプリ作るんや!」

$ npx create-nuxt-app nuxt-app

えんじにあ「色々聞かれるけどこれでええねん、さくっとしたいからLintは外すで!」 ※ Lintはぜひ使いましょう

create-nuxt-app v3.4.0
✨  Generating Nuxt.js project in nuxt-app
? Project name: nuxt-app
? Programming language: JavaScript
? Package manager: Npm
? UI framework: (Use arrow keys)
? UI framework: 
? UI framework: Vuetify.js
? Nuxt.js modules: Axios
? Linting tools: (Press <space> to select, <a> to toggle all, <i> to invert selection)
? Testing framework: Jest
? Rendering mode: Universal (SSR / SSG)
? Deployment target: Server (Node.js hosting)
? Development tools: jsconfig.json (Recommended for VS Code if you're not using typescript)
? Continuous integration: None
? Version control system: Git

えんじにあ「アプリの原型できた〜とりあえず実行してみよか。Nuxt.jsの準備は一旦完了や!」

$ npm run dev

スクリーンショット 2020-12-01 19.29.41.png

Storybookの準備

えんじにあ「次はでざいなーさんとのコミュニケーション円滑化のためにStorybook導入するで」

えんじにあ「Nuxt.jsでStorybook使うならnuxt/storybookが楽やで」

$ npm install --save-dev @nuxtjs/storybook

えんじにあ「これだけでStorybookをもう立ち上げられるのが最高や」

$ npx nuxt storybook

※ 自動でブラウザのlocalhost:3003が立ち上がります
スクリーンショット 2020-12-01 21.17.27.png

えんじにあ「とりあえずデフォルトで存在するLogo.vueコンポーネントのロゴでもStorybookにのっけてみるか」
※ Nuxt.js初期設定でVuetifyを選択するとLogo.vueが自動で生成されるので、ここではそれを活用します

えんじにあ「まずはcomponents配下にLogo.Stories.js作るんや」

~/components/Logo.stories.js
import Logo from './Logo'

export default {
  title: 'Logo',
}

export const Normal = () => ({
  components: { Logo },
  template: '<logo />',
})

えんじにあ「ほれ、これだけでStorybookにコンポーネントを載せられたで」
スクリーンショット 2020-12-01 22.12.51.png

でざいなー「ほう!便利そうだけどSorybookの良さはまだわからんなぁ。これを導入してわいにはどんな恩恵があるん?」

えんじにあ「Storybookを導入メリットは、わいの作ったコンポーネントをデザイナー皆さんがすぐチェックできるところや」

でざいなー「なるほどなるほど。それならわいの作ったデザインカンプも一緒にこの画面で見られんもんかね?デザインカンプとコンポーネントを見比べたくなる時がくると思うんやけど」

えんじにあ「そう言われると思っとったで!そこでFigma連携や!」

えんじにあ「Figma連携すればStorybook上でFigmaが見れるようになるんや!」

Figma連携

$ npm install --save-dev storybook-addon-designs

えんじにあ「このコマンドでパッケージを入れたら、configファイルにアドオン使うよって書いておくんや」

nuxt.config.js
export default {
  storybook: {
    addons: [
      'storybook-addon-designs'
    ],
  },
}

えんじにあ「おーい、さっき作ってたFigmaのカンプ、共有できるようにしておくれ」

でざいなー「ほいさ、Figmaのカンプを共有するときはメニューバー右上のShareボタンからAnyone with the linkを設定するんやったな...」
スクリーンショット 2020-12-01 22.22.07.png
でざいなー「できた!リンクはhttps://www.figma.com/file/○○○○やで」

えんじにあ「OKや!これでStorybookからFigmaで作ったカンプ見れるようにするやで!」

~/components/Logo.stries.js
import Logo from './Logo'

export default {
  title: 'Logo',
}

export const Normal = () => ({
  components: { Logo },
  template: '<logo />',
})

// ここから下を追記

Normal.parameters = {
  design: {
    type: 'figma',
    url: 'https://www.figma.com/file/〇〇〇〇',
  },
}

スクリーンショット 2020-12-01 22.30.05.png

えんじにあ「これでOKや!」

でざいなー「やったね!これでStorybook上でFigmaのデザインカンプとコンポーネントを見比べることができるようになったな!」

でざいなー「(これで今後は開発中もコンポーネントをしっかりチェックできるな)」

(数分後)

でざいなー「...今回開発のアプリ、ボタンは今回4種類にするつもりや。それぞれ使い回すからコンポーネント化するべきやろね」

でざいなー「色はそれぞれ#E53935#3949AB#F9A825#AED581で前3つはテキストを白く、後ろ2つは丸角のボタンにするわ」

でざいなー「そんでそんで、実際開発したボタンに適当なテキスト入れたらどんな感じになるか見てみたいんや。他にも(以下略)」

でざいなー「...Storybookってそういうのも簡単にチェックできるん?」

えんじにあ「...できるっ!!」

Storybookコントローラ設定

えんじにあ「実はこういうときにStorybookの本当の良さがでるんよ!Storybookのコントローラ機能を作っていくで」


Storybookコントローラ機能

Storybook上にプルダウンバーやテキストボックス、トグルボタン等を表示させ、それらによりコンポーネントへパラメータを渡すことで条件に応じたコンポーネントデザインを確認することができる機能


えんじにあ「まずはButtonのコンポーネント作るか」

えんじにあ「propsでパラメータの受け取り口を先に作っておくんや。こうすることで後々色・丸角・挿入テキストをコントロールできるようなるわけや」

えんじにあ「ちなみに今回の筆者さんはtemplate内の<v-app>を付けずに『Vuetifyが効かない!』と長い時間困っていたそうな」

えんじにあ「みんなは気をつけるんやで!」

~/components/Button.vue
<template>
// Vuetifyなら<v-app>で囲うのを忘れないように
  <v-app>
    <v-btn :color="color" :rounded='round'>
      <slot>{{ text }}</slot>
    </v-btn>
  </v-app>
</template>

<script>
export default {
  props: {
    color: {
      type: String,
      default: 'default',
    },
    round: {
      control: Boolean,
    },
    text: {
      control: String,
    }
  },
}
</script>

えんじにあ「次にButton.stories.jsを作ってButton.vueコンポーネントをStorybookに載っける設定やね」

えんじにあ「Logoの時と違うのは、各設定値をコントロールできるようにしていることや」

~/components/Button.stories.js
export default {
    title: 'Button',
    argTypes: {
        // ここで色選択プルダウン追加
        color: {
          control: {
            type: 'select',
            options: ['red darken-1 white--text',
                      'indigo darken-1 white--text',
                      'yellow darken-3 white--text',
                      'light-green lighten-2'],
          },
          defaultValue: 'primary'
        },
        // ここで丸角の有無を選択するトグルボタン追加
        round: { control: 'boolean' },
        // ここでテキストボックスの追加
        text: {
            control: 'text',
            defaultValue: 'Awesome Button'
        }
    }
}

export const Button = (arg, { argTypes }) => ({
    props: Object.keys(argTypes),
    template: '<Button v-bind="$props" />'
})

えんじにあ「こうするとほれ、画面下にコントロールできるところが出てくるんや」
スクリーンショット 2020-12-04 0.39.02.png

えんじにあ「これで好きにパラメータ変えて試してええで。色も変えられるし丸角ボタンも確認できる、テキストを自由に入れてみることだって可能や」

でざいなー「ええやんええやん!」

でざいなー「ええんやけど、、今の状況、、えんじにあさんのローカルでしかStorybook実行できんのは不便すぎません?」

えんじにあ「せやな...。最後にサーバにデプロイしてどっからでも見れるようにしておくか...。」

Netlifyへデプロイ


Netlifyとは

静的ホスティングサービスプラットフォームであり、Githubのリポジトリと連携させることが可能である。
Githubへpushすれば自動的にデプロイしてくれる機能もあり、サーバサイドのことを考えず簡単に扱うことができる。


えんじにあ「手順としてはgithubにこれまでのコードをアップした後、Netlifyで作ったSite(プロジェクトにようなもの)に連携させるだけや」

えんじにあ「今回NetlifyのSite設定で気をつけるべきはBuildの設定やね。下のようにBuild commandPublish directoryを設定するんや」
スクリーンショット 2020-12-07 11.23.56.png

えんじにあ「設定が完了したらあとはデプロイを待つだけ...」

えんじにあ「でけた!」

スクリーンショット 2020-12-07 12.36.22.png

えんじにあ「これからはここ(サンプル)でデザイン情報を密に共有していけるで!」
※ 今回作ったサンプルを上記URLで公開しています

でざいなー「ほんと素敵っ!これで仲良く開発できそうやねっ!」

〜めでたしめでたし〜

さいごに

今の御時世、次々に新しいツールが出ては廃れ出ては廃れを繰り返しています。
そのため最適なツールの組み合わせを探すことはもはや、永遠の課題なのかもしれません。
しかし今選択しうる最高の開発環境を、皆さんでこれからも追い続けていきましょう。

50
31
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
50
31