jackmiwamiwa devblog

フロントエンドをメインに行ったことをまとめていくサイトになります。

Nuxt.jsの初期設定~行なったこと

設定ミスやよく理解していない部分を把握するため、
再構築するときにやりやすくするようにいろいろと一応メモ

2019/06/27追記

jackswim3411.hatenablog.com

でNuxt.jsでのv2の設定についても随時追記していこうと思っていますので、よろしくお願いします。

Nuxtをすぐに始めるなら

$ vue init nuxt-community/starter-template nuxt-sample
$ cd nuxt-sample
$ npm i
$ npm run dev

nuxt-sampleはプロジェクト名 のあとに http://localhost:3000を開く 参考 : インストール - Nuxt.js

インストール時に聞かれることについて

? Project name (nuxt-sample)

プロジェクト名。(上で入力したもので大丈夫)

? Project description (Nuxt.js project)

プロジェクトの説明文。 (package.jsonのdescriptionに記載されるくらい。)

スクリーンショット 2018-12-14 15.26.24.png (47.3 kB)

? Author (ユーザー名)

↑のautherに名前が記載される。

Next.jsについて

Vue.jsについて

Vueと他のフレームワークとの比較

Nuxt.jsについていろいろ

今回の設定について

  • あくまでもSPAではない静的ページの作成(記事とかの変動のページはないつもり。)
  • htmlpug,cssscssを使っていく予定

ディレクトリについて

├ assets/        # Sassや画像など
├ components/    # コンポーネント
├ layouts/       # ヘッダーやフッターを含む共通のレイアウト
├ middleware/    # ページのレンダリング前に実行したい関数(認証など)
├ pages/         # 各ページを表すコンポーネント(このディレクトリをもとにルーティング)
├ plugins/       # プラグイン
├ static/        # assetsに含めたくない静的ファイル
├ store/         # Vuex
├ stories/       # storybookの設定ファイル
└ nuxt.config.js # Nuxt.jsの設定ファイル

参考 : ディレクトリ構造 - Nuxt.js

コードフォーマット

  • es-lint : コードのフォーマットやルール違反、構文エラーを自動でチェックしてくれるツール
  • prettier : コードのフォーマットを可能な限り自動で整形してくれるツール

es-lint を使ってコードの自動チェックを行うことで、構文的に問題のあるコードや、記述が好ましくないコードを事前に検出出来るほか、 prettier を使って 細かいフォーマットのエラーなどを自動で修正することができる

ES-LINT を用いたコード検査

デフォルトの内容 : .eslintrc.js

module.exports = {
  root: true,
  env: {
    browser: true,
    node: true
  },
  parserOptions: {
    parser: 'babel-eslint'
  },
  extends: [
    // https://github.com/vuejs/eslint-plugin-vue#priority-a-essential-error-prevention
    // consider switching to `plugin:vue/strongly-recommended` or `plugin:vue/recommended` for stricter rules.
    'plugin:vue/essential'
  ],
  // required to lint *.vue files
  plugins: [
    'vue'
  ],
  // add your custom rules here
  rules: {}
}

デフォルトでは - テンプレート内の v-xxx 系のディレクティブが正しく利用されているかのチェック - コンポーネントの data プロパティが関数で定義されているかのチェック - computedや data , methods間で キーの重複がないかのチェック

を行なっている

これらのコードチェックを行う場合には

$ npm run lint

これにより拡張子が.js .vue のファイルを対象にコードのチェックが自動的に行う。

チェックの結果見つかったエラーはターミナルに表示され、コマンドは終了コード 1 を返す。 エラーが見つからなかった場合は、何も表示されず、終了コードも 0 を返す。

PRETTIER によるコードの自動整形

prettier はコードの自動整形を行うツール。コード内での セミコロンの有無やインデントの統一などを行う。

prettier を利用するにはまず以下のコマンドで、モジュールをインストール

$ npm i -D eslint-plugin-prettier eslint-config-prettier 

.eslintrc.jsに以下を追記

extends: [
    'plugin:vue/essential',
    'plugin:prettier/recommended'
],

現状でnpm run lintを行うとエラーが出る。

packeage.jsonに以下を追記。

"prettier": "eslint --fix --ext .js,.vue --ignore-path .gitignore ."

この状態でnpm run prettierを行うといい感じに整形してくれる。 ↑を行なった状態でnpm run lintを行うとエラーが消えているはず。

headの宣言について(metaタグ系)

ファイルについて

  • nuxt.config.js
head: {
    titleTemplate: (titleChunk) => {
      return titleChunk ? titleChunk+' | 全体のタイトル' : '全体のタイトル';
    },
    meta: [
      { charset: 'utf-8' },
      { name: 'viewport', content: 'width=device-width, initial-scale=1' },
      { name: 'keywords', content: 'キーワード1, キーワード2'},
      { hid: 'description', name: 'description', content: 'ページの説明文'}
    ],
    link: [
      { rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }
    ]
  },
  • pages/index.vue
<script>
export default {
}

</script>
  • pages/about.vue
<script>
export default {
  data() {
    return {
      pagetitile: 'about',
      pagedescription: '説明文が入ります。。。'
    }
  },
  head () {
    return {
      title: `${this.pagetitile}のページですーーー`,
      meta: [
        { hid: 'description', name: 'description', content: this.pagedescription }
      ]
    }
  },
}

</script>

head内についてはとりあえず仮埋めなので、

  • titleタグ(ページごとに動的。)
  • descriptionタグ(ページごとに動的。)
  • charset(固定)
  • viewport(固定)
  • favicon(固定)

を設定。(後で必要なものがあれば追加を行う予定)

Titleタグについて

titleタグは Topページならtitle上では何も宣言しない

→この場合 Site Titleになる

Aboutページ(Topページ以外)は〇〇ページですなどを宣言する

→ この場合aboutページです。 - Site Titleとなる

共通タイトルの設定

  • nuxt.config.js
module.exports = {
    head: {
        title: 'nuxt-title'
        titleTemplate: '%s | Nuxt.app'
    }
}

この状態だと nuxt-title | Nuxt.appのようになる。
(ページごとに個別に設定を行なっていない前提。)

また、ユーザーごとにタイトルの変更を行いたい場合には

  • users/_id.vue
<script>
    export default {
        head() {
            return {
                title: this.user.id
            }
        }
    }
</script>

のように記載を行うことで

ユーザID | Nuxt.appのような感じになる。

スクリーンショット 2018-10-22 4.15.13.png (87.9 kB)

↑はnuxt.jsの本コードから作ったもの。

descriptionタグについて

基本的にPagesディレクトリ内での宣言を行う

headについてのメモ

  • Titleタグ,descriptionタグをPage内で宣言してしまうとgoogleアナリティクスが反応しなくなる??
  • また、動的にしたときのTitleタグなどはその時々で変更されてしまう?
    → これについては設定するのは自分なので、静的に設定すればよい??

参考url

NUXT.JS 入門 #7 – NUXT.JS と SEO 設定 – chatbox blog nuxtでtitleタグを動的に設定する · polidog lab++

imgについて

Webpack を通じて画像を関する方法は、static フォルダから画像を配信する方法に比べて、次のようなメリットがある。

  • Webpack の file-loader がファイル名に自動的にバージョンハッシュを付与し、ブラウザキャッシュによる更新漏れを防いでくれる。
  • Webpack の url-loader がファイルサイズの小さな画像ファイルに自動的にbase64処理を実施し、テンプレートへの埋め込みを実施してくれる。

FILE-LOADERによるバージョンハッシュ

Webpack の管理する画像URLは実際に記述したURLとは若干異なり、ファイル名の末尾にバージョンハッシュが付与されたものになる
→ これは、同一のファイル名で画像の中身を更新した際に、画像の中身がブラウザキャッシュの影響で正常に更新されない問題を解決するために必要で、運用上非常に便利
staticフォルダから配信される画像ファイルは、記述したままのURLでファイルが配信されるため、画像の内容を更新した際に古いブラウザキャッシュが影響して上手く更新が出来ないケースがある

URL-LOADER による BASE64 処理

Webpack の管理する画像が 1kB未満のファイル容量だった場合、そのファイルは base64 エンコードされてテンプレート内にインライン化される。

小さな画像の取り込みで沢山のリクエストが発生するのを防ぎたいときなどに便利。

WEBPACKで取り扱えない画像ファイル

Webpack経由での画像配信は便利だが、全てのケースで対応できるわけではない。

  • link タグ経由で読み込まれる Nuxt管理外の CSS 内での url(...) では、Webpack を利用することができない。
  • 動的に生成されるURLでは、Webpack がビルド時に画像のURLを特定できないため、Webpack の機能を利用する事ができない。

動的に生成されるurlの例

<div v-for="user in users">
  <img src="`/images/${user.avatarPath}`"/>
</div>

cssの読み込みについて

API: css プロパティ - Nuxt.js

コンポーネント内での読み込み

.vue ファイルの style タグにscopedを付加させることでコンポーネント内に特殊な属性が付与され、style 内に記述したCSSコンポーネント内でのみ有効なCSSとなる。

npm 経由でインストールしたモジュールを参照

css のセクションでは scss や css ファイルを参照する他、npm 経由でインストールしたモジュールを参照することも可能

bulma の利用例

module.export = {
  css:[
    "bulma"
  ],
}

bootstrap の利用例

module.export = {
  css:[
    "bootstrap/scss/bootstrap.scss"
  ],
}

font-awesome読み込み

cdnを読み込む

参考

Font-awesomeについてnuxt.config.js内で読み込みを行う

  • nuxt.config.js
head: {
    link: [
      { rel: 'stylesheet', href:'https://use.fontawesome.com/releases/v5.0.6/css/all.css' }
    ]
  },

storybookでfontawesomeを読み込む

.storybook/prevoew-head.htmlを作り、

<link href="https://use.fontawesome.com/releases/v5.0.6/css/all.css" rel="stylesheet">

を記載する。

参考

全体的なscssファイルの読み込み

初期に読み込みを行うものについて

  • base.scss

初期の設定について記載し、読み込むためのファイル。
ディレクトリはbaseの中に入れる

変数の宣言を行うものについて

  • style.scss

Scssの変数をvueの中で読み込みを行うためのファイル。
ディレクトリはstyleの中に入れる

変数をvueファイルで読み込むためにやること

初期とは同じような感じできないため、nuxt-sass-resources-loaderのインストールを行う。

  • nuxt-sass-resources-loaderのインストール

nuxt-sass-resources-loader - npm

読み込みについて

  • nuxt.config.js
css: [
  '@fortawesome/fontawesome-free-webfonts',
  '@fortawesome/fontawesome-free-webfonts/css/fa-brands.css',
  '@fortawesome/fontawesome-free-webfonts/css/fa-regular.css',
  '@fortawesome/fontawesome-free-webfonts/css/fa-solid.css',
  '~/assets/scss/base.scss'
],
modules: [
  ['nuxt-sass-resources-loader', [
    '@/assets/scss/style.scss'
  ]],
],

googleアナリティクスを使う

参考 : Google アナリティクスの統合 - Nuxt.js

storybookの設定

インストール & ファイルの作成

$ npm i -S @storybook/vue
$ mkdir .storybook stories
$ touch .storybook/config.js stories/index.js

ファイルの内容について

  • .storybook/config.js
import { configure } from '@storybook/vue'

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

const loadStories = () => {
  require("../stories/index")
}

configure(loadStories, module)

stories/index.jsについては、各コンポーネントの内容を読み込む感じで行う 既存の内容

  • stories/index.js
import Vue from 'vue';

import { storiesOf } from '@storybook/vue';

//Atoms
import '../components/Atoms/AppLogo/index.stories'
import '../components/Atoms/H1Title/index.stories'
import '../components/Atoms/H2Title/index.stories'

//Molecules

//Organisms
import '../components/Organisms/GlobalHeader/index.stories'
import '../components/Organisms/GlobalFooter/index.stories'

任意のディレクトリに index.stories.jsの名前でそれぞれの内容を読み込むイメージ

  • AppLogo/index.stories.js
import Vue from 'vue';

import { storiesOf } from '@storybook/vue'

import AppLogo from './index.vue'

storiesOf('Atoms', module)
// .add('story as a template', () => '<message></message>')
  .add('AppLogo', () => ({
    components: { AppLogo },
    template: '<AppLogo></AppLogo>'
  }))

環境変数の設定について

Nuxt.js で dotenv を活用する – chatbox blog

webstormなど Webpack に対応した IDE~@エイリアスを対応させる

プロジェクト直下にwebpack.config.jsを仮入れとして作成。

  • webpack.config.js
// this is dummy webpack config for webstorm

const path = require('path')

module.exports = {
  resolve: {
    extensions: ['.js', '.json', '.vue', '.ts'],
    root: path.resolve(__dirname),
    alias: {
      '@': path.resolve(__dirname),
      '~': path.resolve(__dirname),
    },
  },
}

commitとかはさせる必要なし??

window または document が undefined になるとき

vue-slickなどのSSRを考慮していないものを入れると起こる。

スクリーンショット 2018-11-12 14.13.05.png (115.2 kB) こんな感じの画面になる。

対処法としてif (process.browser)の判定を挟むとエラーを修正することができる。

参考

inview的なやつ(observe-visibility)を入れる

Nuxt.js上で要素が出現したら何かが起こるようにしたい。。。

手順

vue-observe-visibilityをインストール

plugins/observe-visibility.jsを作って以下を記載

  • plugins/observe-visibility.js
import Vue from "vue";
import VueObserveVisibility from "vue-observe-visibility";

Vue.use(VueObserveVisibility);

nuxt.config.jsに上のものが通るようにする

  • nuxt.config.js
   plugins: [
    "~plugins/observe-visibility"
   ]

使いたいファイルに以下のように記載すればok

<template lang="pug">
      section.topMessage(v-observe-visibility="visibilityChanged" :class="{active: isVisible}")
</template>
<script>
 export default {
   data() {
    return {
      isVisible: true
    };
   },
  methods: {
    visibilityChanged(isVisible, entry) {
      this.isVisible = isVisible;
      console.log(this.isVisible);
    }
   }
 };
</script>

この場合、要素内に入るとactiveというクラスが付加させる。

参考

safariとかも対応させる

observe-visibility.jsはsafariとかでは動かないので、polyfillを読み込む (もっといい方法があると思うけどとりあえず。。。) - nuxt.config.js

script: [
  {
    charset: "utf-8",
    src:
      "https://cdn.polyfill.io/v2/polyfill.min.js?features=IntersectionObserver,IntersectionObserverEntry"
  }
]

参考 : https://github.com/Akryum/vue-observe-visibility/issues/26

store内のテキストを改行

  • store/index.js
import Vuex from "vuex";

const store = () =>
  new Vuex.Store({
    state: {
      people: [
        {
          id: 1,
          comment: "組込み開発の最新分野で、\n世界で求められる技術者として成長を"
        }
      ]
    }
  });
export default store;
  • 使う場所のファイル
<template lang="pug">
    h4(v-html="person.comment.replace(/\\n/g,'<br/>')")
</template>

参考 : https://qiita.com/huigo/items/0efcf50c17b0b1ee27cb

ビルド後のディレクトリ移動

基本だと ページのurl なので、ページのurl/recruitに表示されるようにする。

nuxt.config.jsにビルド後のディレクトリを記載

今回は下層のrecruitにいれたいので、以下のように設定。

  • nuxt.config.js
generate: {
  dir: "dist/recruit"
}

絶対値の場所を recruitにする

nuxtファイルの読み込みが絶対値で行われていたので、それに対応することができるように、、 あんまり使いたくないけどスピード重視でやったので、、、

  • nuxt.config.js
router: {
    base: "/recruit/"
}

注意。。

baseタグが埋め込まれるので、ページ内リンクとかがほぼ死ぬ。

jqueryのslideToggleみたいなことをやりたい

slideToggleとは

使うもの

https://github.com/danieldiekmeier/vue-slide-up-down

See the Pen Vue slideToggle by miwa_shuntaro (@miwashutaro0611) on CodePen.

nuxtに入れる

参考 : https://github.com/NightCatSama/vue-slider-component/issues/75

$ npm i -D vue-slide-up-down
  • nuxt.config.js
plugins: [
    {src: "@/plugins/slide-up-down", ssr: false}
]
  • /plugins/slide-up-down.js
import Vue from 'vue'
import SlideUpDown from 'vue-slide-up-down'
Vue.component('slide-up-down', SlideUpDown)
  • 使う場所.vue
slide-up-down(:active="active" :duration="300")
    p 内容