前回のコマンドラインでのnpm installの実行で、larave-mixのパッケージがインストールされました。今回はそれを利用して、実際にユーザーがブラウザを通して直接使用するapp.jsapp.cssを作成します。

関連するディレクトリやファイル

今回関連するファイルは、プロジェクトのディレクトリのあちこちにあります。混乱しないように、フロントエンドのファイルの作成に関わるディレクトリやファイルの説明から始めます。以下は、Laravelのプロジェクトのディレクトリ構造の一部です。今回に関係のないapp/などのディレクトリは含まれていないので注意を。

.
├── node_modules
│   ├── accepts
│   ...    
├── package.json
├── package-lock.json
├── public
│   ├── css
│   │   └── app.css
│   └── js
│       └── app.js
├── resources
│   ├── js
│   │   ├── app.js
│   │   ├── bootstrap.js
│   │   └── components
│   │       └── ExampleComponent.vue
│   ├── sass
│   │   ├── app.scss
│   │   └── _variables.scss
│   └── views
│       ├── auth
│       │   ├── login.blade.php
│       │   ├── passwords
│       │   │   ├── email.blade.php
│       │   │   └── reset.blade.php
│       │   ├── register.blade.php
│       │   └── verify.blade.php
│       ├── home.blade.php
│       ├── layouts
│       │   └── app.blade.php
│       └── welcome.blade.php
└── webpack.mix.js

上において、

node_modules は、コマンドラインでnpm installの実行でダウンロードしたjavascriptのモジュールのファイルを収納するディレクトリです。package.jsonで指定したモジュールだけでなく、それらが依存するモジュールもダウンロードされるので、たくさんのディレクトリやファイルがあります。

package.json は、プロジェクトで使用するjavascriptのモジュールを指定します。先のnode_modulesのディレクトリのファイルはそこで指定するパッケージをもとにダウンロードされたものです。

package-lock.json は、コマンドラインでnpm installを実行したときに作成されます。ダウンロードしたモジュールのバージョン情報も記されるので、プロジェクトのインストール時に同じバージョンのモジュールの使用がそれで可能となります。

public は、ユーザーがブラウザを通して使用するcssやjsファイルを収納するディレクトリです。それらのファイルは、後に説明するnpm runの実行により作成されます。

resources/jsresources/sass は、publicに収納されているファイル(app.jsなど)の作成の元となるファイルを収納します。

resources/views は、もちろんLaravelのコントローラで使用されるbladeのファイルを収納します。

laravel-mixを使用したワークフロー

上のpublicのディレクトリに保存される、app.jsapp.cssファイルの作成には以下の作業工程が必要となります。

1.ソースファイルを編集

resourcesディレクトリにおいて、jsやsassなどのビルドに必要なファイルを編集します。
ここでは、ExampleComponent.vueのvuejsのコンポーネントもソースファイルの1つです。

2.webpack.mix.jsを編集

これは、ビルドの設計図です。laravel-mixが必要とするもので、webpackの実行に使います。
以下は、プロジェクトのディフォルトでインストールされるwebpack.mix.jsの中身ですが、ソースファイルとそれから作成されるファイルの収納場所が記されています。

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

/*
 |--------------------------------------------------------------------------
 | Mix Asset Management
 |--------------------------------------------------------------------------
 |
 | Mix provides a clean, fluent API for defining some Webpack build steps
 | for your Laravel application. By default, we are compiling the Sass
 | file for the application as well as bundling up all the JS files.
 |
 */

mix.js('resources/js/app.js', 'public/js')
    .sass('resources/sass/app.scss', 'public/css');

上はシンプルな設定ですが、sassのファイルをコンパイルしてcssファイルを作成し、jsファイルで使用するモジュールを1つのファイルのバンドルし、バベル化し最小化したり、複雑な作業をたくさん行います。バベル化とは、書いたjsのスクリプトがたとえ次世代のjavascriptの新機能でも、現在のブラウザでも使えるようにするようにトランスパイルすることです。

3.webpackを実行

webpackは、以下のコマンドで実行されます。

開発用には、

$ npm run dev

あるいは、ライブ用のために、

$ npm run prod

を実行してコンパイルします。devprodの実行パラメータは、package.jsonで定義されています。以下の、scriptsのセクションを見てください。

{
    "private": true,
    "scripts": {
        "dev": "npm run development",
        "development": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js",
        "watch": "npm run development -- --watch",
        "watch-poll": "npm run watch -- --watch-poll",
        "hot": "cross-env NODE_ENV=development node_modules/webpack-dev-server/bin/webpack-dev-server.js --inline --hot --config=node_modules/laravel-mix/setup/webpack.config.js",
        "prod": "npm run production",
        "production": "cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js --no-progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js"
    },
...

devは、developmentで、prodは、productionの短縮形ということがわかります。

また、それらのコマンドでは、webpackを実行して、laravel-mixが提供しているwebpack.config.jsの設定ファイルを使用していることもわかります。

laravel-mixのおかげで、複雑なwebpackの作業の設定が、先に掲載したwebpack.mix.jsに見られるようにたったの2行の設定となっています。感激です。

4.bladeファイルの編集

作成された、app.cssやapp.jsは、例えば、以下のようにレイアウトのbladeテンプレートで使用されます。

<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <!-- CSRF Token -->
    <meta name="csrf-token" content="{{ csrf_token() }}">

    <title>{{ config('app.name', 'Laravel') }}</title>

    <!-- Scripts -->
    <script src="{{ asset('js/app.js') }}" defer></script>

    <!-- Fonts -->
    <link rel="dns-prefetch" href="//fonts.gstatic.com">
    <link href="https://fonts.googleapis.com/css?family=Nunito" rel="stylesheet">

    <!-- Styles -->
    <link href="{{ asset('css/app.css') }}" rel="stylesheet">
</head>
<body>
...

以上です。

By khino