11
17

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

レガシィシステムでVueとPHPの連携を考える

Last updated at Posted at 2018-07-17

※考察なので無駄に長いです。

結論から書くと**SystemJS**がベストかな。

ヾ(・ω<)ノ" 三三三● ⅱⅲ コロコロ♪


------------------- ↓ 余談はここから ↓-------------------

Angularが出たときは、酷ぇ物が流行ってるなぁと思い、
Reactが出たときは、思想は素晴らしいけど使い物にならないなぁと思い、
webpackやらBabelやらバッチやモジュールにあふれる世界をみると、
近寄りたくねぇと思っていた。

半年も経てばシステム丸っと過去のものになるJavascript界隈ですが、
ようやく使えそうなフレームワークに出会った。
それが**Vuejs**。
これもVer1の頃は様子見でVer2になってから触り始め、
最近漸くVuejsを仕事で扱う機会があったという感じ。

Vuejsには単一ファイルコンポーネント(Single File Component, SFC)という<template>, <script>, <style>を一つのファイルとして管理する仕組みがある。
単純にPHPでSFCを出力して、
Vuejs側で動的に取り込めばいいじゃん(lazy loadというらしい)と思ったが、
そう簡単にはいかないようだ。
JSの人たちの、バッチでどうにかしときゃええやろ精神はどうにかならんもんかな。

さて、PHP5.2にPHPUnitを入れる、
なんて需要のない記事を書いていることからわかるように、
仕事で古いシステムを扱うことが多い。

それにReactやAngularのような最近のJavaScriptフレームワークを組み込もうにも

  • Nodejsサーバが立てられない
  • JavaScriptのソース管理やデプロイが確立していない
  • PHP V8Jsが使えない

なんてざら。
こんな状態で組み込みなんてできるのかどうか。
その辺を模索してみる。
思想的には以下のような感じ。

  • PHPはSFC単位で出力
  • JSをSFCを動的に呼び出し
  • 事前バッチはなるべくなくす(必須ではない)

------------------- ↓ 本題はここから ↓-------------------

HTML Imports

Google提案で、HTMLを分割管理できる機能。
WebComponents四人衆で一番期待していた。
Mozillaがすっかり老害化したおかげで風前の灯火となった。

Firefox での Web Components のサポート状況
https://developer.mozilla.org/ja/docs/Web/Web_Components/Status_in_Firefox

(ES Modulesで同じことできるとかぬかしおって。できねーっての)
とはいえ、polymerを駆使すればちゃんと動作する。

HTML Importsサンプルコード
index.html
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>VueJS Component Test</title>
  <script src="https://unpkg.com/vue"></script>
  <script defer src="https://unpkg.com/@webcomponents/webcomponentsjs@1/webcomponents-loader.js"></script>
</head>

<body>
  <link rel="import" href="./src/example.vue">
  <div id="wrapper">
    <my-component></my-component>
  </div>
</body>
<script>
  window.addEventListener('WebComponentsReady', function (e) {
    var app = new Vue({
      el: '#wrapper',
    });
  });
</script>

</html>
src/example.vue
<template>
  <div @click="changeName()">
    Hello, {{name}}.
  </div>
</template>

<script>
var doc = document.currentScript.ownerDocument;
var template = doc.querySelector("template");

Vue.component("my-component", {
  template,
  data() {
    return {
      name: "world"
    };
  },
  methods: {
    changeName() {
      this.name = "foobar";
    }
  }
});
</script>

<style lang="less" scoped>
div {
  font-weight: bold;
  color: red;
}
</style>

サンプルソースはここ。
https://github.com/dohzoh/vue-example-htmlimport/tree/master/html-import

RequireJS

動的にJSをロードするということで真っ先に思いつく[RequireJS]。
最古参のシステムでJQueryUnderScoreの頃は本当にお世話になった。
RequireJSの[Vuejs]プラグインにrequire-vuejsがあるのでそれを使う。

サンプルだが、HTMLImportsの時とは全体的に異なるので注意。

requirejsサンプルコード
index.html
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>VueJS Component Test</title>
  <script src="https://unpkg.com/requirejs/require.js"></script>
</head>

<body>
  <div id="wrapper">
    <my-component></my-component>
  </div>
</body>
<script>
  require.config({
    paths: {
      'Vue': 'https://unpkg.com/vue/dist/vue',
      'vue': 'https://unpkg.com/require-vuejs/dist/require-vuejs',
    },
  });
  require(['Vue', 'vue!src/example.vue'],(Vue, App) => {
    var app = new Vue({
      el: '#wrapper',
      components:{
        myComponent: App,
      },
    });
  });
</script>

</html>
src/example.vue
<template>
  <div @click="changeName()">
    Hello, {{name}}.
  </div>

  <style>
    div {
      font-weight: bold;
      color: red;
    }
  </style>  
</template>

<script>
define(['Vue'], (Vue) =>{
  return Vue.extend({
    template: template,
    data() {
      return {
        name: "world"
      };
    },
    methods: {
      changeName() {
        this.name = "foobar";
      }
    }
  });
});
</script>

サンプルソースはここ。
https://github.com/dohzoh/vue-example-htmlimport/tree/master/requirejs/

SystemJS

Angularでも使われているRequireJS互換のモジュールローダー。
公式のsystemjs-plugin-vueはコマンドライン用なので今回は使わず、
マスクライブラリであるgetlibsを使う。
(この名前はどうなんだろうなぁ。)

SystemJS サンプルコード
index.html
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>VueJS Component Test</title>
  <script src="https://unpkg.com/getlibs"></script>
</head>

<body>
  <div id="wrapper">
    <my-component></my-component>
  </div>
</body>
<script>
  SystemJS.config({
    map: {
      'Vue': 'https://unpkg.com/vue/',
    }
  });

  Promise.all([
    System.import("Vue"),
    System.import("./src/example.vue"),
  ]).then(([Vue, App]) => { 
    var app = new Vue({
      el: '#wrapper',
      components: {
        myComponent: App,
      },
    });
  });
</script>
</html>
src/example.vue
<template>
  <div @click="changeName()">
    Hello, {{name}}.
  </div>
</template>

<script>
export default {
  data() {
    return {
      name: "world"
    };
  },
  methods: {
    changeName() {
      this.name = "foobar";
    }
  }
};
</script>

<style lang="less" scoped>
div {
  font-weight: bold;
  color: red;
}
</style>

サンプルソースはここ。
https://github.com/dohzoh/vue-example-htmlimport/tree/master/systemjs

独自実装系

<template>, <script>, <style>を独自に分解して各モジュールをロードする。

http-vue-loader

以下の記事をご覧ください。

Nodeがなくてもvueファイルを使いたい
https://qiita.com/horikeso/items/d2f00c39e8571f3ff310

その他、独自実装系

ほかにもいくつかあるが列挙だけしておく。

ES Modules

scriptタグのtype属性にmoduleと記述し、
import記法を有効にしたもの。
上記HTML Importsが消える原因。

https://vuejsdevelopers.com/2017/09/24/vue-js-single-file-javascript-components/
https://jakearchibald.com/2017/es-modules-in-browsers/
https://developers.google.com/web/updates/2017/11/dynamic-import

これに関しては事前にコンバートが必要。
rollupjsがおすすめ。

ES Modulesのサンプルはhtml部分だけ載せておく。
リンク先にJSもあるので、
そちらを参照のこと。

ES Modulesサンプルコード
index.html
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>VueJS Component Test</title>
  <script src="https://unpkg.com/vue"></script>
</head>

<body>
  <div id="wrapper">
    <my-component></my-component>
  </div>
</body>
<script type="module">
    import App from "./src/example.js";

    var app = new Vue({
      el: '#wrapper',
      components: {
        myComponent: App,
      },
    });
</script>
</html>

サンプルソースはここ。
https://github.com/dohzoh/vue-example-htmlimport/tree/master/es-modules/

考察

あえて、ESModulesを使う理由はない。
予め置換しておく必要がある上に、
IE対応が微妙なので論外だ。(Mozilla〇ね)
ならば、Webpack系列でファイル1枚にするのと大して変わらん。

独自実装系はやんちゃにFunction関数(要するにeval)を使っているので、
個人用途に限られるだろう。

HTML ImportsはVueとの相性は抜群だった。
ただ、残念ながら今後ブラウザでサポートされることはない。
polymerを一生抱えるシステムを創るとなるとリスクは高いか。
インポートの度にlinkタグを生成するとなると取り回しもちょっと悪い。

となると、RequireJSSystemJSという寂しい選択肢になったが、
こちらはお好みでという感じかなと思う。
ただ、vueファイルがAMD記法(define)であるRequireJSより、
ES6記法(export default)が使えるSystemJSの方が、
将来的なシステム取り回しにも対応できるだろう。


------------------- ↓ 後書はここから ↓-------------------

JavaScript界隈の人たちは同じところをぐるぐる回るのがお好きなようで、
最近の話題がSSR(サーバーサイドレンダリング)だそうだ。
サーバーサイドはRestAPIだけ作っとけばいいとさんざん言ってきた連中が、
SSRとか言ってんだから失笑ものだわな。

ここまでやって、HyperAppなるものがあることを知った。
また1から調査かな。

11
17
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
17

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?