JavaScript
jQuery
laravel
w2ui
Laravel-Mix

Laravel Mixでw2uiを良い感じに扱う(CommonJSに対応していないライブラリを扱う)

前書き

w2uiというjQueryのUIプラグインを、Laravel Mixを使って管理しようとしたのですが、苦労したので残しておきます。w2ui以外にも、CommonJSに対応していないライブラリを使う時に応用が効くと思います。

Mixを使う事により、npm管理したり、モジュール化されたり、jsをまとめたり、まとまったjsのキャッシュをコントロールしたりできます。

Laravel Mixの概要についてはこちら。基本的なセットアップは済んでいるものとして説明します。
アセットのコンパイル(Laravel Mix) 5.4 Laravel

w2uiについてはこちらを参照してください。
100万行扱えるグリッドw2ui GridとHandsontableの紹介 - Qiita

環境

MacVagrant上で構築したCentOS
Laravel5.4(5.4で検証しましたが、他のバージョンでも同じように使えると思います)
yarn(互換性があるのでnpmでも同じになるはずです)
(yarnとnpmコマンドの互換はこちら yarnを使ってみた - Qiita

バージョンの罠

まず、w2uiのバージョンについて説明する必要があります。
公式ページ(Home | JavaScript UI - w2ui) からDownloadしたり、GitHubのmasterを参照すると1.5.rc1が、npmから取得するとstableな1.4が取得されます。

Laravel mixはwebpackをラップしており、CommonJSに対応していればrequireするだけで簡単に動きます。
が、1.4系はCommonJSに対応していないため、単純にrequireしても動きません。
逆に1.5系はnpmに登録されていません。

というわけで、作戦としては2つ考えられます

  1. npmから取得した1.4系を頑張ってCommonJS対応して使う
  2. 1.5系をダウンロードするなり、url参照するなりする

最終的に作戦2を採用しましたが(実処理が1.5に依存していたため)、途中までこの事実に気が付かずに作戦1も検証していました。というわけで、作戦1についてもいけた所までは公開しておきます。

手順 作戦1.npmから取得した1.4系を頑張ってCommonJS対応して使う

packageの取得

yarn add w2ui

w2ui使う処理

$(window).on('load', function() {
    w2utils.locale('ja-jp.json');

    $('#grid').w2grid({
        name: 'grid',
        recid:'id',
        method: 'GET',
// 省略
    });
    w2ui['grid'].load('hogeAction');

色々機能があるのですが、今回はこんな感じの処理にしていました。
w2tilsw2uiというグローバルな変数がある前提の処理になっています。

app.jsへの組み込み

    var w2uiModule = require('exports-loader?w2ui,w2utils,w2obj!w2ui');
    window.w2utils = w2uiModule["w2utils"];
    window.w2ui = w2uiModule["w2ui"];
    window.w2obj = w2uiModule["w2obj"];

前述の通り、w2tilsw2uiというグローバルな変数がある事にしないといけません。
1.4系はCommonJSに対応していない(exports記述が無い)ので、var w2uiModule = require('w2ui');としてもw2uiModuleは空objectです。

そこで、exports-loaderという特殊なloaderを指定し、取得したい値を指定する事で、w2uiモジュールの値を外部に取り出す事が可能です。exports-loaderはyarn(npm)で取得しておく必要があります。
LaravelMixは内部的にwebpackを使っているため、こういった便利なwebpackの機能を使う事ができます。loaderについてはこちらを参考にしました。
webpackを使い倒す - Thujikun blog

また、似たようなissueもあがっていたので、同じく参考にしました。
Compatibility with browserify · Issue #712 · vitmalina/w2ui

手順 作戦2 1.5系をダウンロードするなり、url参照するなりする

packageの取得

扱うファイルを固定にしたかったので(本体が更新されても影響しない)、公式ページからダウンロードして、resouces/assets/jsにjsファイルを、resouces/assets/sassにcssファイルを直接配置します。

w2ui使う処理

作戦1と同じ

app.jsへの組み込み

    var w2uiModule = require('./w2ui.min.js');
    window.w2utils = w2uiModule["w2utils"];
    window.w2ui = w2uiModule["w2ui"];

今度は単純にrequireで取得できます。
以下のような処理がw2uiに記述されていて、CommonJSに対応しているからです。

(function(global, w2ui) {
    if (typeof define=='function' && define.amd) {
        return define(function(){ return w2ui; });
    }
    if (typeof exports!='undefined') {
        if (typeof module!='undefined' && module.exports)
            return exports = module.exports = w2ui;
        global = exports;
    }
    for (var m in w2ui) {
        global[m] = w2ui[m];
    }
})(this, { w2ui: w2ui, w2obj: w2obj, w2utils: w2utils });

app.cssへの組み込み

app.scssに

@import "w2ui.min.css";

と書けばapp.cssにコンパイルされます。

まとめ

webpackの便利機能を使って、CommonJSに対応していないライブラリを頑張って対応する事もできました。(最終的には作戦2を採用したのですが)

LaravelMixのドキュメントや使用事例はまだ少ないのですが、困った時はwebpackを調査する事で色々対応が可能そうです。