백엔드 API 없이 Laravel 을 Vue CLI 애플리케이션과 통합

28379 단어 inertiajsvuespalaravel
Vue.jsVue CLI로 만들어진 Laravel 프로그램을 사용하고 싶을 때마다'백엔드 API가 필요해'라는 녀석이 당신의 희망을 깨뜨려 괴롭다/슬프다.이런 방법은 틀림없다.그러나 매번 이런 말을 들을 때마다 나는 항상 나 자신에게 묻는다. 왜?Vue CLI를 사용하여 자산을 서비스해야 하기 때문에 Laravel을 백엔드 API로만 사용해야 하는 이유는 무엇입니까?
때때로 사람들은 어떻게 해야 하는 상자에 갇혀 인터넷이 어떻게 작동하는지 잊어버리는 것 같다.

우리 잠깐 멈추자...
Vue CLI의 npm run serve가 무엇을 하는지 생각해 보십시오.
그것은 코드를 가져와 컴파일하고 간단한 웹 서버를 시작하여 컴파일한 자산을 전달한다.
당신은 무엇을 알아차렸습니까?그것은 서버를 향상시키고 자산을 납부한다.우리가 CDN에서 우리의 응용 프로그램에 정적 자산을 제공할 때, 우리는 이렇게 하지 않습니까?우리는 어디에 서버를 설치해서 정적 자산을 제공할 수 있다.그게 다야.
아무도 너에게 말하지 않을 것이다. "오, 당신의 서비스 정적 자산. 지금 당신은 백엔드 API가 필요합니다."나는 네가 나의 견해에 동의할 것이라고 생각한다. 이것은 허튼소리다.
그래서 마지막으로 사람들은 당신이 이렇게 npm run serve하고 Webpack Dev Server를 http://localhost:8080에서 실행할 때 CDN에서 자산을 서비스하는 것처럼 잊어버린 것 같다.

좋아요!알겠어요. 그런데...
이제 알겠지만 Vue CLI는 해싱.js.css 파일 참조가 포함된 HTML 페이지를 생성하고 제공하는 역할을 담당합니다.이것이 바로 우리가 Vue CLI 결과를 미리 제공하고 Laravel 응용 프로그램을 백엔드 API로 사용하는 이유입니다. 맞습니까?
그렇습니다. 하지만 Vue CLI로 생성된 HTML 페이지를 Laravel의 보기로 표시하는 것을 막는 것은 무엇입니까?
여기서부터 시작합시다...

Vue CLI 애플리케이션을 어디서 생성해야 합니까?
이것은 당신의 선택이지만, 내가 좋아하는 방식은 나의 자원 폴더를 Vue 프로그램으로 만드는 것입니다.
  • 폴더를 resources에 백업합니다.
  • Vue 애플리케이션을 새 폴더resources-bkp로 생성
  • 당신의 resources를 소속된 위치로 돌려보내기
  • 새 빈 디렉터리 만들기 resources/lang
  • 생성resources/views 파일
  • 중요한 내용이 없으면 삭제하십시오.
  • mv resources resources-bkp
    vue create resources
    mv resources-bkp/lang resources/lang
    mkdir resources/views
    nano resources/vue.config.js
    rm -rf resources-bkp
    

    NOTICE: Keep in mind that, from now on, all of your npm commands must be run at the resources folder. I usually save some time by keeping 2 terminals open on my VSCode workspace: one at the project root and another at the resources folder. This way I can run commands at the project root (php artisan, composer) without having to stop the DevServer running on a separate terminal.



    기본 블레이드 템플릿 만들기resources/vue.config.jsresources-bkp 안으로 이동하고 resources/public/index.html로 이름을 바꿉니다.
    mv resources/public/index.html resources/src/template.blade.php
    

    분리 개발 및 프로덕션 구축
    개발 과정에서 생성된 HTML은 생산에 생성된 HTML과 다르다.예를 들어, resources/src/template.blade.php 태그는 환경에 따라 기본 URL이 다릅니다.
    <!-- development -->
    <link href="http://localhost:8080/css/0.d09619e2.css" rel="prefetch">
    <script type="text/javascript" src="http://localhost:8080/js/chunk-vendors.js"></script>
    
    <!-- production -->
    <link href="https://assets.mywebapp.com/css/0.d04519e3.css" rel="prefetch">
    <script type="text/javascript" src="https://assets.mywebapp.com/js/chunk-vendors.a07692ee.js"></script>
    
    그래서 우리는 그들을 헤어지게 해야 한다.개발 과정에서 우리는 생성된 보기를 link에 놓고 생산 과정에서script에 놓을 것이다.
    우리는 보기를 렌더링할 때마다 우리가 처한 환경을 검사하고 싶지 않다.따라서, 우리는 resources/views/devserver/ 문장 혼란 코드를 사용하지 않고 resources/views/ 에서 보기 if 설정을 변경할 것입니다.
    이렇게 하면 개발 과정에서 Laravel은 내부 보기paths를 먼저 찾고 그곳에서 보기를 찾지 못할 때만 볼 수 있다configs/view.php.
    // config/view.php
    
        'paths' => (env('APP_ENV', 'production') === 'local')
            ? [
                resource_path('views/devserver'),
                resource_path('views')
            ]
            : [
                resource_path('views')
            ],
    
    저희도 개발 보기를 저희 저장소에 제출하고 싶지 않으니 resources/views/devserver/ 파일에 경로를 추가하십시오.
    # .gitignore
    /resources/views/devserver
    
    우리의 자산에 관해서 우리는 resources/views/에 투매할 것이다.그러나 개발 과정에서 Webpack DevServer는 메모리에서 직접 서비스를 제공합니다.

    Vue CLI 올바르게 구성
    Vue CLI 구성이 필요합니다.나는 그것을 상세하게 평론했다.
    const path = require('path')
    
    let environmentViewsDirectory = ''
    let outputDir = 'dist/'
    
    /**
     * This is a precaution
     * In case we accidentally write dev-server files to disk,
     * we're not going to mess with our production ready dist folder
     */
    if (process.env.NODE_ENV === 'development') {
      environmentViewsDirectory = 'devserver/'
      outputDir = 'dist-devserver/'
    }
    
    /**
     * A helper function to create Vue CLI page entries
     * @param {string} name The name of the JavaScript entry point for the page
     * @param {string} outputPath The path to the resulting HTML Blade file without the extension
     * @param {string} template An optional template file to be used as base for the Blade view
     * @returns 
     */
    const page = (name, outputPath, template) => {
      return {
        [name]: {
          entry: `src/${name}.js`,
          filename: path.resolve(__dirname, `views/${environmentViewsDirectory}${outputPath}.blade.php`),
          template: template || 'src/template.blade.php'
        }
      }
    }
    
    module.exports = {
      /**
       * If you're not aiming for a SPA
       * You can add as many pages here as you want
       * as long as you create an entry .js file at resources/src/
       * You can also use this to create a separate template for an admin endpoint or any other endpoint you need
       */
      pages: {
        ...page('main', 'app'),
        // ...page('contact', 'contact'),
        // ...page('admin', `admin`),
      },
      // Where to dump resulting files
      outputDir: `../public/${outputDir}`,
      // The URL from which assets will be served
      // AND WHICH will be used by injected assets inside the HTML
      publicPath: process.env.VUE_APP_ASSET_URL,
      css: {
        extract: (process.env.NODE_ENV === 'development')
          ? {
            filename: 'css/[name].css'
          }
          : true
      },
      devServer: {
        // Public needs to be explicitly set since we're not using the defaults
        public: process.env.VUE_APP_ASSET_URL,
        // During development, we want to write ONLY the HTML files to the disk
        // This is needed because Laravel won't be able to read the view directly from memory
        // But we want our .js and .css assets to still be served directly from memory
        // So, we're writing to disk ONLY if the output file is at views/devserver/
        writeToDisk: (filePath) => {
          return /views\/devserver\//.test(filePath);
        },
        // Allows you to point any host to the devserver port.
        // Eg.: http://assets.localhost:8080 will also work
        // Alternatively you could use the "allowedHosts" option
        disableHostCheck: true,
        // Avoid CORS issues
        headers: {
          "Access-Control-Allow-Origin": "*",
          "Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, PATCH, OPTIONS",
          "Access-Control-Allow-Headers": "X-Requested-With, content-type, Authorization"
        }
      }
    }
    
    

    중요 프롬프트: 프로세스.환경VUE 어플리케이션 자산 URL.gitignorepublic/dist/process.env.VUE_APP_ASSET_URL로 설정됩니다.resources/.env.local에서 resources/.env.production는 DevServer 호스트여야 합니다(뒤에 있는 슬래시를 잊지 마십시오).
    파일을 만듭니다.
    nano resources/.env.local
    nano resources/.env.production
    
    # resources/.env.local
    VUE_APP_ASSET_URL=http://localhost:8080/
    
    resources/.env.local 상황에 따라 정한다.일반적으로 생산 환경에서 나는 루트 지향VUE_APP_ASSET_URL의 자역을 설치한다.이렇게 하면 나는 그것의 모든 내용을 쉽게 캐시할 수 있다.
    이 경우 resources/.env.production는 하위 도메인에 불과합니다.그렇지 않으면 주소 끝에 추가해야 합니다 public/dist/.
    # resources/.env.production
    
    # subdomain pointing to public/dist/
    VUE_APP_ASSET_URL=https://assets.mywebapp.com/
    
    # same domain
    VUE_APP_ASSET_URL=http://www.mywebapp.com/dist/
    
    이제 VUE_APP_ASSET_URL 폴더에서 dist/를 실행할 수 있습니다.
    cd resources
    npm run serve
    

    경로
    이제 라우팅을 수행할 수 있는 두 가지 방법이 있습니다.

    방법1
    각 페이지에 대해 별도의 보기 파일을 생성합니다(npm run serveresources 속성의 주석 참조).이것은 새 페이지를 만들 때마다 resources/vue.config.js에 새 항목pages 파일(예를 들어 .js을 추가하고 주석resources/src/에 추가해야 한다는 것을 의미한다.이 예에서는 Laravel과 같은 보기만 되돌려줍니다.
    // routes/web.php
    
    Route::get('/', function () {
        return view('app');
    });
    
    // Route::get('/contact', function () {
    //    return view('mybladefile');
    // });
    

    방법2(권장)
    요청마다 같은 보기를 사용하고, 페이지 키에 따라 클라이언트에 어떤 구성 요소를 불러올지 결정합니다.나는 이런 방법을 더욱 좋아하지만, 코드가 정상적으로 작동하기 위해서는 약간의 작업이 필요하다.이것은 현재 페이지에 필요하지 않은 구성 요소를 불러오는 것을 피하기 위해서입니다.
    페이지 구성 요소의 전용 폴더를 만듭니다.
    mkdir resources/src/pages
    
    resources/src/mypageentry.js 페이지를 만듭니다.
    // resources/src/pages/Home.vue
    
    <template>
      <div class="home">
        <h1>Hello from Home component</h1>
      </div>
    </template>
    
    비밀번호를 변경합니다...page('mypageentry', 'mybladefile').
    // resources/src/App.vue
    
    <template>
      <div id="app">
        <Page />
      </div>
    </template>
    
    <script>
    export default {
      name: 'App',
      components: {
        Page: () => import('@/pages/' + window.app.page.component + '.vue')
      }
    }
    </script>
    
    보시다시피, 우리는 현재 Home.vue 대상에 연결된 전역 대상을 통해 보여야 할 페이지를 가져옵니다.이렇게 하려면 다음을 App.vue에 추가합니다.
    <head>
      <!-- ... -->
      <script>
        window.app = @json($jsapp)
      </script>  
    </head>
    
    그런 다음 경로를 통해 데이터를 전달합니다.
    // routes/web.php
    
    Route::get('/', function () {
        return view('app', [
            'jsapp' => [
                'page' => [
                    'component' => 'Home'
                ]
            ]
        ]);
    });
    

    이거 좀 써...사탕 좀 주시겠어요?
    물론, 우리는 보기를 렌더링할 때마다 모든 그룹을 통과하지 않습니다.우리는 트로그로티 사람이 아니야!
    이 작업을 간소화하기 위해 보기 매크로를 만듭니다.
    // app/Providers/AppServiceProvider.php
    
    public function boot()
    {
        View::macro('vue', function ($component, $data = []) {
            return view('app', [
                'jsapp' => [
                    'page' => [
                        'component' => $component,
                        'data' => $data
                    ]
                ]
            ]);
        });
    }
    
    그리고 우리는 이렇게 할 수 있다.
    // routes/web.php
    
    Route::get('/', function () {
        return View::vue('Home'); // Cool, huh?
    });
    

    하지만...서버 데이터를 Vue 구성 요소에 어떻게 전달합니까?
    서버 쪽 섹션이 완료되었습니다.우리의 window 매크로는 두 번째 매개 변수로 데이터 그룹을 받아들인다.
    전역mixin을 사용하여 모든 구성 요소가 이 데이터에 쉽게 접근할 수 있도록 합니다. (더 좋은 방법이 있다면 계속하십시오.)
    // resources/src/main.js
    
    Vue.mixin({
        data () {
          return {
            page: window.app.page.data
          }
        }
    })
    
    new Vue({
      render: h => h(App)
    }).$mount('#app')
    
    이제 경로에서 몇 가지 데이터를 전달합니다.
    // routes/web.php
    
    Route::get('/', function () {
        return View::vue('Home', [
            'title' => 'Imaginations from the server side!!'
        ]);
    });
    
    이제 어셈블리에서 제목을 간단하게 사용할 수 있습니다.
    // resources/scr/components/Home.vue
    
    <template>
      <div class="home">
        <h1>{{ page.title }}</h1>
      </div>
    </template>
    
    이거 너무 좋지 않아요?PHP 서버와 Vue 사이의 한계를 뛰어넘었습니다.js 모듈 세계!

    물요법은요?
    우리가 본 두 번째 루트 방법은 Inertia.js에서 사용하는 메커니즘이다. 이것은 Laravel과 Vue를 사용하여 SPA를 만드는 가장 좋은 방법이다.js.스포일러 힌트: 만약 당신이 이 글을 따른다면 90퍼센트의 일을 완성했을 것이다. 당신이 이곳에서 한 모든 것은 그곳에서 사용할 것이다.사실 본고의 경로 부분의 모든 내용은 필요 없다.나는 네가 더욱 진일보할 것을 강력히 건의한다.관성js 너무 좋아요.

    환매 조항
    나는 이미 너를 위해 GitHub repo with all of this work done 복제판을 만들어서 네가 자신의 작품을 볼 수 있도록 했다.

    DON'T FORGET TO CREATE YOUR resources/.env.local FILE AND SET THE VUE_APP_ASSET_URL ENVIRONMENT VARIABLE



    결론
    보시다시피 Laravel을 Vue CLI 응용 프로그램의 간단한 API 백엔드로 사용하는 것은 Vue가 있는 응용 프로그램을 얻을 수 있는 유일한 방법이 아닙니다.js 기반 전단.평소와 같이 라벨의 모든 라우팅 기능과 다른 훌륭한 기능을 사용할 수 있으며, 단지 Vue를 사용하면 된다.js의 취지는 프로그램의 시각층을 사용하는 것입니다.그리고 만약 당신이 모두 수욕에 관한 것이라면 한 걸음 더 걸어갈 수 있다.
    누구에게나 도움이 되었으면 좋겠습니다.건배!

    좋은 웹페이지 즐겨찾기