株式会社フォトラクション WEBチーム所属 ジョンです!
Photoruction Advent Calendar 2021の7日目の記事です。
Vueのシングル・ファイル・コンポーネントをSPAではないプロジェクトに使える方法を紹介したいと思います。
目次
フォトラクションでは、アプリケーションの改善を常に行っています。それの一つの計画としては今のアプリケーション内に古く書かれているBackbone.jsとjQueryを最もモダンなフレームワーク、Vue.jsに書き直すことです。
だが一つ問題があり、レガシーコードを書き直しながら新しい機能を増やすことも大事で私たちのリソースをコードの書き直しだけに無駄に使うのがふさわしくない。そのため、Backbone.jsやjQueryで書かれているコードにも新しい機能を追加することもよくあるのです。ソースコードをすべてVue.jsに書き直すついでにBackbone.jsやjQueryをこれ以上増やしたくないので、新しい機能もVueで開発したかったです。
なお、Vueにはいろいろ書き方があります。その一つはSFCを使わずに直接Vueのインスタンスを作ることです。もちろんこのような書き方にしても問題ないですが、VueのSFCのメリットを得られなくなる上に管理もしにくくなります。
<!DOCTYPE html> <html> <head> <title>俺のものすごいアプリ</title> </head> <body> <div> <!-- 既存コード --> </div> <div id="my-vue-component"> <other-component /> </div> <script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous" ></script> <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script> <script> $(document).ready(() => { ...既存コード }); Vue.component('other-component', { data() { ... }, template: '...' }); new Vue({ el: '#my-vue-component', template: '...', data() { ... }, methods; { ... } }); </script> </body> </html>
では、早速始めましょう!
前提条件
Node.js - npmからVueやwebpackなどをダウンロードするため、Vueのシングル・ファイル・コンポーネントはそのままJavaScriptに使うことができないため、コンパイルする必要があります。
シングル・ファイル・コンポーネント(Single-File Component)
<template> <button> <other-component /> <slot /> </button> </templaet> <script> import OtherComponent from './OtherComponent.vue'; export default { component: { OtherComponent }, data() { return { ... }; }, methods: { ... } }; </script> <style scoped> button { padding: 1rem 2rem; } </style>
Vueのシングル・ファイル・コンポーネントは基本的に.vue
という拡張子が付いています。この.vue
ファイルにはHTML、JavaScriptとCSSをまとめてバンドルすることができます。Vueでシングル・ページ・アプリケーション(SPA)を作ったことがある人には見慣れたコードになると思います。このファイルはSPAを作るときの.vue
ファイルと全く同じのため、他のコンポーネントやライブラリーをインポートすることはできますし、JavaScriptの代わりにTypeScriptを使うこともできますし、SASSなどを使うこともできます。
ローダーのスクリプト
先ほど作ったSFCを使えるために、ローダースクリプトを作ります。ローダースクリプトはVueコンポネントをアプリケーションにマウントさせるためのスクリプトになります。これがないとSFCを使用できません。
import Vue from "vue"; import MyComponent from "../components/MyComponent.vue"; const el = document.querySelector('#some-element'); new Vue(MyComponent).$mount(el);
VueでSPAを開発したことがある方は.vue
ファイルのようにこれも見慣れたコードになっていると思います。Vueのシングル・ページ・アプリケーションのindex.js
に書かれているものと同じです。ここで何をやっているのかというと、まずVueとプロジェクトに使いたいコンポーネントをインポートします。そして、new Vue(MyComponent)
で新しいVueのインスタンスを作り、コンポーネントをパラメータとして渡します。それから、.$mount(el)
でアプリケーション内の好きな場所にマウントします。
コンパイル
コンポーネントとローダースクリプトを完成したら、コンパイルする必要があります。コンパイルするためにはNode.jsが必要です。Node.jsはまだインストールしていない方には先にインストールしてください。Node.jsをインストールした後次へ進んでください。
Nodeで既に開発している場合
もしNodeですでに開発をしている場合はnpm
から必要なパッケージのみインストールしてください。自分のプロジェクトにすでにインストールされているパッケージはインストールしなくていいです。プロジェクトにインストール済みのパッケージはpackage.json
に確認できます。
まずは、vue
、vue-loader
とvue-template-compiler
をインストールします。
npm install -D vue vue-loader vue-template-compiler
次はwebpack
をインストールします。
npm install -D webpack webpack-cli
最後は.vue
の中にあるCSSなどのためのローダーをインストールします。
npm install -D @babel/core babel-loader css-loader vue-style-loader
今回はシンプルにしたいため、SASSなどを使わないですが、もしSASSが必要であればsass-loader
などをインストールする必要があります。
次は、webpack.config.js
を修正します。
webpack
が使われていないプロジェクトにはこのファイルが存在していない可能性あります。であれば、プロジェクトのroot
にwebpack.config.js
のファイルを作成してください。
const { dirname } = require("path"); const VueLoaderPlugin = require("vue-loader/lib/plugin"); module.exports = { entry: { "favorite-cat": "./vue/loaders/favoriteCatLoader.js", }, output: { filename: "bundle.js", path: __dirname, }, module: { rules: [ { test: /\.vue$/, loader: "vue-loader", }, { test: /\.js$/, loader: "babel-loader", }, { test: /\.css$/, use: ["vue-style-loader", "css-loader"], }, ], }, plugins: [ new VueLoaderPlugin(), ], };
webpack.config.js確認
webpack.config.js
はすでにあるプロジェクトには上記の内容が自分のwebpack
コンフィグに存在しているかどうか確認してください。module.exports
のmodule.rule
の順番が大事なので、webpack.config.js
を修正するときに注意をしてください。
新しいコンポーネントやローダースクリプトを追加するときに、module.exports
のentry
に追加しなければなりません。
module.exports = { entry: { "comp1": "./loaders/ComponentLoader1.js", "comp2": "./loaders/ComponentLoader2.js", "comp3": "./loaders/ComponentLoader3.js", }, ... }
プロジェクトのroot
にpackage.json
を開いて、下記を追加してください。
"scripts": { "build": "webpack --config webpack.config.js --mode development" },
プロジェクトに初めてNodeを使った場合にはwebpack.config.js
みたいにpackage.json
も存在していない可能性があります。その場合は、下記を実行し、プロジェクト情報を入力してください。
npm init
そのあとは上記のpackage.json
ファイルの編集を行ってください。
最後にはビルドをします。
npm run build
上記のコマンドを実行したら、プロジェクトのroot
にbundle.js
が生成されます。そのbundle.js
をHTMLの中にインクルードします。
<html> <body> ... <script src="bundle.js" defer></script> </body> </html>
そのあと、HTMLにコンポーネントのマウント先を作ります。
ロードスクリプトに#some-element
にコンポーネントをマウントしようとしているため、<div id="some-element"></div>
を追加すれば、Vueコンポーネントはこのdiv
の中にマウントされます。
まとめ
自分のプロジェクトはVueのシングル・ページ・アプリケーションではなくてもVueのシングル・ファイル・コンポーネントを使えます。上記でいろいろやりましたが結局3つのステップで済むことができます。
1. Vueコンポーネントを作成
2. ローダースクリプトを作成
3. ビルド
今までのスパゲッティコードを何とかしたいけど、今のプロジェクトをSPAに書き換えることができない人は是非やってみてください!
株式会社フォトラクションでは一緒に働く仲間を募集しています
corporate.photoruction.com
www.wantedly.com