昨天提到了後端與前端的混和( Hybrid )模式,我們今天就會提出比較完整的例子,來說明一下我自己目前比較喜歡的方式。由於 Phalcon 實在有點冷門,所以我今天會用一個更冷門的 Slim PHP Framework 來介紹( 你是故意的嗎 )。
對了,今天也會有 Docker 會分享給各位,方便大家不用處理環境問題。
後端的設計
我們昨天有提到後端的作法,今天我們來實作一些關於後端的操作方式。首先,我們需要準備一些需要的工具:
- PHP 7.3 with PHP-FPM
- Nginx
- Slim PHP Framework
我們這邊用 PHP 來舉例,所以倘若你不是使用 PHP 的話,你要換成其他的後端語言也是可以。昨天我們有說了,後端也是需要一些 Router 來接收前端來的狀況,所以,對於路由的部分,我們還是需要做設定。
<?php
use DI\Container;
use Middlewares\TrailingSlash;
use Slim\Factory\AppFactory;
use Slim\Views\Twig;
use Slim\Views\TwigMiddleware;
require __DIR__ . '/vendor/autoload.php';
// Create Container using PHP-DI
$container = new Container();
AppFactory::setContainer($container);
$container->set('view', function () {
return new Twig(__DIR__ . '/view');
});
// Set container to create App with on AppFactory
$app = AppFactory::create();
$app->addRoutingMiddleware();
// Add Twig-View Middleware
$app->add(TwigMiddleware::createFromContainer($app));
// Add trailing slash
$app->add(new TrailingSlash());
// Add two routes
$app->get('/', \Ithomeironman2019\Controller\HomeController::class . ':index');
$app->get('/hello', \Ithomeironman2019\Controller\HomeController::class . ':hello');
// Run application
$app->run();
我們就簡單設定兩組路由就好了,然後我們是交給 HomeController
來做,這個地方就跟昨天說的一樣,你可以準備 TDK, JSON-LD 與要交給前端的資料。至於 API 什麼的我這邊就不額外在提,資料來源我不多做著墨,就直接使用固定資料來當作範例。
<?php
namespace Ithomeironman2019\Controller;
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
use Psr\Container\ContainerInterface;
class HomeController
{
protected $container;
protected $view;
protected $templateData = [];
// constructor receives container instance
public function __construct(ContainerInterface $container)
{
$this->container = $container;
$this->view = $container->get('view');
}
public function index(Request $request, Response $response, $args)
{
return $this->view->render($response, 'index.twig', $this->templateData);
}
public function contact(Request $request, Response $response, $args)
{
return $this->view->render($response, 'hello.twig', $this->templateData);
}
}
前端的設計
前端的部分,其實就是把 Vue 拆開來,然後改一下設定。不過,老實說 Vue CLI 3.0 之後,設定改了一狗票,如果要回頭搭配 Webpack 的話,其實很麻煩。但是,原先的 3.0 的 vue-cli-service
運作方式,個人覺得挺難用的。
然後,你其實可以用 Vue CLI 來把跟 Webpack 相關的資料輸出:
vue inspect > webpack.txt
這樣你就可以拿到跟 Webpack 有關的設定,然後你想要用那個部分,就從這邊把他拿出去用。不過多少還是會遇到一點問題,
"Cannot assign to read only property 'exports' of object '#<Object>'"
Cannot assign to read only property 'exports' of object '#<Object>'
Local NPM Module causes "Cannot assign to read only property 'exports' of object"
然後呢,我還是建議你們使用 concurrently
或是 gulp-shell
的方式,來把前後端的 Watch 接起來,因為 Webpack 要套到 Vue CLI 3.0 還要能正常運作,實在有點太浪費時間。我大概花了 20 個小時卡在套件相依,然後卡在 ES5, ES6, Webpack, Vue CLI 使用 JavaScript 的版本衝突,各種 module 操作衝突等等。
真心覺得累。
其實這樣就好了:
"serve": "concurrently \"gulp\" \"vue-cli-service build --watch\""
上面大概就是開發模式跑起來的狀況,底下是監看整個 PHP/Vue 的部分,左上角是簡單的啟動一個 Web Server 的服務,右上角是目前資料夾。主要的開發還是以 Vue CLI 3.0 為主。
混合模式
上述就是簡單的混合模式的基本架構。最後我們在 build
的時候,他會統一建立到 dist
底下,大概會類似這個樣子:
然後你只要把 dist
部屬到遠端,然後把 Nginx/Apache 指向 public/index.php
就好了。剩下的大概就是 TDK, JSON-LD 由後端幫你出,然後前端由 Vue 那邊幫你產生。
以上是最終執行結果。由於我在整理 Docker 耗費太多時間,今天的文章實在沒有心力交代太多過程。就容許我先這樣子結束這一回合吧。
小結
那個說好的 醬汁 Dockfile 嘛,由於我還沒調整好,所以我應該明天在給大家(哈哈哈哈)。