最近、jsでrequireが無いと生きれない身体になってしまいました。
CoffeeScriptから卒業して、ES6でコードを書くようにもしています。ES6のClass構文とかアロー関数が無いと人生辛くなってきました。
そんなわけで自分はbrowserifyを使ってコードを書いてます。requireを良い感じにコンパイルして1つのファイルにまとめてくれる奴です。
そんなときに結構困るのがwp_head()
や、wp_footer()
からscriptタグでjQuery、underscore.js、Backbone.js等の有名処のライブラリが出力される場合があることです。
functions.phpで無理矢理消しても良いのですがそれは筋が悪そうなので、browserify-shimを使って指定されたライブラリはグローバル変数のものを使うようにします。
そのコードがこんな感じ。
gist: https://gist.github.com/torounit/0da591b62d03187b4641
package.json
{
"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
'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']);
タスク
$ gulp browserify //コンパイル
$ gulp watchify //ファイルの変更を監視して自動コンパイル
といった格好になります。
browserify-shim
browserifyには、transformというAPIがありまして、ここにプラグインを突っ込むことが出来ます。
アプリケーションコード上のJSから呼び出せるのは通常、node_modulesにインストールされているものか、ファイル名で指定されたJSのみですが、require(‘jquery’) のようなコードを書いたときに、node_modulesではなく、グローバル変数のjQueryを呼んでくることが出来るようになります。
package.jsonにbrowserify-shimという項目を作ってこんな感じで指定すれば動作します。
{
"browserify-shim": {
"jquery": "global:jQuery",
"underscore": "global:_",
"backbone": "global:Backbone"
}
}
debowerify
debowerifyは、bowerでインストールしたライブラリをrequireやimportできるようにするプラグインです。
最近オワコンと言われているbowerですが、jQueryプラグインなどをnpmでインストールして持ってくると、そこからnode_modules内のjqueryを取ってきてしまうと言う問題があります。shimの方の設定が悪いのかどうなのか解らないのですが、そんなわけでその手のものは仕方ないのでbowerで持ってきてrequire(import)します。
npmだけで管理はしたいのでどうにかしたいところです。最悪、jQueryプラグインも普通にscriptタグで読み込ませるコトもたまにやります。
まとめ
とりあえずこれで、ライブラリの多重インストールを避けつつインストールが出来ます。後はテーマ側で
$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とかBackbone.jsバージョンが古い問題とかもあるんですけどね。。。