adonisとvueを使用してビルドフルスタックJavascriptアプリケーション


Originally posted at michaelzanggl.com. Subscribe to my newsletter to never miss out on new content.


今日はJavaScriptのみを使用してクリーンなアプリケーションを構築できるようにする2つの素晴らしいフレームワークをまとめたいと思います.
Adonis Laravelのインスピレーションを得たWebフレームワークのノードです.これは、Ralavelの機能の多くをSQL ORM、認証、移行、MVC構造などのように扱っています.
Vue フロントページWebフレームワークは、単一のページアプリケーション(SPA)または一般的に、対話型を必要とするアプリケーションを構築することです.反応のように、それはあなたが考える方法を変更し、フロントエンドを設計します.
このチュートリアルにコードを見つけることができます.

ムンゲ / アドニスVue


デモと青写真プロジェクトの青写真


アドニスVue


これは、フルスタックとBluePrint\/デモADonisjsとVue用です.それを設定する方法を確認してください.

移動


スタートアップ移行を実行するには、次のコマンドを実行します.
adonis migration:run

アプリケーションを起動する

npm run dev



プロジェクト設定

ADONIS CLIをインストールする

npm install -g @adonisjs/cli

アドニスプロジェクト


adonis new fullstack-app
cd fullstack-app

Webpack


ファイル構造


我々はすべてのフロントエンドのJavaScriptとVueファイルを作成するresources/assets/js . Webpackはこれらを転送し、内部に配置しますpublic/js .
必要なディレクトリとファイルを作りましょう
mkdir resources/assets/js -p
touch resources/assets/js/main.js
// resources/assets/js/main.js

const test = 1
console.log(test)

ウェブパック


カラベルの背景から来る人々は、よく知られているかもしれませんLaravel-Mix . 良いことは、我々がadonisプロジェクトのためにララベル混合を使うことができるということです.それはWebpackの構成地獄の多くを取り、80/20ユースケースに最適です.
依存関係のインストールとコピーを開始するwebpack.mix.js プロジェクトのルートディレクトリに.
npm install laravel-mix --save
cp node_modules/laravel-mix/setup/webpack.mix.js .
webpack.mix.js すべての設定が行われる場所です.設定しましょう
// webpack.mix.js

let mix = require('laravel-mix');

// setting the public directory to public (this is where the mix-manifest.json gets created)
mix.setPublicPath('public')
// transpiling, babelling, minifying and creating the public/js/main.js out of our assets
    .js('resources/assets/js/main.js', 'public/js')



// aliases so instead of e.g. '../../components/test' we can import files like '@/components/test'
mix.webpackConfig({
    resolve: {
        alias: {
            "@": path.resolve(
                __dirname,
                "resources/assets/js"
            ),
            "@sass": path.resolve(
                __dirname,
                "resources/assets/sass"
            ),
        }
    }
 });
また、クラッシュを避けるために、既存の例を削除してください
mix.js('src/app.js', 'dist/').sass('src/app.scss', 'dist/');

必要なスクリプトの追加


スクリプトを追加しましょうpackage.json それは、我々の資産を放散させます.次の行を追加するscripts .
// package.json

"assets-dev": "node node_modules/cross-env/dist/bin/cross-env.js NODE_ENV=development webpack --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js",
"assets-watch": "node node_modules/cross-env/dist/bin/cross-env.js NODE_ENV=development webpack --watch --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js",
"assets-hot": "node node_modules/cross-env/dist/bin/cross-env.js NODE_ENV=development webpack-dev-server --inline --hot --config=node_modules/laravel-mix/setup/webpack.config.js",
"assets-production": "node node_modules/cross-env/dist/bin/cross-env.js NODE_ENV=production webpack --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js"
実行可能npm run assets-watch 開発中にファイルを監視する.コマンドを実行するには、次の2つのファイルを作成します.public/mix-manifest.json and public/js/main.js . チームで働くとき、彼らが多くのマージ衝突を引き起こすことがありえるので、これらの生成されたファイルにgitignoreに最適です..

ルーティング


我々はスパを構築しているので、adonisは/api . 他のすべてのルートはVueに転送されます.そして、それはクライアント側のルーティングの世話をします.
中を行くstart/routes.js そして、以下のスニペットを加えます
// start/routes.js

// all api routes (for real endpoints make sure to use controllers)
Route.get("hello", () => {
    return { greeting: "Hello from the backend" };
}).prefix("api")
Route.post("post-example", () => {
    return { greeting: "Nice post!" };
}).prefix("api")

// This has to be the last route
Route.any('*', ({view}) =>  view.render('app'))
この行を見てみましょう.Route.any('*', ({view}) => view.render('app'))アスタリスクの意味everything that has not been declared before . したがって、これが宣言される最後のルートであることは重要です.
内部引数view.render app 我々のスパの出発点は、どこでロードされますmain.js ファイルを作成しました.Adoisは刃にかなり類似しているエッジテンプレートエンジンを使用します.我々の見解をつくりましょう
touch resources/views/app.edge
// resources/views/app.edge

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Adonis & Vue App</title>
</head>
<body>
    <div id="app"></div>
    {{ script('/js/main.js') }}
</body>
</html>
グローバルscript 関数は内部のファイルを探すresources/assets そして、自動的にスクリプトタグを作成します.

VUEセットアップ


VueとVueルータをインストールしましょう
npm install vue vue-router --save-dev
Vueを初期化するresources/assets/js/main.js
// resources/assets/js/main.js

import Vue from 'vue'
import router from './router'
import App from '@/components/layout/App'

Vue.config.productionTip = false


new Vue({
  el: '#app',
  router,
  components: { App },
  template: '<App/>'
})
この作品を作るために、我々はつくらなければなりませんApp.vue . すべてのレイアウト関連のものはここに行きます、我々はちょうど現在それのために超簡単にして、ちょっとルータを含みます.
mkdir resources/assets/js/components/layout -p
touch resources/assets/js/components/layout/App.vue
// /resources/assets/js/components/layout/App.vue

<template>
    <router-view></router-view>
</template>

<script>
export default {
  name: 'App'
}
</script>
また、クライアント側のルータ設定を作成する必要があります
mkdir resources/assets/js/router
touch resources/assets/js/router/index.js
// resources/assets/js/router/index.js

import Vue from 'vue'
import Router from 'vue-router'

Vue.use(Router)

export default new Router({
    mode: 'history', // use HTML5 history instead of hashes
    routes: [
        // all routes
    ]
})
次に、内部に2つのテストコンポーネントを作りましょうresources/assets/js/components ルータをテストする.
touch resources/assets/js/components/Index.vue
touch resources/assets/js/components/About.vue
// resources/assets/js/components/Index.vue

<template>
    <div>
        <h2>Index</h2>
        <router-link to="/about">To About page</router-link>
    </div>
</template>

<script>
export default {
    name: 'Index',
}
</script>
二番目の
// /resources/assets/js/components/About.vue

<template>
    <div>
        <h2>About</h2>
        <router-link to="/">back To index page</router-link>
    </div>
</template>

<script>
export default {
    name: 'About',
}
</script>
インデックスコンポーネントには、ページとその逆のリンクがリダイレクトされます.
ルータの設定に戻り、ルートに2つのコンポーネントを追加しましょう.
// resources/assets/js/router/index.js

// ... other imports
import Index from '@/components/Index'
import About from '@/components/About'

export default new Router({
    // ... other settings
    routes: [
        {
            path: '/',
            name: 'Index',
            component: Index
        },
        {
            path: '/about',
            name: 'About',
            component: About
        },
    ]
})

ランチ


我々のアプリケーションを起動し、我々が持っているものを参照してみましょう.必ず持っているnpm run assets-watch 次に、使用してadonisサーバーを起動
adonis serve --dev
デフォルトではADONISポート3333を使用しますので、ヘッドlocalhost:3333 そしてインデックスとページの間をナビゲートすることができます.
やってみるlocalhost:3333/api/hello JSONで以下の応答を得るべきです.{ greeting: "Nice post!" } .

ボーナス


私たちはちょうど終わっています、滑らかに働くすべてを得るために我々が必要とする少数のマイナーなものがあります
  • CSRF保護
  • キャッシュ
  • 配備(heroku)
  • CSRF保護


    Stateless ( JWT )認証を使用していないので、ポストを使用して要求を削除する必要がありますCSRF protection . 以前に作成したポストルートを取得しようとしましょう.あなたはdevtoolsからこれを行うことができます.
    fetch('/api/post-example', { method: 'post' })
    
    応答は、あなたのようなものですPOST http://127.0.0.1:3333/api/post-example 403 (Forbidden) 以来、我々はまだCSRFトークンを追加していません.Adonisはクッキーにこのトークンを保存します.したがって、NPMモジュールをインストールして、それを取得するのを手伝ってください.
    npm install browser-cookies --save
    
    NPMモジュールをインストールするには、まずアドニスサーバをシャットダウンすることをお勧めします.
    次に次のコードを追加しますmain.js
    // resources/assets/js/main.js
    
    // ... other code
    
    import cookies from 'browser-cookies';
    
    (async () => {
        const csrf = cookies.get('XSRF-TOKEN')
        const response = await fetch('/api/post-example', {
            method: 'post',
            headers: {
                'Accept': 'application/json',
                'Content-Type': 'application/json',
                'x-xsrf-token': csrf,
            },
        });
    
        const body = await response.json()
    
        console.log(body)
    })()
    
    これは、コンソールで望ましい結果を与えるべきです!これをモジュールに抽出することを勧めます.もちろん、代わりにaxiosのようなライブラリを使用することもできます.

    キャッシュ


    Cache Busting 我々の訪問者が常に我々がサーブする最新の資産を得るのを確実にする方法です.
    有効にするには、次のコードを追加しますwebpack.mix.js
    // webpack.mix.js
    
    mix.version()
    
    再起動npm run assets-watch , あなたは内部の変化を見る必要がありますmix-manifest.json
    // public/mix-manifest.json
    
    {
        "/js/main.js": "/js/main.js?id=e8f10cde10741ed1abfc"
    }
    
    我々が変化をするときはいつでもmain.js ハッシュが変更されます.このJSONファイルを私たちのビューで読むことができます.
    touch start/hooks.js
    
    const { hooks } = require('@adonisjs/ignitor')
    const Helpers = use('Helpers')
    
    const mixManifest = require(Helpers.publicPath('mix-manifest.json'))
    
    hooks.after.providersBooted(async () => {
        const View = use('View')
        View.global('versionjs', (filename) => {
            filename = `/js/${filename}.js`
            if (!mixManifest.hasOwnProperty(filename)) {
                throw new Error('Could not find asset for versioning' + filename)
            }
    
            return mixManifest[filename]
        })
    
        View.global('versioncss', (filename) => {
            filename = `/css/${filename}.css`
            if (!mixManifest.hasOwnProperty(filename)) {
                throw new Error('Could not find asset for versioning' + filename)
            }
    
            return mixManifest[filename]
        })
    })
    
    これは私たちのビューで使用できる2つのグローバルメソッドを作成します.移動するresources/assets/views/app.edge 置換
    {{ script('/js/main.js') }}
    
    with
    {{ script(versionjs('main')) }}
    
    そして、それはすべてのキャッシュの破裂です.

    展開


    もうan article AdonisアプリをHerokuに配備すること.我々は同じプロジェクトに我々の資産を持っているので、我々は展開をスムーズに実行する1つまたは2つのものを追加する必要があります.下に次のコードを追加しますscripts 内部package.json
    // package.json
    
    "heroku-postbuild": "npm run assets-production"
    
    これはHerokuに配備中に我々の資産を配布するよう指示します.あなたがHerokuを使用していない場合、他のサービスはおそらく同様のソリューションを提供します.
    展開が失敗した場合.
    あなたのHerokuアプリを設定するには、dev依存関係もインストールする必要があります.次のコマンドを実行することで設定できます
    heroku config:set NPM_CONFIG_PRODUCTION=false YARN_PRODUCTION=false
    
    また、Herokuウェブサイトの設定を直接設定できます.
    そして、それはそこにあるすべてです.
    すべての設定をスキップするには
    adonis new application-name --blueprint=MZanggl/adonis-vue-demo
    
    あなたが既に登録ルートとコントローラ、Vuetifyレイアウト、Vue店などを含む青写真に興味があるならば、知らせてください.
    この記事があなたを助けたならば、私は書くソフトウェアを単純化することに多くのヒントを持っていますhere .