「スマホでも使いやすいようにVeu.jsを導入、ついでにコンテナ化 その①」わたしのWebサービス開発日記 #13

スポンサーリンク
個人開発
スポンサーリンク

近況

タイトルを変更した。

元の「開発者の開発者による開発者のための記録」はなんか壮大すぎる。

「わたしのWebサービス開発日記」ぐらいがちょうどいいのかもということで変更した。

朝顔の観察日記ぐらいの感覚で読んでって意味を込めて。

このシリーズは久々の投稿になってしまったのは新しい機能を追加しようとしたけど、むずくて軽く挫折していたから。

別のアップデートをしようとしてその作業をしていた。(そのせいで時間がかかっていたのよね)

その作業が今回記事にする「veu.jsの導入」。(と「コンテナ化」)

Veu.jsの導入について

今回、Veu.jsを導入することにした理由は

「スマホだとこのWebサービス鬼のように使いにくいから」

「Veu.jsを知れる機会になるから」

見てくれ↓ひどいだろ?笑 画面いっぱいに広がる地図。画面をスワイプしようとすると地図移動をしてしまう...。

で、vue.jsならスマホでも見やすくなるみたいなのはちらっと聞いていたのと、僕のwebサービスで使っているleafletがveu.js対応できるvue-leafletなるものがあるとのことだったので、今回採用することにした。

ChatGPT先生

一応、ChatGPT先生にも相談してみたんだ。

私

元々Djangoで開発していたwebサービスをvue.jsを追加で使うことでモバイルフレンドリーにできる?

という問いに対して、ChatGPT先生の答えは以下。

はい、Djangoで開発されたウェブサービスにVue.jsを追加することで、モバイルフレンドリーなウェブアプリケーションを作成できます。以下は、DjangoとVue.jsを組み合わせてモバイルフレンドリーなアプリケーションを開発するための一般的な手順です:

フロントエンドの刷新: Vue.jsを使用して、Djangoテンプレートやフロントエンドを刷新します。Vue.jsを導入すると、SPAやリアクティブなUIなど、モバイルフレンドリーな機能を実現できます。

RESTful APIの設計: Djangoを使用してRESTful APIを設計し、バックエンドとフロントエンドの間でデータの双方向通信を実現します。Vue.jsはAPIを使用してデータを取得・送信できるため、リアルタイムでデータを同期することが可能です。

Vue.jsの統合: Vue.jsをDjangoテンプレートやHTMLファイルに組み込みます。通常、<script>セクションにVue.jsコンポーネントを定義し、Vue Routerを使用してページ遷移を管理します。

レスポンシブデザイン: モバイルフレンドリーなデザインを確保するために、CSSフレームワーク(例:Bootstrap、Vuetifyなど)を使用して、画面サイズに合わせたレスポンシブデザインを実装します。

モバイルプラットフォーム対応: CordovaやCapacitorなどのモバイルアプリケーションフレームワークを使用して、Vue.jsで開発したウェブアプリケーションをモバイルアプリに変換することも検討できます。

DjangoとVue.jsの組み合わせにより、バックエンドとフロントエンドの分離、リアクティブなユーザーインターフェース、効率的なデータ通信など、モバイルフレンドリーなアプリケーションを開発するための多くの機能を活用できます。ただし、プロジェクトの要件に応じて、適切なアーキテクチャとデザインを選択することが重要です。

ふーん、スマホで使いやすくなるんだ。

それともう一つ、vue-leafletを使うとスマホで見やすくなるかってところも気になる。

私

vue-leafletを使えばスマホからでもマップが操作しやすいモバイルフレンドリーなアプリケーションになる?

という問いに対して、ChatGPT先生の答えは以下。

はい、vue-leafletを使用すると、スマートフォンからでもマップを操作しやすいモバイルフレンドリーなアプリケーションを開発できます。vue-leafletはVue.jsとLeafletを統合したライブラリであり、マップ関連のコンポーネントをVue.jsのアプリケーションに簡単に組み込むことができます。以下は、vue-leafletを使用してモバイルフレンドリーなマップアプリを開発するための主な利点です:

レスポンシブデザイン: vue-leafletを使用すると、マップがスマートフォンの画面サイズに合わせて自動的に調整されるため、モバイルデバイスでも使いやすいユーザーインターフェースを提供できます。

タッチジェスチャー対応: スマートフォンやタブレットデバイスのタッチジェスチャーに対応しており、ユーザーがピンチ・ズームやスワイプなどのジェスチャーを使用してマップを操作できます。

カスタマイズ可能なUI: vue-leafletはカスタマイズ可能なコンポーネントとプロパティを提供し、マップの外観や機能をアプリケーションの要件に合わせて調整できます。

Leafletの機能を活用: vue-leafletはLeafletの強力な機能を利用できるため、カスタムマーカー、ポップアップ、ポリゴン、ラインストリングなどを簡単に追加できます。

Vue.jsとの統合: vue-leafletはVue.jsのコンポーネントとして提供されるため、Vue.jsアプリケーション内で直接マップコンポーネントを使用できます。

vue-leafletを使用すれば、モバイルフレンドリーなマップアプリケーションの開発が簡素化され、スマートフォンからでも使いやすいマップ体験を提供できます。ただし、デザインやユーザーエクスペリエンスにも注意を払うことが重要です。

悶々としていた

vueってcliで導入する意味ってあるのか?

さて、ある程度調べたら手を動かさないと理解できないところもあるので、実際に構築してく必要があるのだが、構築する上で一つ疑問に思うところがあった。

vueってcliで導入する意味ってあるのか?

ってこと。

調べるとvueってCLIとCDNの2種類があることが分かった。

CDN(Vue.js)はJavaScriptフレームワーク

CLI(VueCLI)はVue.jsで開発するためのツール群

話が脱線してしまったが、もともとこのWebサービスはDjangoで開発しているんだけど、これってDjangoで開発している環境に「cliで導入する意味ってあるのか?」という疑問が出てくる。

というのもDjangoはフルスタックなフレームワークなわけで、つまり、フロントエンドも含めて構築できるツールになる。

それに対してVue CLIをわざわざ導入する意味があるのかと思っていた。

最初はコストがあまりかからないし、CDNでいいんじゃないかと思っていた。

vue-leafletのCDNがうまくいかん

しかし、vue-leafletのCDNがどうもうまくいかなかった。

CLIの導入記事は幾つも見つかるのだけど、CDNでの実装が見つからずに結構悶絶した。

ここでハマるのなら、記事のあるCLIでの導入をする方がいいんじゃないかと思うようになっていた。

しかし、CLIで導入するなら実行をどうするのかが気になった。

nodeを実行した状態にしなければならない。

つまり、Vue CLIのプロセスとDjangoのプロセスの2つをバックグラウンド動かす必要がある。

DjangoはGunicornがあるけど、Vue CLIってどうなるんだ?

ツールが増える毎に運用が複雑になっていく。

そんなこともあり、コンテナ化をする必要を感じ始めた。

そんなこんなでコンテナ化することにした

ということで、コンテナ化も進める必要性があると判断し、コンテナ化にも踏み切ることにした。

今使おうとしているツールは

nginx, django, gunicorn, vue.js, mysql

となりそれなりに数はある。

これらをコードの払い出しであったり、エラーハンドリングしていくにも大変になっていく未来も想像できる。

実装

ということで、やっと手を動かしていく。

今回の実装でやらなければならないことをToDoリスト化する。

  • ◻️DjangoとVue.jsとの接続確認
  • ◻️Nginxのコンテナ化(フロントエンド)
  • ◻️Vue.jsのコンテナ化とVue.jsとNginxの接続(フロントエンド)
  • ◻️Djangoのコンテナ化(バックエンド)
  • ◻️mysqlのコンテナ化(バックエンド)
  • ◻️証明書の自動更新

なかなか重い内容…。

今回は一つ目の「DjangoとVue.jsとの接続確認」を進めていきたいと思う。

こちら👇のサイトなどを参考にしました。最初からやる人はこちら👇のサイトを参考にした方が良い。

Django REST FrameworkとVue.jsの環境構築 - Qiita
環境MacOS Monterey Version12.4Chip: Apple M1 Max使用技術Python 3.10DjangoDjango REST FrameworkVue.…

まずdjango側の設定から。

必要なものをインストールする。

$ pip3 install Django djangorestframework django-cors-headers

djangoの設定

project/settings.pyのINSTALLED_APPSにrest_frameworkを追加する。

INSTALLED_APPS = [
  ・・・略・・・
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'django.contrib.gis',
    'leaflet',
    'fontawesomefree',
    'rest_framework',
]

アプリの方のviews.pyに以下を追加。これは現在の時間を取得するように処理している。

from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status

class DateTimeView(APIView):
    def get(self, request):
        datetime_str = datetime.datetime.now().strftime('%Y%m%d_%H%M%S')
        return Response(datetime_str, status=status.HTTP_200_OK)

アプリの方のurls.pyに以下のハイライトの部分を追加。

from django.urls import path
from . import views
from app.views import SampleAPIView, DateTimeView

app_name = 'app'
urlpatterns = [
    ・・・略・・・
    path("datetime/", DateTimeView.as_view(), name="datetime"),
]

ちなみにproject側のurls.pyは以下のようになっている。

from django.contrib import admin
from django.urls import path, include
from . import views
from django.conf import settings
from django.conf.urls.static import static

urlpatterns = [
    path('app/', include('app.urls')),
    path('article/', include('article.urls'), name='article'),
]

vueの設定

vue CLIのインストール

$ npm install -g @vue/cli

新しいバージョンをインストール

$ nvm install v18.18.0

veuのプロジェクトを作成(→選択するモードに入るので選択)

$ vue create frontend

一番上のDefaultとnpmを選んだ
? Please pick a preset: Default ([Vue 3] babel, eslint)
? Pick the package manager to use when installing dependencies: NPM

作成されたディレクトリに移動して、サーバーを起動する。

$ cd frontend
$ npm run serve

これで、http://localhost:8080/にアクセスすると以下の画面が表示される。

ここで、もし、以下のようなエラーが出たらsettings.pyを修正する必要がある。

Invalid HTTP_HOST header: 'localhost:8000'. You may need to add 'localhost' to ALLOWED_HOSTS.

この場合プロジェクトのディレクトリ内にあるsettings.pyのALLOWED_HOSTSに以下のようにlocalhostを追加してあげる必要がある。

ALLOWED_HOSTS = ['127.0.0.1', 'localhost']

これ、127.0.0.1だけだとlocalhostで同様のエラーが発生するので注意ね。

Djangoとvueの接続を確認する

上記で表示したページはHelloWorld.vueというファイルの内容が表示されており、

HellowWorld.vueはsrc/componentsというディレクトリの中にあります。

このファイルを編集して、Djangoで取得した値をページに出力してみます。

axiosのインストール。(axiosはHTTP通信が簡単にできる、JavaScriptのライブラリ)

$ npm install axios

HellowWorld.vueを以下のように編集

<template>
  <div class="hello">
    <h1>{{ msg }}</h1>
    <!-- add -->
    <div>
      {{ text }}
    </div>
  </div>
</template>

<script>
// add
import axios from "axios";

export default {
  name: "HelloWorld",
  props: {
    msg: String
  },
  // add
  data() {
    return {
      text: null,
    };
  },
  mounted() {
    axios
      .get("/app/datetime/")
      .then((response) => (this.text = response.data))
      .catch((e) => console.log(e));
  },
};
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
h3 {
  margin: 40px 0 0;
}
ul {
  list-style-type: none;
  padding: 0;
}
li {
  display: inline-block;
  margin: 0 10px;
}
a {
  color: #42b983;
}
</style>

ここで注意は

      .get("/app/datetime/")

のところ。

ここはdjangoのurls.pyで上記で変更したところを基に書く。

この記事での実装ではprojectのurls.pyでappのpath、そのappのurls.pyでdatetimeのpathを指定してるため、/app/datetime/となる。

この「/app/datetime/」を「/app/datetime」とすると404エラーになるので注意。(細かいところなので意外と見つからずハマったりする。)

frontend/vue.config.jsファイルを以下のように編集。(★のついているところは設定しているあたいに応じて修正する。今回はappなのでapp)

const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({
  publicPath: "/",
  transpileDependencies: true,
  devServer: {
    host: "localhost",
    hot: "only",
    proxy: {
      "^/app": { //★設定している値に応じて修正
        target: "http://localhost:8000",
        changeOrigin: true,
      },
    },
  },
})

以上を設定したら、djangoとvue cliを起動して「http://localhost:8080/」にアクセスする。

### djangoの起動
$ python3 manage.py runserver

### vue cliの起動
$ npm run serve

アクセスしたら以下の画面が出ればOK。時刻が取得できているのが分かる。

これでDjangoとVue CLIの接続確認ができた。

今回はここまで

今回はここまでとする。

  • ✅DjangoとVue.jsとの接続確認

ができた。

次回は以下をしていこうと思う。

  • ◻️Nginxのコンテナ化(フロントエンド)
  • ◻️Vue.jsのコンテナ化とVue.jsとNginxの接続(フロントエンド)

その他、思うこと。

今年2023年の9月にGoogleが25周年を迎えていた。

25周年を迎えた日のGoogle検索の画面

まだ、25年ということに驚く。

今から25年前の1998年9月、Googleが設立された。

当時は創業者のセルゲイ・ブリンとラリー・ペイジは博士課程の研究で忙しくGoogleのプログラムを100万ドルで売ろうとしていた。

売ろうとしていた企業の中には現在は倒産しているエキサイト社も含まれる。

そしてその企業の中にはヤフーもあった。

しかし、ヤフーはこの買収を見送った。

そして、2002年、今度はヤフーから30億ドルでGoogleを買いたいと申し出があった。

Google側はその話を断った。

さらに2年後の2004年Googleの価値は1500億ドルになった。

参考:「成功はランダムにやってくる」

この25年間の軌跡を体験したブリンとペイジはとても幸せだっただろう。

お金が手に入るというより、その成長の景色を見れたことがうらやましい。

エキサイト社がGoogleを買っていたら同社は倒産しなかったかもしれない。

ヤフーがGoogleを買収していてたら検索エンジンの王者に君臨し続けられたかもしれない。

そして、Googleは今のような地位にならなかったかもしれない。

具体的な成功の法則というものはあるわけではなく、僕たちは今できる選択肢の中から成功の可能性があると考えられる選択肢を選んでいく必要がある。

今、開発しているWebサービスがどのような未来を辿るのかはわからない。

しかし、バタフライエフェクトという言葉もあるように、何かしら将来に影響を与えているのだろう。

それが成功であればいいのだが、今の僕にできることはそれを願って進んでいく事だけだから真剣にそれに取り組んでいこうと思う。

今回はここまで。ではまた。👋👋👋


僕も使っている、SakuraのVPSサーバー。この記事のサービスもこのVPSサーバーで動いています。👇

ドメインはこちらでも取得可能!👇

タイトルとURLをコピーしました