読者です 読者をやめる 読者になる 読者になる

tanaka's Programming Memo

プログラミングについてのメモ。

Laravel Elixirでwebpackを使ってCodeSplittingをする

PHP Laravel Webpack

Laravel5.3のElixirからwebpack 1.13.3でビルドして、JavaScriptのコードを分割をする手順です。ページごとに用意する Entry Chunk である「app.js」と「app2.js」をビルドすると同時に、どちらのJavaScriptファイルでも利用するコードを「common.js」という名前のファイルに書き出します。(Laravelがインストールするwebpackは、2.1.0以降の指定でした。2016/11/26追記)

前提

以下の環境での例です。

  • macOS Sierra
  • Laravel5.3
  • npm 3.10.8

プロジェクトの作成

  • 以下で、Laravelのプロジェクトを作成して、プロジェクトフォルダーに入る
laravel new laravel-code-splitting
cd laravel-code-splitting
  • 以下で、laravelのプロジェクトを起動する
php artisan serve

以上で、 http://localhost:8000 をWebブラウザーで開くと、Laravelと表示されるページが動きます。


コードの作成

app.jsはそのまま利用します。このコードは、Vueで example というタグを定義しています。ページ中にそのタグを書くと、メッセージが表示されます。

app2.js用には、 app2 というルートを定義して、app2.blade.php というテンプレートを用意します。app2.jsには、jQueryを使って本文に「app2.jsでここを書き換えました。」と表示するコードを作成します。

app.jsを動かす

wecomeページのテンプレートに example タグを追加します。

  • resources/views/welcome.blade.php をエディターで開く
  • 80行目付近の「<div class="content">」という行を探して、以下のようにid属性を追加する
            <div id="app" class="content">
  • 84行目付近(Laravelと表示しているdivブロックの下)に以下のコードを追加
                <example></example>
  • 最後から2行目の「</body>」の上に、以下のコードを追加
        <script type="text/javascript" src="./js/app.js"></script>

以上ができたら、上書き保存をして、 http://localhost:8000 をリロードします。先ほどのページに「Example Component」「I'm an example component!」と表示が追加されれば成功です。

app2.jsのコードを作成

app2.js用のコードを追加します。まずは、Webページの雛形を作成します。

  • resources/views/app2.blade.php ファイルを新規作成して、エディターで開く
  • 以下のコードを入力して保存
<!DOCTYPE html>
<html lang="ja">
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1">

        <title>Laravel app2</title>

        <!-- Fonts -->
        <link href="https://fonts.googleapis.com/css?family=Raleway:100,600" rel="stylesheet" type="text/css">

        <!-- Styles -->
        <link href="/css/app.css" rel="stylesheet">

    </head>
    <body>
        <div class="container">
            <h1 id="page-body" class="bg-info">
                app2.jsが未作成
            </h1>
        </div>
        <script type="text/javascript" src="./js/common.js"></script>
        <script type="text/javascript" src="./js/app2.js"></script>
    </body>
</html>

app2.jsを作成します。

  • resources/assets/js/app2.js ファイルを新規に作成して、エディターで開く
  • 以下のコードを入力して保存
require('./bootstrap');

$('#page-body').text("app2.jsでここを書き換えました。");

次に、ルートを作成します。

  • routes/web.php をエディターで開く
  • ファイルの最後に以下のコードを追加する
Route::get('/app2', function() {
    return view('app2');
});

以上ができたら、 http://localhost:8000/app2 にアクセスします。「app2.jsが未作成」と表示されればここまで成功です。


webpackの設定

app2.jsが正しく動作すると「app2.jsでここを書き換えました。」とページに表示されるはずです。現在動作しないのは、 public/js フォルダーに app2.js が存在しないからです。 app2.js をwebpackでビルドする設定を作成して、必要なファイルを生成します。

環境の構築

ビルドに利用するツール類をインストールします。

  • ターミナルでプロジェクトフォルダーに移動して、以下を実行
npm install

インストールが完了したら、ターミナルで以下を実行します。

gulp

これでデフォルトの設定でJavaScriptがビルドされます。ビルドされたJavaScriptファイルは public/js フォルダー内に生成されます。まだ初期設定のままなので、 app.js しか生成されません。webpackの設定ファイルを用意して、 app2.js が実行可能なEntry Chunkとしてビルドされるようにします。

設定ファイル webpack.config.js の作成

  • プロジェクトフォルダー直下に webpack.config.js というファイルを作成してエディターで開く
  • 以下のコードを入力して保存
var webpack = require('webpack');

module.exports = {
    entry: {
        app: './resources/assets/js/app',
        app2: './resources/assets/js/app2'
    },
    output: {
        filename: '[name].js'
    },
    plugins: [
        new webpack.optimize.CommonsChunkPlugin({
            names: 'common'
        })
    ]
};

webpack.config.js というファイルに設定を書いておくと、 Elixir が自動的に読み込んで適用してくれます。

上記の設定は、実行するためのコードを持ったChunkである Entry Chunk として app.js と app2.js を作成して、両者に共通のコードは common.js にまとめるというものです。

ターミナルで以下を実行してビルドしてください。

gulp

http://localhost:8000/app2 をリロードすると、「app2.jsでここを書き換えました。」と表示されて、無事に app2.js が動作したことが確認できます。

http://localhost:8000 をリロードしてみてください。先ほどは正しく動作していたのに、 example タグのメッセージが消えてしまいました。これは、app2 との共通部分のコードが common.js に移動してしまったからです。以下の作業をして修正します。

  • resources/views/welcome.blade.php をエディターで開く
  • ファイルの下から3行目にある「<script type="text/」から始まる行の上に、以下の行を追加
        <script type="text/javascript" src="./js/common.js"></script>

以上で保存して、 http://localhost:8000 をリロードすると、正しく動作するようになります。


まとめ

Laravelでページの遷移をするサイトを作成する場合、ページごとに利用するJavaScriptを分けた方がコードが減って便利そうだったので、webpackの Multi Entry Chunk を試してみました。

Laravel5.3のElixirには、最初からwebpackのビルド環境が組み込まれていますので、 npm install で環境をインストールして、 webpack.config.js をプロジェクトフォルダー直下に作成して、設定を書けば webpack の各種機能を利用することができます。

設定ファイルに以下のプラグインの設定を追加したので、 app.js と app2.js の双方に出てくるコードを common.js に分離してくれて、コードの重複が減ります。これができるのが webpack の強みのようです。

    plugins: [
        new webpack.optimize.CommonsChunkPlugin({
            names: 'common'
        })
    ]

JavaScript の読み込みは、まず common.js を読み込んでから、app.js か app2.js を呼び出します。

webpack.config.js が正しく設定できた後は、ターミナルで

gulp watch

を実行すると、コードが変更されるたびに自動的にビルドされるので便利です。