■ はじめに
Node.jsのバージョンに依存せず複数プロジェクトを構築する手段の一つとして試してみた。
特にM1チップマシン上でNode.js開発環境を構築するのが大変だったので、
簡略化したかったというのが主な動機です。
今回はあくまで開発環境をDocker化するものなので、本番環境で使えるコンテナを構築するわけではないことはご留意ください。
ブラウザからは http://localhost:8080
で確認できます。
『docker-compose.yml』 及び 『vue.config.js』 で指定したポートとなります。
本記事内では8080を指定しています。
■ 事前知識
- ほとんどの操作はターミナルで行うのでCLIの知識(というか慣れの部分が大きいかも)
- Dockerに関する知識(イメージとコンテナの関係)
- Node.jsのプロジェクトなのでパッケージ管理の知識(yarn.lockは編集してはいけないとか)
ホストOSの情報
自分の場合はmac環境で作業しました。
メインはM1ですが、Intel macでも大丈夫そうです。
- OS:Big Sur (M1搭載)
- Docker:v20.10.10
- Docker Compose:v2.1.1
ホストOSにDockerのインストールが必要です。
ホストOSにNode.jsやyarnのインストールは不要です。
コンテナの操作
基本的には docker-compose.yml
のあるディレクトリでコマンドを叩く。
# コンテナをビルド
docker compose build
# 失敗するようなら
docker compose build --no-cache
# コンテナを起動
docker compose up -d
# コンテナに入る
docker compose exec web bash
## コンテナ停止:コンテナに入っている場合
exit
## コンテナ停止:コンテナに入っていない場合
docker compose stop
## コンテナを破棄(必要に応じてやる)
docker compose down
Vue CLIの操作
Vue CLIの各コマンドを叩く場合はコンテナ内に入る必要がある。
Vue CLIをグローバルにインストールしていない場合はpackage.jsonのあるディレクトリに移動する。
# package install
yarn install
# start DevServer
yarn serve
# Compiles and minifies for production
yarn build
# Run your unit tests
yarn test:unit
# Run your end-to-end tests
yarn test:e2e
# Lints and fixes files
yarn lint
DevServerの操作
- 起動する際はコンテナに入った状態で
yarn serve
- 終了する際は
control + C
で止める
■ 開発状況ごとの違い
- プロジェクトの初期構築段階
- 構築済みプロジェクトをクローン
それぞれの場合で Dockerfile
, docker-compose.yml
に多少の違いがある。
プロジェクトの初期構築段階の場合
コンテナ内でvue create
を使えるようする必要がある。
この段階では node_modules
のマウントはしない。
下記のページを参考にして、コンテナが起動したままになるようにDockerfileを作成
FROM node:14.18.1-slim
WORKDIR /app
RUN apt-get update && \
# node-sassとかnode-gypの対策に入れる
apt-get install -y python make g++ &&\
yarn global add @vue/cli
version: "3.8"
services:
web:
container_name: web
build: ./docker/web
ports:
- 8080:8080
privileged: true
volumes:
- ./app:/app
tty: true
stdin_open: true
コンテナ内でプロジェクト作成する
コンテナを起動してマウントしたappディレクトリ内にプロジェクトを構築していく。
細かい選択内容はお好みでどうぞ。
# ./app
vue create .
構築済みプロジェクトをクローンした場合
プロジェクトをクローンした場合 = package.json
及び yarn.lock
がすでに存在する場合。
docker-compose up
をしたタイミングで yarn install
が走り node_modules
にインストールされる。
FROM node:14.18.1-slim
WORKDIR /app
RUN apk update && \
# node-sassとかnode-gypの対策に入れる
apt-get install -y python make g++
version: "3.8"
services:
web:
container_name: web
build: ./docker/web
ports:
- 8080:8080
privileged: true
volumes:
- ./app:/app
- ./app/node_modules:/app/node_modules
tty: true
stdin_open: true
command: /bin/sh -c "yarn install --check-files && yarn serve"
-
yarn install --check-files
不足しているパッケージを確認して追加インストールするコマンド。
別ブランチからプルしてきて差分があった場合に不足分をインストールするイメージです。
参考: https://classic.yarnpkg.com/lang/en/docs/cli/install/#toc-yarn-install-check-files -
yarn serve
vue-cliの場合です。react や nuxt の場合とコマンドが異なる可能性があります。
■ ディレクトリ構成
下記を選択すると最終的なディレクトリ構成はこうなるはず。
- cypress
- jest
- babel
- postcss
Vue CLI v3.4.1
? Please pick a preset: Manually select features
? Check the features needed for your project: Babel, Router, Vuex, CSS Pre-proc
essors, Linter, Unit, E2E
? Use history mode for router? (Requires proper server setup for index fallback
in production) Yes
? Pick a CSS pre-processor (PostCSS, Autoprefixer and CSS Modules are supported
by default): Sass/SCSS (with node-sass)
? Pick a linter / formatter config: Prettier
? Pick additional lint features: (Press <space> to select, <a> to toggle all, <
i> to invert selection)Lint on save
? Pick a unit testing solution: Jest
? Pick a E2E testing solution: Cypress
? Where do you prefer placing config for Babel, PostCSS, ESLint, etc.? In packa
ge.json
? Save this as a preset for future projects? No
project_root
├── app/
│ ├── dist/ ← buildするとできる
│ ├── node_modules/ ← yarn install が成功するとできる
│ ├── public/
│ │ └── css/ ←これは自分で作る
│ │ └── reset.css
│ ├── src/
│ │ ├── assets/
│ │ │ ├── img/
│ │ │ └── scss/ ←これは自分で作る
│ │ │ ├── _colors.scss
│ │ │ ├── _global_inject.scss
│ │ │ ├── _mixins.scss
│ │ │ ├── _utility.scss
│ │ │ └── _variables.scss
│ │ ├── ...[ プロジェクトに応じた各ディレクトリ(views, componets, plugins など) ]/
│ │ ├── App.vue
│ │ ├── main.js
│ │ ├── registerServiceWorker.js
│ │ ├── router.js
│ │ └── store.js
│ ├── tests/
│ ├── babel.config.js
│ ├── cypress.json
│ ├── jest.config.js
│ ├── package.json
│ ├── postcss.config.js
│ ├── vue.config.js ←これは自分で作る
│ └── yarn.lock
├── docker/
│ └── web/
│ └── Dockerfile
├── docker-compose.yml
├── README.md
├── .git/
└── .gitignore
追加で入れることが多いもの
これらは入れなくてもvueの動きは確認できます。
# ajax
yarn add axios
# sass global valiables and mixin
vue add sass-resources-loader
# webfont: fontawesome5.x
yarn add @fortawesome/fontawesome-svg-core
yarn add @fortawesome/free-solid-svg-icons
yarn add @fortawesome/vue-fontawesome
yarn add @fortawesome/free-regular-svg-icons
yarn add @fortawesome/free-brands-svg-icons
# vuexの永続化のためlocalstorageを使えるようにするやつ
yarn add vuex-persistedstate
# UIフレームワーク(使わないこともある)
vue add vuetify
個人的なpackage構成
バージョンはあくまで現段階のものです。
多少増えたり減ったりしますが、今のところはこの構成をテンプレートにしています。
{
"name": "project_root",
"version": "0.1.0",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"test:unit": "vue-cli-service test:unit",
"test:e2e": "vue-cli-service test:e2e",
"lint": "vue-cli-service lint",
},
"dependencies": {
"@fortawesome/fontawesome-svg-core": "1.2.36",
"@fortawesome/free-brands-svg-icons": "5.15.4",
"@fortawesome/free-regular-svg-icons": "5.15.4",
"@fortawesome/free-solid-svg-icons": "5.15.4",
"@fortawesome/vue-fontawesome": "2.0.6",
"axios": "^0.24.0",
"core-js": "^3.6.5",
"register-service-worker": "^1.6.2",
"vue": "^2.6.14",
"vue-router": "^3.5.3",
"vuex": "^3.6.2",
"vuex-persistedstate": "^4.1.0"
},
"devDependencies": {
"@vue/cli-plugin-babel": "~4.5.0",
"@vue/cli-plugin-e2e-cypress": "~4.5.0",
"@vue/cli-plugin-eslint": "~4.5.0",
"@vue/cli-plugin-pwa": "~4.5.0",
"@vue/cli-plugin-router": "~4.5.0",
"@vue/cli-plugin-unit-jest": "~4.5.0",
"@vue/cli-plugin-vuex": "~4.5.0",
"@vue/cli-service": "~4.5.0",
"@vue/eslint-config-prettier": "^6.0.0",
"@vue/test-utils": "^1.0.3",
"babel-eslint": "^10.1.0",
"eslint": "^7.11.0",
"eslint-plugin-prettier": "^3.3.1",
"eslint-plugin-vue": "^6.2.2",
"prettier": "^2.4.1",
"sass": "^1.43.4",
"sass-loader": "^10.2.0",
"vue-cli-plugin-sass-resources-loader": "^1.0.0",
"vue-template-compiler": "^2.6.14"
}
}
packageをmain.jsにimportする。
import Vue from "vue";
import App from "./App.vue";
import router from "./router";
import store from "./store";
import "./registerServiceWorker";
// Ajax
import axios from "axios";
// Fontawesome
import { library } from "@fortawesome/fontawesome-svg-core";
import { FontAwesomeIcon } from "@fortawesome/vue-fontawesome";
import { fas } from "@fortawesome/free-solid-svg-icons";
import { fab } from "@fortawesome/free-brands-svg-icons";
import { far } from "@fortawesome/free-regular-svg-icons";
library.add(fas, far, fab);
Vue.component("font-awesome-icon", FontAwesomeIcon);
Vue.config.productionTip = false;
Vue.prototype.$axios = axios;
new Vue({
router,
store,
render: (h) => h(App),
}).$mount("#app");
vuexにもpackageを追加。
import Vue from "vue";
import Vuex from "vuex";
import createPersistedState from "vuex-persistedstate"; //これを追記
Vue.use(Vuex);
export default new Vuex.Store({
//〜中略〜
plugins: [createPersistedState()] // これを追記
});
個人的なconfig
vue.config.jsは自分で作る必要があります。
distの中身もとりあえずgit管理する想定なので、buildした際に各ファイルにハッシュが付かないようにfalseにします。
vue.config.js
は情報を見つけるのに苦労しました。
const path = require("path");
module.exports = {
// disable hashes in filenames
filenameHashing: false,
// devserver port
devServer: {
port: 8080, // well-known以外に設定しておく
disableHostCheck: true,
},
// sass global variables and mixin file load...
// SCSSを使わない場合はここから下は不要です。
chainWebpack: (config) => {
const ofs = ["vue-modules", "vue", "normal-modules", "normal"];
const cssRules = config.module.rule("css");
const postRules = config.module.rule("postcss");
const scssRules = config.module.rule("scss");
const addSassResourcesLoader = (rules, type) => {
rules
.oneOf(type)
.use("sass-resoureces-loader")
.loader("sass-resources-loader")
.options({
resources: [
path.resolve("./src/assets/scss/_global_inject.scss"),
path.resolve("./src/assets/scss/_colors.scss"),
path.resolve("./src/assets/scss/_mixins.scss"),
path.resolve("./src/assets/scss/_utility.scss"),
path.resolve("./src/assets/scss/_variables.scss"),
],
});
};
ofs.forEach((type) => {
addSassResourcesLoader(cssRules, type);
addSassResourcesLoader(postRules, type);
addSassResourcesLoader(scssRules, type);
});
return config;
},
};
■ デプロイ
yarn build
でデプロイ用の静的なファイル群(.html, .css, .js)を app/dist
配下に出力します。
それらのファイルをホスティングすることでインターネット上に公開されます。
Firebase
へのデプロイを試すためにまとめた記事↓
■ 参考記事
- https://qiita.com/kurararara/items/d76776a7dc2d763a068b
- https://qiita.com/JotarO_Oyanagi/items/541ea88870ee3b6888e9
- https://coffee-ojisan.com/vue-x-fontawesome