Help us understand the problem. What is going on with this article?

便利にNuxt開発をするために準備していること

前書き

個人的にNuxt開発する際の準備Todoを清書しました。
目次から気になるTopicだけみていってください:smiley:

AtomicDesgin & Storybookのセットはコーディングしていて本当に気持ちいいですね:sunny:

github

以下のすべての設定を行ったrepositoryをいかにおいておきます。
forkしてshを実行していただければご利用いただけます。

https://github.com/wataboru/nuxt-initial-setting-completed

プロジェクト作成

何はともあれ、とりあえずプロジェクトを作ります。
npx create-nuxt-appで作成します。

$ npx create-nuxt-app sample-nuxt-project

create-nuxt-app v2.15.0
✨  Generating Nuxt.js project in sample-nuxt-project
? Project name sample-nuxt-project
? Project description My slick Nuxt.js project
? Author name Wataru@Boru
? Choose programming language JavaScript
? Choose the package manager Yarn
? Choose UI framework None
? Choose custom server framework None (Recommended)
? Choose Nuxt.js modules Axios
? Choose linting tools ESLint, Prettier
? Choose test framework None
? Choose rendering mode Single Page App
? Choose development tools None
<省略>

SCSSの導入

BEM形式でCSSを記載していくため、便利に使えるSCSSを導入します。

yarn add sass-loader node-sass sass-resources-loader
package.json(実行後_抜粋)
  "dependencies": {
    "@nuxtjs/axios": "^5.3.6",
    "node-sass": "^4.14.0",
    "nuxt": "^2.0.0",
    "sass-loader": "^8.0.2"
  },

リセットCSSを適応

Webブラウザの初期Styleはリセットして、ストレスフリーにスタイリングしましょう!

  1. ディレクトリ作成
    mkdir -p styles
  2. お好きなリセットCSSを取得して、上記ディレクトリに格納
    cp -p ~/hoge/reset.scss styles/
  3. nuxt.config.jsへ追記
nuxt.config.js(抜粋)
  /*
   ** Global CSS
   */
  css: [{ src: '@/styles/reset.scss', lang: 'scss' }],

AtomicDesign用のディレクトリ作成

AtomicDesignとは?という方はざっくりこの辺がわかりやすいかもしれません。
Atomic Design を分かったつもりになる | DeNA DESIGN BLOG

  • /components配下に以下作成

    • atoms
    • molecules
    • organisms
    • pages
    • (templatesについては、/layoutsを利用)
  • コマンド

mkdir -p components/atoms components/molecules components/organisms components/pages

storybookの導入

AtomicDesignによる実装に非常に効果的なStorybookを導入して、便利にコンポーネントを作っていきましょう!

atoms___ContentHeading_-_Test_⋅_Storybook.png

導入手順

  • まずはyarnでimport

    yarn add -D @storybook/vue

  • pagkage.jsonにscriptを追記して楽にする

package.json(抜粋)
  "scripts": {
    "storybook": "start-storybook -p 9000 -s ./dist"
  },
  • storybook用のフォルダを作成
    mkdir .storybook
  • SCSSを効かせるためのファイルを作成 vim .storybook/Decorator.vue
storybook/Decorator.vue
<template>
  <div class="decoarator">
    <slot name="story"></slot>
  </div>
</template>

<script>
export default {
  name: 'Decorator'
}
</script>

<style lang="scss">
@import '@/styles/reset.scss';
</style>
  • viewport-addonを導入(SPサイズなどで検証するのに利用)
    yarn add -D @storybook/addon-viewport babel-preset-vue
  • actions-addonを導入(nuxt-linkの検査などに利用)
    yarn add -D @storybook/addon-actions
  • configファイルを作成
    vim .storybook/config.js
    • Decoratorの設定
    • @storybook/addon-viewportの設定
    • @storybook/addon-actionsの設定
storybook/config.js
import Vue from 'vue'
import { addDecorator, addParameters } from '@storybook/vue'
import Decorator from './Decorator.vue'
import { INITIAL_VIEWPORTS } from '@storybook/addon-viewport'
import { action } from '@storybook/addon-actions'

/* nuxt-linkをstorybook上で検査できるようにする */
Vue.component('nuxt-link', {
  props:   ['to'],
  methods: {
    log() {
      action('link target')(this.to)
    },
  },
  template: '<a href="#" @click.prevent="log()"><slot>NuxtLink</slot></a>',
})

/* 共通SCSSを呼び出す */
addDecorator(() => ({
  components: { Decorator },
  template: `
    <decorator>
      <story slot="story"/>
    </decorator>
  `
}))

/* ViewPortプラグインの初期設定 */
addParameters({
  viewport: {
    viewports: INITIAL_VIEWPORTS,
    defaultViewport: 'iphonex'
  }
})

  • main.jsを作成し、storiesファイルのパスを指定。
    vim .storybook/main.js
storybook/main.js
/*
 storybook fileの場所を正規表現で指定
 vueファイルとstories.jsファイルを同フォルダに配置する場合
 */
module.exports = {
  stories: ['../components/**/*.stories.[tj]s']
}
  • 利用するWeb fontがあれば、preview-head.htmlを作成
    vim .storybook/preview-head.html
storybook/preview-head.html
<!-- Adobe Fontsなど、フォントファイルをlink形式でstorybookに効かせたい場合は本ファイルを作成 -->
<link rel="stylesheet" href="https://use.typekit.net/hogehoge.css" />
  • アドオン適用のため、addons.jsを作成
    vim .storybook/addons.js
storybook/addons.js
import '@storybook/addon-viewport/register'
import '@storybook/addon-actions/register'
  • webpack.config.jsを作成
    vim .storybook/webpack.config.js
storybook/webpack.config.js
const path = require('path')

/* SCSSを利用できるようにloaderを設定
  (注意) nuxt側とは別で、改めてこちらのwebpack.configを設定する必要がある。
  */
module.exports = ({ config }) => {
  config.resolve.alias['@'] = path.resolve(__dirname, '../')
  config.resolve.alias['~'] = path.resolve(__dirname, '../')
  config.module.rules.push({
    test: /\.scss$/,
    loaders: [
      'style-loader',
      'css-loader',
      'sass-loader',
    ]
  })
  return config
}
  • テストのため、atomsにディレクトリを作成しファイルを配置
    • mkdir -p components/atoms/Title
components/atoms/Title/index.vue
<template>
  <div class="title">
    <slot />
  </div>
</template>

<style lang="scss" scoped>
.title {
  font-size: 40px;
  color: #000;
}
</style>
components/atoms/Title/index.stories.js
import StoryComponent from './index'

export default {
  title: 'atoms/Title'
}

export const normal = () => ({
  components: { StoryComponent },
  template: `<story-component>Title</story-component>`
})
  • storybookを起動する
    yarn run storybook

image.png

その他、必要に応じて導入する

  • Moment.js
    • yarn add moment
  • Lodash.js
    • yarn add lodash
  • その他プラグイン周りも必要に応じて導入する

  • GoogleAnalytics 参考:公式Doc

    • yarn add @nuxtjs/google-analytics
    • plugins/ga.jsを作成し、nuxt.config.jsに追記
plugins/ga.js
/* eslint-disable */

export default ({ app }) => {
  /*
  ** クライアントサイドかつプロダクションモードでのみ実行
  */
  if (process.env.NODE_ENV !== 'production') return
  /*
  ** Google アナリティクスのスクリプトをインクルード
  */
  (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
  (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
  m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
  })(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
  /*
  ** 現在のページをセット
  */
  ga('create', 'UA-XXXXXXXX-X', 'auto')
  /*
  ** ルートが変更されるたびに毎回実行(初期化も実行される)
  */
  app.router.afterEach((to, from) => {
    /*
    ** Google アナリティクスにページビューが追加されたことを伝える
    */
    ga('set', 'page', to.fullPath)
    ga('send', 'pageview')
  })
}
nuxt.config.js(抜粋)
  plugins: [
    { src: '~plugins/ga.js', mode: 'client' }
  ]
vengavengavnega
ProductOwner 兼 Engineer
mediful
2020年2月に立ち上がったメディカルテックスタートアップです。医療の様々な課題解決に挑戦し、医療現場を支え、社会の健全な活動に貢献するために日夜努力を続けています。
https://mediful.co.jp/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした