vue-cli 3.0で始めるPWAとVue.jsのconfig周り
みなさん、Vue.jsやってますか?僕はバリバリです(?)
最近vue-cliの3系が出て、npmもvue-cli
から@vue/cli
に変わりましたね。導入からディレクトリ構成も結構変わりました(webpack.configがないとか)。
大きな変更点として、webpack4系の対応と、template形式からplugin形式のカスタマイズに変更になりました。この辺りはこのスライドなどが参考になると思います。
Nuxt.jsも話題なのですが、今回は、今僕が開発中のプロジェクトの設定を丸々リプレースするための参考に、普通のVue.jsでプロジェクトを作成してみようと思います。
また、設定周りで変わったところも多いので(process.envとかcommon.scssの読み込みとか)、Tipsとして最後の方に載せておきます。
環境
- node: v10.6.0
- npm: 6.1.0
ちなみに僕はnodeのバージョン管理にanyenv
からのndenv
を使用しています。とても使いやすい。
プロジェクト作成
早速いきましょう
-% npm install -g @vue/cli
----------- 中略 -----------
+ @vue/cli@3.0.0-rc.4
added 692 packages from 471 contributors in 30.393s
-% vue -V
3.0.0-rc.4
インストールができました。
それではプロジェクトを作成します。ここで、一番最初の選択肢はDefault
ではなくManually
にすることに気を付けてください。
-% vue create vue-cli-3-pwa-sample
Vue CLI v3.0.0-rc.4
? Please pick a preset: Manually select features
? Check the features needed for your project: Babel, PWA, Router, Vuex, CSS Pre-processors, Linter, Unit, E2E
? Pick a CSS pre-processor (PostCSS, Autoprefixer and CSS Modules are supported by default): SCSS/SASS
? Pick a linter / formatter config: Basic
? Pick additional lint features: Lint on save
? Pick a unit testing solution: Mocha
? Pick a E2E testing solution: Cypress
? Where do you prefer placing config for Babel, PostCSS, ESLint, etc.? In dedicated config files
? Save this as a preset for future projects? Yes
? Save preset as:
? Pick the package manager to use when installing dependencies: NPM
とまあ、こんな感じで設定していくと良いと思います。2つ目は**「Babel, PWA, Router, Vuex, CSS Pre-processors, Linter, Unit, E2E」**と、TypeScript以外を選択しています。まあ、細かいところはお好みで。
⚓ Running completion hooks...
📄 Generating README.md...
🎉 Successfully created project vue-cli-3-pwa-sample.
👉 Get started with the following commands:
$ cd vue-cli-3-pwa-sample
$ npm run serve
はい、プロジェクトが作成されました。
起動
早速起動してみましょう。
-% cd vue-cli-3-pwa-sample
-% npm run serve
INFO Starting development server...
98% after emitting CopyPlugin
DONE Compiled successfully in 5830ms 7:20:11 PM
App running at:
- Local: http://localhost:8080/
- Network: http://192.168.20.4:8080/
Note that the development build is not optimized.
To create a production build, run npm run build.
起動したので、localhost:8080にChromeでアクセスしてみましょう。
また、もう一つNetwork: http://192.168.20.4:8080/
があるため、LAN内からIPでもアクセスできるようです。試しに、僕のAndroid端末でアクセスしてみましょう。
素晴らしい!!これで端末デバッグもやりやすいですね!!
構成
root/
├ node_modules/
├ public/
│ ├ img/icons/
│ ├ favicon.ico
│ ├ index.html - SPAの起点になるhtmlファイル
│ ├ manifest.json - PWA用のmanifestファイル
│ └ robots.txt
├ src/
│ ├ assets/
│ ├ components/ - 汎用性の高いvueファイルはここに
│ ├ views/ - ページに相当するvueファイルはここに(パス名=ファイル名にすると良い)
│ ├ App.vue - SPAの起点になるvueファイル
│ ├ main.js - Vueの基本設定を記述、App.vueをhtmlに紐付ける
│ ├ registerServiceWorker.js - サービスワーカーの設定
│ ├ router.js - ルーティング設定
│ ├ store.js - Vuexの設定
│ └ robots.txt
├ tests/
│ ├ e2e - E2Eテスト
│ └ unit - Unitテスト
├ .browserslistrc - CSS3のベンダープレフィックスを自動で付与する際の設定
├ .eslintrc.js - ESLintの設定
├ .gitignore
├ .postcssrc.js - PostCSSの設定だが、ここではautoprefixerの適用
├ babel.config.js - Babelの設定
├ cypress.json - E2Eテストフレームワークの設定
├ package.json
├ package-lock.json
└ README.md
ざっと見るに、public
に静的ファイルを設置し、srcにはコンパイルなどが必要なファイルを置くようだ。
ここでindex.htmlを見ると、<%= BASE_URL %>favicon.ico
という記述があるので、BASE_URL
でpublic
直下にアクセスできるみたい。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<title>vue-cli-3-pwa-sample</title>
</head>
<body>
<noscript>
<strong>We're sorry but vue-cli-3-pwa-sample doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>
各種設定
さて、ライブラリや設定周りも少し紹介します。
package.json
VueでWebアプリを作成するにあたり、使用頻度の高いライブラリです。(※)のものは、前述の手順で既にinstallされているものです。
- vue-route (※): SPAのルーティング
- vuex (※): プロジェクト全体の共通リソースを管理するのに便利
- vuex-persistedstate: localStrageを使ったvuexリソースの永続化
- buefy: BulmaというCSSフレームワークを、Vue向けにコンポーネント化してくれたもの。エフェクトがあるので、Bulmaよりも良さげ
- ElementUI: 汎用性の高いコンポーネントを提供してくれている(が、ちとサイズがでかい
- vee-validate: inputバリデーション
- vue-i18n: 国際化
- vue-moment: 日付を扱うmoment.jsのvueプラグイン
- webpack-bundle-analyzer: ライブラリのサイズ関係を一目できるやつ
router.js
特にないが、デフォルトがhashモードなので、historyモードにしておくと良い。
import Vue from 'vue'
import Router from 'vue-router'
import Home from './views/Home.vue'
import About from './views/About.vue'
Vue.use(Router)
export default new Router({
mode: 'history',
routes: [
{
path: '/',
name: 'home',
component: Home
},
{
path: '/about',
name: 'about',
component: About
}
]
})
store.js
永続化したいなら以下のように
import Vue from 'vue'
import Vuex from 'vuex'
import createPersistedState from 'vuex-persistedstate'
Vue.use(Vuex)
export default new Vuex.Store({
state: {},
mutations: {},
actions: {},
plugins: [createPersistedState()]
})
process.envどうするの
webpack4
からno configを謳っているが、envは書きたい。ので、以下のファイルをルートに設置する。
VUE_APP_API_URL=https://localhost:9000/v1
VUE_APP_DEBUG=true
VUE_APP_API_URL=https://api.hoge.com/v1
VUE_APP_DEBUG=false
ポイントは、VUE_APP_
を頭に付けること。これがないとprocess.env
に入ってこない。
もちろん取り出すときもprocess.env.VUE_APP_API_URL
でアクセスする。
全vueファイルで共通のCSSを読み込みたい
以前のwebpackを使うバージョンでは、webpack.config
に以下のような設定を書いていたと思う。
scss: generateLoaders('sass').concat({
loader: 'sass-resources-loader',
options: {
resources: path.resolve(__dirname, '../src/assets/scss/common.scss')
}
})
さて、本バージョンからはwebpack.config
がないため、vue.config.js
というファイルをルートに作成し、以下のように記述すれば良い。
module.exports = {
css: {
loaderOptions: {
sass: {
data: `@import "@/assets/scss/common.scss";`
}
}
}
}
webpack-bundle-analyzer
vue.config.js
ついでに、こいつを使いたい場合は以下のように書けば良い。
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
module.exports = {
css: {
loaderOptions: {
sass: {
data: `@import "@/assets/scss/common.scss";`
}
}
},
configureWebpack: {
plugins: [new BundleAnalyzerPlugin()]
}
}
おわりに
設定周りは調べる時間が無駄なので、参考にしていただければと思います。
あれ、PWA...??