vue.jsを使ってECサイトの構築を行ってみたいといった時に参考になりそうなオープンソースプロジェクトVue Storefrontがあることを知ったのでインストールと簡単な動作確認を行ってみたいと思います。

Vue Storefrontをカスタマイズするためには、vue.jsだけではなくVue Router, Vue Storeの知識が必須となります。

Vue Storefrontとは

Vue Storefontはvue.jsで記述され、PWA(Progressive Web Apps)のECサイトを構築することができます。フロントエンド側をVue Storefontで構築し、バックエンドはMagentoやWooCommerceなど海外で人気の高いeCommerceのプラットフォームと連携することができます。

バックエンドにはサードパーティの連携方法も準備されているようです。本文書を執筆時点ではバックエンドとの連携の動作確認はサードパーティに限らずeCommerceプラットフォームとの連携も行っていません。

モバイルファーストなども特徴としており、パフォーマンスにかなり力を入れているようです。WordPressのようにテーマを使ってユーザが閲覧するページを自由にカスタマイズすることが可能です。

バックエンドのサーバやプラットフォームがなくても動作確認用のデータが取得できるhttps://demo.vuestorefront.ioをインストール中に選択することができるため動作確認を行うことが可能です。

インストール

Vue Storefrontをインストールするためには、yarnが必要となります。インストールされていない場合はインストールを行ってください。Homebrewを利用している場合は、brew installコマンドでインストールを行います。


 $ brew install yarn

gitコマンドを利用してgitにあるリポジトリをダウンロードします。


 $ git clone https://github.com/DivanteLtd/vue-storefront.git vue-storefront

プロジェクトディレクトリのvue-storefontに移動してyarnコマンドを実行します。yarnの実行には時間がかかります。


 $ cd vue-storefront/
 $ yarn

次にyarn installerを実行しますが、バックエンドにhttps://demo.vuestorefront.ioを利用するか聞かれるので動作確認のためYを選択します。イメージのエンドポイントのパスについて聞かれますが、そのままEnterを押してください。


$ yarn installer
yarn run v1.22.4
$ node ./core/scripts/installer
┌─────────────────────────────────────────────────┐
│ Hi, welcome to the vue-storefront installation. │
│ Let's configure it together :)                  │
└─────────────────────────────────────────────────┘

? Would you like to use https://demo.vuestorefront.io as the backend? (Y/n) Y
? Please provide path for images endpoint https://demo.vuestorefront.io/img/

実行後にCongratulations!が表示されたらインストールは完了です。


┌──────────────────────────────────────────────────────┐
│ Congratulations!                                     │
│                                                      │
│ You've just successfully installed vue-storefront.   │
│ All required servers are running in background       │
│                                                      │
│ Storefront: http://localhost:3000                    │
│ Backend: https://demo.vuestorefront.io               │
│                                                      │
│ Logs: /Users/reffect/Desktop/vue-storefront/var/log/ │
│                                                      │
│ Good Luck!                                           │
└──────────────────────────────────────────────────────┘
yarn installerでnodeプロセスが起動したままになるので停止したい場合はkillなどで停止してください。停止しない場合に再度yarn devを実行して開発サーバを起動すると複数のnodeが起動、ポートも重複しないように3000ではなく3001になります。その場合はどちらのポートでもアクセスが可能です。

ブラウザでメッセージに表示されているhttp://localhost:3000にアクセスを行います。下記の画面が表示されたらVue Storefrontは正常に動作しています。

トップ画面を表示
トップ画面を表示

起動方法

動作確認を行うためyarn devコマンドで起動することができます。


 $ yarn dev
  ・
----------------------------------------------------------
|                                                        |
| Vue Storefront Server started at http://localhost:3000 |
|                                                        |
----------------------------------------------------------
  ・
Compiled successfully.

開発サーバへの接続ポート情報は起動中のメッセージログの中盤に表示されます。

Vue Storefrontの構成要素

Vue Storefrontは以下の3つの要素から構成されています。

  • Vue Storefront Core
  • Vue Storefront Modules
  • Vue Storefront Themes 

Vue Storefront Core

プロジェクトフォルダの中にある/coreに保存されているコアコードで、Vue Storefrontを動作させる上で必須となる機能がすべてここに保存されています。通常Vue Storefrontを利用してサイトを構築する開発者(以下サイト開発者)がこのフォルダ内のファイルを更新することはなく、ここに保存されているコンポーネント等を利用してサイト構築を行います。もし一からECサイトを構築したい場合はコアコードをすべて自分で作成する必要があります。

Vue Storefrontそのものを開発する開発者とVue Storefrontを利用してECサイトを構築する開発者は異なります。Vue Storefront Coreのコードを更新できるのはVue Storefrontを開発する開発者です。

Vue Storefront Modules

プロジェクトフォルダの/core/modules, /src/modulesに保存されているモジュールコードで一つ一つのモジュールは独立しているため個別のモジュールを利用するかどうかはサイト開発者が選択することができます。またコアコードとは異なり、新たなモジュールを追加することもできます。

Vue Storefront Themes

プロジェクトフォルダの/src/themesに保存されているコードでサイト開発者が追加、更新、削除を行うのがこの部分です。ここに保存されているファイルからコアコードやモジュールコードを利用します。サイト開発者はコアコードの更新は行いませんが/src/themesのファイルを更新するためにはコアコードがどのような処理を行うのかを理解しておく必要があります。HTMLやCSS、UIの動きをつけるためのコードを記述していきます。

日本語化設定

海外のオープンソースを利用する場合は日本語化がどうなっているのか気になる人も多いかと思います。まずは日本語化の設定について確認を行います。

デフォルトでは英語が使われているので日本語に設定変更を行います。多言語対応は、vue-i18nライブラリが使われています。

設定はconfigディレクトリにあるlocal.jsonファイルのi18nを変更します。


"i18n": {
  "defaultCountry": "JP",
  "defaultLanguage": "JP",
  "availableLocale": [
    "ja-JP"
  ],
  "defaultLocale": "ja-JP",
  "currencyCode": "円",
  "currencySign": "¥",
  "priceFormat": "{sign}{amount}",
  "dateFormat": "YYYY/M/D HH:mm ",
  "fullCountryName": "Japan",
  "fullLanguageName": "Japanese",
  "bundleAllStoreviewLanguages": false
},
configディレクトリにはdefault.jsonがありますがこちらはデフォルト値が設定されているため直接の変更は行いません。local.jsonを変更するとlocal.jsonで設定した値がdefault.jsonの値に上書きされ反映されるためlocal.jsonの更新を行います。

local.jsonファイルを更新してもデフォルトでは即座に反映されるわけではないので一度yarn devを停止し、再度yarn devを実行してください。

公式マニュアルによるとlocal.jsonファイルのconfig.server.dynamicConfigReloadをtrueに設定すると自動で変更を適用することができるようです。
デフォルトのログイン画面
デフォルトのログイン画面

設定変更後にはログイン画面も日本語になっていることが確認できます。

日本語のログイン画面
日本語のログイン画面
すべての文章が日本語になっているわけではなく一部は日本語化の設定後も英語のものもあるので対応が必要そうです。

テーマを作成

ブラウザに表示される画面はテーマを使って変更を行っています。デフォルトのテーマは、src¥themes¥defaultの中に保存されています。このdefaultフォルダを複製して名前を変更することで新しいテーマを作成し更新を行っていきます。

複製して任意の名前を付けたあとはlocal.jsonファイルのthemeプロパティを変更する必要があります。

ここでは複製した名前をecに変更したのでthemeプロパティは以下のように変更しました。


"theme": "@vue-storefront/theme-ec",

yarn devを再起動して、ecフォルダにあるApp.vueファイルのrouter-viewタグをコメントアウトしてテーマの変更が反映されているか確認します。


<template>
  <div id="app">
    <component :is="layout">
      <router-view /> //コメントアウトする
    </component>
  </div>
</template>

トップページにアクセスを行い、下記のようにヘッダーとフッターのみ残っていたらテーマの変更が行われています。

テーマの変更が反映されている
テーマの変更が反映されている

テーマ内のファイルApp.vueファイルを変更するとブラウザに表示される内容が変わることも同時に理解することができました。

App.vueファイルの中身

Vue Routerの知識があればApp.vueファイルで行われていることが理解できるのでApp.vueファイルを確認してみましょう。


<template>
  <div id="app">
    <component :is="layout">
      <router-view />
    </component>
  </div>
</template>

<script>
import { mapState } from "vuex";
const DefaultLayout = () =>
  import(/* webpackChunkName: "vsf-layout-default" */ "./layouts/Default");
const EmptyLayout = () =>
  import(/* webpackChunkName: "vsf-layout-empty" */ "./layouts/Empty");
const MinimalLayout = () =>
  import(/* webpackChunkName: "vsf-layout-minimal" */ "./layouts/Minimal");

export default {
  data() {
    return {
      ordersData: []
    };
  },
  computed: {
    ...mapState({
      overlayActive: state => state.ui.overlay
    }),
    layout() {
      return `${this.$route.meta.layout || "default"}-layout`;
    }
  },
  components: {
    DefaultLayout,
    EmptyLayout,
    MinimalLayout
  }
};
</script>

App.vueのcomponentタグを見るとvue.jsのcomputedプロパティのlayoutの値によってブラウザに表示されるレイアウトが変わることがわかります。

layoutの中ではmeta.layoutの値によって利用されるコンポーネントファイルがわかることがわかります。


    layout() {
      return `${this.$route.meta.layout || "default"}-layout`;
    }

meta.layoutを確認するためルーティングファイルの¥src¥ec¥router¥index.jsファイルを開きます。中身を確認するとmetaのlayoutを持っているパスは/errorのみです。


{ name: 'error', path: '/error', component: ErrorPage, meta: { layout: 'minimal' } },

再度computedプロパティのlayoutを見ると/errorにアクセスがあった場合はminimal-layoutが表示され、それ以外のパスに接続があった場合はすべてdefault-layoutが利用されることがわかります。

利用されていないempty-layoutというものも存在しますが、これはdefaultとminimal以外のレイアウトを作成したい場合に利用できるテンプレートではないかと思われます。またmapStateでoverlayActiveプロパティがありますが、これは画面のoverlayを制御するために利用する値のようですが、このApp.vueファイルの中では利用されていないようです。

ルーティングファイルindex.jsの確認

ルーティングファイルのindex.jsの中身を確認するとVue Storefrontのdefaultのテーマがどのようなパスを利用し、そのパスに対してどのコンポーネントを利用しているか確認することができます。


const Home = () => import(/* webpackChunkName: "vsf-home" */ 'theme/pages/Home.vue')
const PageNotFound = () => import(/* webpackChunkName: "vsf-not-found" */ 'theme/pages/PageNotFound.vue')
const ErrorPage = () => import(/* webpackChunkName: "vsf-error" */ 'theme/pages/Error.vue')
const Product = () => import(/* webpackChunkName: "vsf-product" */ 'theme/pages/Product.vue')
const Category = () => import(/* webpackChunkName: "vsf-category" */ 'theme/pages/Category.vue')
const CmsPage = () => import(/* webpackChunkName: "vsf-cms" */ 'theme/pages/CmsPage.vue')
const Checkout = () => import(/* webpackChunkName: "vsf-checkout" */ 'theme/pages/Checkout.vue')
const Compare = () => import(/* webpackChunkName: "vsf-compare" */ 'theme/pages/Compare.vue')
const MyAccount = () => import(/* webpackChunkName: "vsf-my-account" */ 'theme/pages/MyAccount.vue')
const Static = () => import(/* webpackChunkName: "vsf-static" */ 'theme/pages/Static.vue')

let routes = [
  { name: 'home', path: '/', component: Home, alias: '/pwa.html' },
  { name: 'checkout', path: '/checkout', component: Checkout },
  { name: 'legal', path: '/legal', component: Static, props: {page: 'lorem', title: 'Legal Notice'}, meta: {title: 'Legal Notice', description: 'Legal Notice - example of description usage'} },
  { name: 'privacy', path: '/privacy', component: Static, props: {page: 'lorem', title: 'Privacy'} },
 ・
//略
  { name: 'cms-page', path: '/i/:slug', component: CmsPage },
  { name: 'page-not-found', path: '*', component: PageNotFound }
]

export default routes

ルーティングのパスは複数ありますがコンポーネントを再利用しているので利用するコンポーネントは10個であることもわかります。

テーマの更新を行うためにはレイアウトとページコンポーネントに記述されているコードを理解する必要があります。次回はそのほかのテーマ内のファイルについて確認を行っていきます。