# WordPress等のCMSがjQuery等を出力するとき、browserifyで上手いことやる。

- リンク: https://torounit.com/blog/wordpress%e7%ad%89%e3%81%aecms%e3%81%8cjquery%e7%ad%89%e3%82%92%e5%87%ba%e5%8a%9b%e3%81%99%e3%82%8b%e3%81%a8%e3%81%8d%e3%80%81browserify%e3%81%a7%e4%b8%8a%e6%89%8b%e3%81%84%e3%81%93%e3%81%a8%e3%82%84/
- 公開日: 2015-07-29T19:05:11+09:00
- 作成者: Toro\_Unit

最近、jsでrequireが無いと生きれない身体になってしまいました。

CoffeeScriptから卒業して、ES6でコードを書くようにもしています。ES6のClass構文とか
アロー関数が無いと人生辛くなってきました。

そんなわけで自分は[browserify](http://browserify.org/)を使ってコードを書いてます。
requireを良い感じにコンパイルして1つのファイルにまとめてくれる奴です。

そんなときに結構困るのが`wp_head()`や、`wp_footer()`からscriptタグで[jQuery](https://jquery.com/)、
[underscore.js](http://underscorejs.org/)、[Backbone.js](http://Backbone.js)等の
有名処のライブラリが出力される場合があることです。

functions.phpで無理矢理消しても良いのですがそれは筋が悪そうなので、browserify-shim
を使って指定されたライブラリはグローバル変数のものを使うようにします。

そのコードがこんな感じ。

[gist: https://gist.github.com/torounit/0da591b62d03187b4641](https://gist.github.com/torounit/0da591b62d03187b4641)

#### package.json

    ```decode:true
    {
      "browserify-shim": {
        "jquery": "global:jQuery",
        "underscore": "global:_",
        "backbone": "global:Backbone"
      },
      "devDependencies": {
        "babelify": "^6.1.3",
        "browserify": "^11.0.0",
        "browserify-shim": "^3.8.10",
        "debowerify": "^1.3.1",
        "gulp": "^3.9.0",
        "gulp-notify": "^2.2.0",
        "vinyl-buffer": "^1.0.0",
        "vinyl-source-stream": "^1.1.0",
        "watchify": "^3.3.0"
      },
      "scripts": {
        "test": "echo \"Error: no test specified\" && exit 1"
      },
      "author": "Toro_Unit",
      "license": "ISC"
    }
    ```

#### gulpfile.js

    ```decode:true
    'use strict';

    // ==================================
    //
    // Config.
    //
    // ==================================

    var config = {
        browserify: {
            bundleOption: {
                cache: {}, packageCache: {}, fullPaths: false, //for watchfy.
                debug: true,
                entries: './src/scripts/app.js',
                extensions: ['js', 'jsx'],
            },
            dest: './dist/scripts/',
            filename: 'app.js'

        }
    }

    // ==================================
    //
    // Load modules.
    //
    // ==================================

    var source = require('vinyl-source-stream');
    var browserify = require('browserify');
    var watchify = require('watchify');
    var gulp = require('gulp');
    var notify = require("gulp-notify");

    var handleErrors = function() {
        var args = Array.prototype.slice.call(arguments);
        notify.onError({
            title: "Compile Error",
            message: "<%= error.message %>"
        }).apply(this, args);
        this.emit('end');
    };

    // ==================================
    //
    // Compile JavaScripts.
    //
    // ==================================

    gulp.task('setWatch', function () {
        global.isWatching = true;
    });

    gulp.task('browserify', function () {

        var b = browserify(config.browserify.bundleOption)
            .transform('babelify')
            .transform("browserify-shim")
            .transform("debowerify");

        var bundle = function () {
            b.bundle().on('error', handleErrors)
                .pipe(source(config.browserify.filename))
                .pipe(gulp.dest(config.browserify.dest));
        };
        if (global.isWatching) {
            var bundler = watchify(b);
            bundler.on('update', bundle);
        }
        bundle();
    });

    gulp.task('watchify', ['setWatch', 'browserify']);
    ```

#### タスク

    ```decode:true
    $ gulp browserify //コンパイル
    $ gulp watchify //ファイルの変更を監視して自動コンパイル
    ```

といった格好になります。

## browserify-shim

browserifyには、transformというAPIがありまして、ここにプラグインを突っ込むことが
出来ます。

アプリケーションコード上のJSから呼び出せるのは通常、node_modulesにインストールさ
れているものか、ファイル名で指定されたJSのみですが、require(‘jquery’) のようなコード
を書いたときに、node_modulesではなく、グローバル変数のjQueryを呼んでくることが出来る
ようになります。

package.jsonにbrowserify-shimという項目を作ってこんな感じで指定すれば動作します。

    ```decode:true
    {
      "browserify-shim": {
        "jquery": "global:jQuery",
        "underscore": "global:_",
        "backbone": "global:Backbone"
      }
    }
    ```

## debowerify

debowerifyは、bowerでインストールしたライブラリをrequireやimportできるようにする
プラグインです。

[最近オワコンと言われているbower](http://havelog.ayumusato.com/develop/others/e656-not_using_already_frontend_libraries.html)
ですが、jQueryプラグインなどをnpmでインストールして持ってくると、そこからnode_modules
内のjqueryを取ってきてしまうと言う問題があります。shimの方の設定が悪いのかどうな
のか解らないのですが、そんなわけでその手のものは仕方ないのでbowerで持ってきてrequire(
import)します。

npmだけで管理はしたいのでどうにかしたいところです。最悪、jQueryプラグインも普通に
scriptタグで読み込ませるコトもたまにやります。

 

## まとめ

とりあえずこれで、ライブラリの多重インストールを避けつつインストールが出来ます。
後はテーマ側で

    ```decode:true
    $js_path = get_template_directory_uri() . 'dist/scripts/app.js';
    wp_enqueue_script( 'app', $js_path, array( 'underscore', 'jquery' ), '1.0.0', true );
    ```

とかやればとりあえずは終了です。

まぁ、WordPressの[underscore.js](http://underscorejs.org/)とか[Backbone.js](http://backbonejs.org/)
バージョンが古い問題とかもあるんですけどね。。。

 
