環境
この手順はproですが、無料版の方でも使えます!最初は無料版で試作していてどうしても欲しいコンポーネントがあったので、こちらをインストールした経緯があるので無料でも適用可能です!
- Homestead 10.2.0
- PHP 7.2
Laravel をインストール
1 |
composer create-project "laravel/laravel=6.*" sampleproject |
vuetify-material-dashboard-pro-v2.1.0/src 以下のファイルをコピー
sampleproject/resources/js へペースト
/sampleproject/resources/js/sass の内容を
/sampleproject/resources/sass へ移動
/sampleproject/resources/sass/variables.scss を削除
package.jsonを修正
package.json
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
{ "private": true, "scripts": { "dev": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js", "development": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js", "watch": "npm run development -- --watch", "watch-poll": "npm run watch -- --watch-poll", "hot": "cross-env NODE_ENV=development node_modules/webpack-dev-server/bin/webpack-dev-server.js --inline --hot --config=node_modules/laravel-mix/setup/webpack.config.js", "prod": "npm run production", "production": "cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js --no-progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js", "postinstall": "echo postinstall finished!!", "heroku-prebuild": "cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js --no-progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js", "heroku-postbuild": "echo heroku-postbuild finished!!" }, "devDependencies": { "laravel-mix": "^5.0.1", "cross-env": "^7.0", "axios": "^0.19", "bootstrap": "^4.0.0", "browser-sync": "^2.26.7", "browser-sync-webpack-plugin": "^2.0.1", "deepmerge": "^4.2.2", "jquery": "^3.2", "lodash": "^4.17.13", "popper.js": "^1.12", "resolve-url-loader": "^2.3.1", "sass": "^1.20.1", "sass-loader": "^8.0.0", "vee-validate": "^3.2.2", "vue-chartist": "^2.2.1", "vue-template-compiler": "^2.6.10", "css-loader": "^3.4.2", "vue-style-loader": "^4.1.2", "vuetify-loader": "^1.4.3" }, "dependencies": { "vue": "^2.5.17", "vue-i18n": "^8.15.3", "vue-router": "^3.1.3", "vuetify": "^2.2.18", "vuex": "^3.1.2" } } |
パッケージをインストール
1 |
npm i |
webpack.mix.jsを修正
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
const mix = require('laravel-mix'); const VuetifyLoaderPlugin = require('vuetify-loader/lib/plugin'); //webpackの設定を上書き mix.webpackConfig({ plugins: [ new VuetifyLoaderPlugin() ], resolve: { extensions: ['.js', '.vue', '.json'], alias: { 'vue$': 'vue/dist/vue.esm.js', '@': __dirname + '/resources/js' }, }, }); //variable.scssのスタイルが反映されないのでwebpackの設定が読み込まれるときに滑り込ませる Mix.listen("configReady", config => { const scssRule = config.module.rules.find(r => r.test.toString() === /\.scss$/.toString()); const scssOptions = scssRule.loaders.find(l => l.loader === "sass-loader").options; scssOptions.implementation = require('sass'); scssOptions.prependData = "@import \"./resources/sass/variables.scss\";"; const sassRule = config.module.rules.find(r => r.test.toString() === /\.sass$/.toString()); const sassOptions = sassRule.loaders.find(l => l.loader === "sass-loader").options; sassOptions.implementation = require('sass'); sassOptions.prependData = "@import \"./resources/sass/variables.scss\""; }); //ブラウザを自動更新 mix.browserSync('プロジェクトのURL') .sass('resources/sass/app.scss', 'public/css') .js('resources/js/app.js', 'public/js') .version(); |
/sampleproject/resources/js/main.js の内容をコピー
/sampleproject/resources/js/app.js へペースト
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
import Vue from 'vue' import App from './App.vue' import router from './router' import store from './store' import './plugins/base' import './plugins/chartist' import './plugins/vee-validate' import './plugins/vue-world-map' import vuetify from './plugins/vuetify' import i18n from './i18n' Vue.config.productionTip = false new Vue({ router, store, vuetify, i18n, render: h => h(App), }).$mount('#app') |
一旦watchしてエラーを確認
1 |
npm run watch |
私はエラーが2つ出ました。
1 2 |
Module not found: Error: Can't resolve '@/sass/overrides.sass' in '/***/***/***/sampleproject/resources/js/plugins' Module not found: Error: Can't resolve 'vue-world-map' in '/***/***/***/sampleproject/resources/js/plugins' |
webpack.mix.jsのresolveにはjsまでのパスしか書いていないので、出ているエラーが1つと、そもそもインストールしていないvue-world-mapです。
plugins/vuetifyの修正を行なっていきます。
/sampleproject/resources/js/plugins/vuetify.js
1 2 3 4 5 6 |
import Vue from 'vue' import Vuetify from 'vuetify/lib' import i18n from '@/i18n' import '@/../sass/overrides.sass' #パスを相対に ##以下略 |
/sampleproject/resources/js/app.js
1 2 3 4 5 6 7 8 9 10 |
import Vue from 'vue' import App from './App.vue' import router from './router' import store from './store' import './plugins/base' import './plugins/chartist' import './plugins/vee-validate' // import './plugins/vue-world-map' #####コメントアウト import vuetify from './plugins/vuetify' import i18n from './i18n' |
ここまですると概ねエラーは消えていますが、もっとややこしい現象が起きます。
このファイルを一度のぞいてみてください。
何かJSのコードが出力されているのではないでしょうか?私だけ?w
/sampleproject/public/css/app.css
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
var map = { "./clint-mckoy.jpg": "./resources/js/assets/clint-mckoy.jpg", "./lock.jpg": "./resources/js/assets/lock.jpg", "./login.jpg": "./resources/js/assets/login.jpg", "./logo.png": "./resources/js/assets/logo.png", "./pricing.jpg": "./resources/js/assets/pricing.jpg", "./register.jpg": "./resources/js/assets/register.jpg", "./vuetify.svg": "./resources/js/assets/vuetify.svg" }; function webpackContext(req) { var id = webpackContextResolve(req); return __webpack_require__(id); } function webpackContextResolve(req) { if(!__webpack_require__.o(map, req)) { var e = new Error("Cannot find module '" + req + "'"); e.code = 'MODULE_NOT_FOUND'; throw e; } return map[req]; } webpackContext.keys = function webpackContextKeys() { return Object.keys(map); }; webpackContext.resolve = webpackContextResolve; module.exports = webpackContext; webpackContext.id = "./resources/js/assets sync recursive ^\\.\\/.*$"; |
下記でも報告されているようです。
https://stackoverflow.com/questions/55057581/npm-run-production-missed-semicolon-error
https://github.com/JeffreyWay/laravel-mix/issues/1976
webpackのバグで5でなおるらしいです…。まだbetaなのと、laravel-mixはまだwebpack4.36.1を使用しています。
/sampleproject/node_modules/laravel-mix/package.json
1 |
"webpack": "^4.36.1", |
ここめっちゃ時間かかりました…。
実は、devやwatch時には全く問題なく動いていて全然気づかなかったんですがherokuにデプロイしようとproductionsしようとするとmissing semicoronてきなエラーが出て止まってしまうんです。
8時間くらいずっとwebpack.mixをトレースしたり色々したんですが、結局var mapに代入されてる画像を根こそぎ消しにかかっていたら一つのコードを消したら、app.cssの内容がクリアされました!!
それがここです。
/sampleproject/resources/js/layouts/frontend/View.vue
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
<template> <v-content id="pages" :class="$vuetify.theme.dark ? undefined : 'grey lighten-3'" > <v-img :class="{ 'v-image--sm': this.$vuetify.breakpoint.smAndDown, 'v-image--md': this.$vuetify.breakpoint.mdAndDown }" :src="require(`@/assets/${src || 'clint-mckoy.jpg'}`)" ###ここを消す!!! gradient="to top, rgba(0, 0, 0, .5), rgba(0, 0, 0, .5)" min-height="100%" > <router-view /> </v-img> </v-content> </template> |
1 |
/sampleproject/resources/js/views/pages/components/core/View.vue |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
<template> <v-content id="pages" :class="$vuetify.theme.dark ? undefined : 'grey lighten-3'" > <v-img :class="{ 'v-image--sm': this.$vuetify.breakpoint.smAndDown, 'v-image--md': this.$vuetify.breakpoint.mdAndDown }" :src="require(`@/assets/${src || 'clint-mckoy.jpg'}`)"###ここを消す!!! gradient="to top, rgba(0, 0, 0, .5), rgba(0, 0, 0, .5)" min-height="100%" > <v-responsive :style="styles" min-height="100vh" class="d-flex align-center" > <router-view /> </v-responsive> </v-img> </v-content> </template> |
requireが悪さをしているみたいですね…webpackのバグってことで!
Laravel側の設定
ではでは、Laravel側の設定を行なっていきます。
/sampleproject/resources/views へindex.blade.phpを追加します。
/sampleproject/resources/views/index.blade.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
<!doctype html> <html lang="{{ app()->getLocale() }}"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <!-- CSRF Token --> <meta name="csrf-token" content="{{ csrf_token() }}"> <title>{{ config('app.name', 'Laravel') }}</title> <!-- Styles --> <link rel="stylesheet" href="{{ mix('css/app.css') }}"> </head> <body> <div id="app"> </div> <!-- Scripts --> <script src="{{ mix('js/app.js') }}"></script> </body> </html> |
routesを編集
/sampleproject/routes/web.php
1 |
Route::get('/{any?}', fn() => view('index'))->where('any', '.+'); |
/sampleproject/routes/api.php
1 2 3 4 5 |
use Illuminate\Http\Request; Route::middleware('auth:api')->get('/user', function (Request $request) { return $request->user(); }); |
1 |
/sampleproject/resources/sass/app.scss<br> |
アイコンが表示されないので、表示されるようにする
/sampleproject/resources/sass/app.scss
1 2 |
@import url('https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900'); @import url('https://cdn.jsdelivr.net/npm/@mdi/font@latest/css/materialdesignicons.min.css'); |
とりあえず表示されるようになったので、次はherokuへアップしていこうと思います。