最近、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バージョンが古い問題とかもあるんですけどね。。。