Featured image of post 【ホストマシンを汚さずに】docker-composeでvue.jsプロジェクトの開発環境を構築する方法【Vue-CLI】

【ホストマシンを汚さずに】docker-composeでvue.jsプロジェクトの開発環境を構築する方法【Vue-CLI】

2853文字

Vue-CLI+Quasar+Pugで静的サイトを作ってみる

フロントの技術はめまぐるしい変化を遂げてますが、最近はVue.jsに落ち着いた感が出てきている気がします。

The Progressive JavaScript Framework なぜ VUE.JS ? はじめる Vue.js

そこで、今回はVue.jsを使ったプロジェクトを作成するところまでを試してみようと思います♪

手順

Dockerfileの作成

まずは入れ物となるDockerfileを作成しましょう。

Dockerfile
FROM node:12.16.1
WORKDIR /usr/src/app
RUN yarn global add @vue/cli

vue-cliさえ使えれば良いのでここでは特にモジュールは入れない事とします。

docker-compose.ymlの作成

次にdocker-compose.ymlを作成しましょう。

docker-compose.yml
version: '3'
services:
  app:
    build: .
    container_name: portfolio-vue
    ports:
      - "10080:10080"
    volumes:
      - .:/usr/src/app
    working_dir: /usr/src/app
    stdin_open: true
    tty: true

イメージのBuild

では、一旦ここまでの設定でDockerイメージをビルドしてみましょう。

docker-compose build
Building app
Step 1/3 : FROM node:12.16.1
12.16.1: Pulling from library/node
Digest: sha256:46f4c17e1edbde36d60a9f6362db7912cfe301bac89afef7cc92421ab3e7ca18
Status: Downloaded newer image for node:12.16.1
 ---> 88c089733a3b
Step 2/3 : WORKDIR /usr/src/app
 ---> Using cache
 ---> 311e9471c5a2
Step 3/3 : RUN yarn global add @vue/cli
 ---> Running in 446ee64187cb
yarn global v1.22.0
[1/4] Resolving packages...
mkdirp 1.x. (Note that the API surface has changed to use Promises in 1.x.)
[2/4] Fetching packages...
info fsevents@1.2.12: The platform "linux" is incompatible with this module.
info "fsevents@1.2.12" is an optional dependency and failed compatibility check. Excluding it from installation.
[3/4] Linking dependencies...
[4/4] Building fresh packages...
success Installed "@vue/cli@4.3.1" with binaries:
      - vue
Done in 175.56s.
Successfully built 311e9471c5a2
Successfully tagged portfolio-vue_app:latest

ビルドが成功したのでコンテナを起動してみます。

docker-compose up -d
Creating network "portfolio-vue_default" with the default driver
Creating portfolio-vue ... done

正常にコンテナが起動しましたね♪

コンテナ内の作業

では、次はコンテナに入ってプロジェクトを整えていきましょう。

docker-compose exec app /bin/bashでコンテナの中に入りましょう。

Vue-CLIでプロジェクトを作成

まずはVue-CLIを使ってプロジェクトの雛壇を作成しましょう。

設定はよしなに選んでください。

vue create <プロジェクト>
?  Your connection to the default yarn registry seems to be slow.
   Use https://registry.npm.taobao.org for faster installation? Yes


Vue CLI v4.3.1
? Please pick a preset: Manually select features
? Check the features needed for your project: Babel, TS, PWA, CSS Pre-processors, Linter
? Use class-style component syntax? Yes
? Use Babel alongside TypeScript (required for modern mode, auto-detected polyfills, transpiling JSX)? Yes
? Pick a CSS pre-processor (PostCSS, Autoprefixer and CSS Modules are supported by default): Stylus
? Pick a linter / formatter config: Basic
? Pick additional lint features: Lint on save
? Where do you prefer placing config for Babel, ESLint, etc.? In dedicated config files
? Save this as a preset for future projects? No
? Pick the package manager to use when installing dependencies: Yarn


Vue CLI v4.3.1
✨  Creating project in /usr/src/app/vue.
⚙️  Installing CLI plugins. This might take a while...

yarn install v1.22.0
info No lockfile found.
[1/4] Resolving packages...
[2/4] Fetching packages...
info fsevents@1.2.12: The platform "linux" is incompatible with this module.
info "fsevents@1.2.12" is an optional dependency and failed compatibility check. Excluding it from installation.
info fsevents@2.1.2: The platform "linux" is incompatible with this module.
info "fsevents@2.1.2" is an optional dependency and failed compatibility check. Excluding it from installation.
[3/4] Linking dependencies...
[4/4] Building fresh packages...
success Saved lockfile.
info To upgrade, run the following command:
$ curl --compressed -o- -L https://yarnpkg.com/install.sh | bash
Done in 176.63s.
🚀  Invoking generators...
📦  Installing additional dependencies...

yarn install v1.22.0
[1/4] Resolving packages...
[2/4] Fetching packages...
info fsevents@1.2.12: The platform "linux" is incompatible with this module.
info "fsevents@1.2.12" is an optional dependency and failed compatibility check. Excluding it from installation.
info fsevents@2.1.2: The platform "linux" is incompatible with this module.
info "fsevents@2.1.2" is an optional dependency and failed compatibility check. Excluding it from installation.
[3/4] Linking dependencies...
[4/4] Building fresh packages...
success Saved lockfile.
Done in 107.25s.
⚓  Running completion hooks...

📄  Generating README.md...

🎉  Successfully created project vue.
👉  Get started with the following commands:

 $ cd vue
 $ yarn serve

動作確認

これでプロジェクトの雛壇は出来たので動作確認をしてみましょう。

作成したディレクトリに移動して、以下のコマンドで開発用サーバーを起動してください。

yarn serve
yarn run v1.22.0
$ vue-cli-service serve
 INFO  Starting development server...
Starting type checking service...
Using 1 worker with 2048MB memory limit
98% after emitting CopyPlugin

 DONE  Compiled successfully in 18762ms                                                                                                                                                                                             1:05:15 PM

No type errors found
Version: typescript 3.8.3
Time: 6811ms

  App running at:
  - Local:   http://localhost:8080/

  It seems you are running Vue CLI inside a container.
  Access the dev server via http://localhost:<your container's external mapped port>/

  Note that the development build is not optimized.
  To create a production build, run yarn build.

無事に起動しました。

CLIで生成されたディレクトリは以下の通りです。

tree -L 3
.
├── Dockerfile
├── README.md
├── docker-compose.yml
└── {作成プロジェクト}
    ├── README.md
    ├── babel.config.js
    ├── node_modules
    │   └── 略
    ├── package.json
    ├── public
    │   ├── img
    │   ├── index.html
    │   └── robots.txt
    ├── src
    │   ├── App.vue
    │   ├── assets
    │   ├── components
    │   ├── data
    │   ├── favicon.ico
    │   ├── main.ts
    │   ├── quasar.js
    │   ├── registerServiceWorker.ts
    │   ├── shims-tsx.d.ts
    │   ├── shims-vue.d.ts
    │   └── styles
    ├── tsconfig.json
    └── yarn.lock

が、ポート番号が8080となっており、docker-compose.ymlで開けたポートとズレちゃってますねorz

vue.config.jsで開発サーバーのポート番号を変更

vueプロジェクトの開発サーバーのポートはvue.config.jsを作成して設定を追加する事で変える事が出来ます。

[adsense-responsive]

vue.config.js
module.exports = {
    devServer: {
      port: 10080,
      host: '0.0.0.0',
      disableHostCheck: true,
    },
  };

確認

上記ファイルを作成したら再度起動してみてください。

yarn serve
yarn run v1.22.0
$ vue-cli-service serve
 INFO  Starting development server...
Starting type checking service...
Using 1 worker with 2048MB memory limit
98% after emitting CopyPlugin

 DONE  Compiled successfully in 10038ms                                                                                                                                                                                             1:09:11 PM

No type errors found
Version: typescript 3.8.3
Time: 8633ms

  App running at:
  - Local:   http://localhost:10080/

  It seems you are running Vue CLI inside a container.
  Access the dev server via http://localhost:<your container's external mapped port>/

  Note that the development build is not optimized.
  To create a production build, run yarn build.

起動ログも無事にポートが10080に変わっていますね!

ブラウザからlocalhost:18080/ にアクセスする事で正常に表示もされました♪

Quasarをインストール

次にVue.jsのデザインフレームワークのQuasarを追加しましょう。

関連記事 【Vue.jsのUIフレームワーク】Electronアプリのデザインフレームワークに「Quasar」をインストール・導入する方法 2019/09/08 2008文字 約5分で読めます

vue add quasar
📦  Installing vue-cli-plugin-quasar...

yarn add v1.22.0
[1/4] Resolving packages...
[2/4] Fetching packages...
info fsevents@1.2.12: The platform "linux" is incompatible with this module.
info "fsevents@1.2.12" is an optional dependency and failed compatibility check. Excluding it from installation.
info fsevents@2.1.2: The platform "linux" is incompatible with this module.
info "fsevents@2.1.2" is an optional dependency and failed compatibility check. Excluding it from installation.
[3/4] Linking dependencies...
[4/4] Building fresh packages...
success Saved lockfile.
success Saved 1 new dependency.
info Direct dependencies
└─ vue-cli-plugin-quasar@2.0.0
info All dependencies
└─ vue-cli-plugin-quasar@2.0.0
Done in 94.88s.
✔  Successfully installed plugin: vue-cli-plugin-quasar

? Allow Quasar to replace App.vue, About.vue, Home.vue and (if available) router.js? Yes
? Pick a Quasar components & directives import strategy: (can be changed later) Auto import (kebab-case)
? Pick your favorite CSS preprocessor: Stylus
? Choose Quasar Icon Set Material
? Default Quasar language pack - one from https://github.com/quasarframework/quasar/tree/dev/ui/lang en-us
? Use RTL support? No
? Select features: IE11 support, Roboto font, Material, Material Outlined, Material Round, Material Sharp, Fontawesome, Ionicons, MDI, Eva

🚀  Invoking generator for vue-cli-plugin-quasar...
📦  Installing additional dependencies...

yarn install v1.22.0
[1/4] Resolving packages...
[2/4] Fetching packages...
info There appears to be trouble with your network connection. Retrying...
info fsevents@1.2.12: The platform "linux" is incompatible with this module.
info "fsevents@1.2.12" is an optional dependency and failed compatibility check. Excluding it from installation.
info fsevents@2.1.2: The platform "linux" is incompatible with this module.
info "fsevents@2.1.2" is an optional dependency and failed compatibility check. Excluding it from installation.
[3/4] Linking dependencies...
[4/4] Building fresh packages...
success Saved lockfile.
Done in 151.58s.
⚓  Running completion hooks...

✔  Successfully invoked generator for plugin: vue-cli-plugin-quasar
 INFO  quasar
Documentation can be found at: https://quasar.dev

Quasar is relying on donations to evolve. We'd be very grateful
if you can read our manifest on "Why donations are important":
https://quasar.dev/why-donate
Donation campaign: https://donate.quasar.dev Any amount is very
welcomed. If invoices are required, please first contact
razvan@quasar.dev

Please give us a star on Github if you appreciate our work:
https://github.com/quasarframework/quasar

Enjoy! - Quasar Team

自動変換をYにした場合は以下のように自動でQuasarの形式に変換されてます。

App.vue
<template>
  <q-layout view="lHh Lpr lFf">
    <q-header elevated class="glossy">
      <q-toolbar>
        <q-btn
          flat
          dense
          round
          @click="leftDrawerOpen = !leftDrawerOpen"
          aria-label="Menu"
          icon="menu"
        />

        <q-toolbar-title>
          Quasar App
        </q-toolbar-title>

        <div>Quasar v{{ $q.version }}</div>
      </q-toolbar>
    </q-header>

    <q-drawer
      v-model="leftDrawerOpen"
      show-if-above
      bordered
      content-class="bg-grey-2"
    >
      <q-list>
        <q-item-label header>Essential Links</q-item-label>
        <q-item clickable tag="a" target="_blank" href="https://quasar.dev">
          <q-item-section avatar>
            <q-icon name="school" />
          </q-item-section>
          <q-item-section>
            <q-item-label>Docs</q-item-label>
            <q-item-label caption>quasar.dev</q-item-label>
          </q-item-section>
        </q-item>
        <q-item clickable tag="a" target="_blank" href="https://github.com/quasarframework/">
          <q-item-section avatar>
            <q-icon name="code" />
          </q-item-section>
          <q-item-section>
            <q-item-label>Github</q-item-label>
            <q-item-label caption>github.com/quasarframework</q-item-label>
          </q-item-section>
        </q-item>
        <q-item clickable tag="a" target="_blank" href="https://chat.quasar.dev">
          <q-item-section avatar>
            <q-icon name="chat" />
          </q-item-section>
          <q-item-section>
            <q-item-label>Discord Chat Channel</q-item-label>
            <q-item-label caption>chat.quasar.dev</q-item-label>
          </q-item-section>
        </q-item>
        <q-item clickable tag="a" target="_blank" href="https://forum.quasar.dev">
          <q-item-section avatar>
            <q-icon name="forum" />
          </q-item-section>
          <q-item-section>
            <q-item-label>Forum</q-item-label>
            <q-item-label caption>forum.quasar.dev</q-item-label>
          </q-item-section>
        </q-item>
        <q-item clickable tag="a" target="_blank" href="https://twitter.com/quasarframework">
          <q-item-section avatar>
            <q-icon name="rss_feed" />
          </q-item-section>
          <q-item-section>
            <q-item-label>Twitter</q-item-label>
            <q-item-label caption>@quasarframework</q-item-label>
          </q-item-section>
        </q-item>
      </q-list>
    </q-drawer>

    <q-page-container>
      <HelloWorld />
    </q-page-container>
  </q-layout>
</template>

Pugの追加

次はPugの追加をしましょう。

関連記事 【簡単瞬殺】vue-cliでpugを導入して記述量を半分以下に減らす方法【Electron】 2019/09/11 636文字 約2分で読めます
[adsense-responsive]

HTMLのようなマークアップだと記述量が多くなってしまうので、階層化によって記述が出来るPugだと記述量が圧倒的に少なくなります

ただ、ESLintなどが対応していないなどのデメリットもあるのでお好みで導入してください。

今回は簡単なページを作るだけなのでESLintの懸念は一旦忘れて導入してみようと思います♪

追加は以下のコマンドで簡単に出来ます。

vue add pug
📦  Installing vue-cli-plugin-pug...

yarn add v1.22.0
[1/4] Resolving packages...
[2/4] Fetching packages...
info fsevents@1.2.12: The platform "linux" is incompatible with this module.
info "fsevents@1.2.12" is an optional dependency and failed compatibility check. Excluding it from installation.
info fsevents@2.1.2: The platform "linux" is incompatible with this module.
info "fsevents@2.1.2" is an optional dependency and failed compatibility check. Excluding it from installation.
[3/4] Linking dependencies...
[4/4] Building fresh packages...
success Saved lockfile.
success Saved 33 new dependencies.
info Direct dependencies
└─ vue-cli-plugin-pug@1.0.7
info All dependencies
...
()
...
Done in 106.08s.
✔  Successfully installed plugin: vue-cli-plugin-pug

Plugin vue-cli-plugin-pug does not have a generator to invoke

App.vueのHTML記法をPug記法に変換

次にApp.vueのHTML記述をPug記法に変換しましょう。

App.vue
<template lang="pug">
  q-layout(view='lHh Lpr lFf')
    q-header.glossy(elevated='')
      q-toolbar
        q-btn(flat='', dense='', round='', @click='leftDrawerOpen = !leftDrawerOpen', aria-label='Menu', icon='menu')
          q-toolbar-title           Quasar App
          div Quasar v{{ $q.version }}
    q-drawer(v-model='leftDrawerOpen', show-if-above='', bordered='', content-class='bg-grey-2')
      q-list
        q-item-label(header='') Essential Links
        q-item(clickable='', tag='a', target='_blank', href='https://quasar.dev')
          q-item-section(avatar='')
            q-icon(name='school')
          q-item-section
            q-item-label Docs
            q-item-label(caption='') quasar.dev
        q-item(clickable='', tag='a', target='_blank', href='https://github.com/quasarframework/')
          q-item-section(avatar='')
            q-icon(name='code')
          q-item-section
            q-item-label Github
            q-item-label(caption='') github.com/quasarframework
        q-item(clickable='', tag='a', target='_blank', href='https://chat.quasar.dev')
          q-item-section(avatar='')
            q-icon(name='chat')
          q-item-section
            q-item-label Discord Chat Channel
            q-item-label(caption='') chat.quasar.dev
        q-item(clickable='', tag='a', target='_blank', href='https://forum.quasar.dev')
          q-item-section(avatar='')
            q-icon(name='forum')
          q-item-section
            q-item-label Forum
            q-item-label(caption='') forum.quasar.dev
        q-item(clickable='', tag='a', target='_blank', href='https://twitter.com/quasarframework')
          q-item-section(avatar='')
            q-icon(name='rss_feed')
          q-item-section
            q-item-label Twitter
            q-item-label(caption='') @quasarframework
    q-page-container
      HelloWorld

</template>
...
(略)
...

templateタグにlang="pug"を追加するのを忘れずに。

確認

では、ここまでの修正を確認してみましょう。

正常に表示が出来ました♪

VSCodeのPrettierの設定

こちらの設定は好みによりますが、VSCodeの保存時の自動コードフォーマットを有効にしたい方は以下の記事を参考にして追加してみてください♪

関連記事 【Prettier・ESLint】Vue-CLIで生成したプロジェクトにVSCodeの自動整形と静的チェックを有効化する方法【フロントエンド最新技術】 2020/04/18 1310文字 約3分で読めます

終わりに

これでPug+Quasarを用いたVueプロジェクトの準備が出来ました。

Vue-CLIを使えばコマンドを打つだけでだいたい整える事が出来るので、ぜひ参考にしてみてください♪