2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

debowerifyとjstifyを同時に適用時したときに発生するエラーの解決法

Last updated at Posted at 2014-09-07

要約

debowerifyを利用している場合は,underscore/Lo-Dash系テンプレートの読み込みにはtemplateifyを使うのがよい.

解決法をGoogleで検索したが,私には見つけられなかったので,私の考えた解決法をここに記述することにした.

状況説明

  • browserifyでフロントエンドのCoffeeScriptをコンパイル
  • サーバーサイドのサードパーティ・ライブラリはnpmで,フロントエンドのサードパーティ・ライブラリをbowerで管理
    • 小さいプロジェクトなので分離せず,1つのプロジェクトとして管理している
    • bower管理下のライブラリの読み込みのため,debowerifyを適用
  • フロントエンドのテンプレートとして,underscore/Lo-Dash系テンプレートを使用
    • そのため,jstifyも適用しようとした

その結果

エラーが発生した...

以下,最小構成での再現手順.

$ cd /path/to/proj
$ npm install bower browerify debowerify jstify
$ node_modules/.bin/bower install underscore
$ echo "var t = require('./t.jst');" > a.js
$ echo -n foobar > t.jst
$ node_modules/.bin/browserify -t debowerify -t jstify a.js
Error: Cannot find module 'underscore' from '/path/to/proj'
    at /path/to/proj/node_modules/browserify/node_modules/resolve/lib/async.js:50:17
    at process (/path/to/proj/node_modules/browserify/node_modules/resolve/lib/async.js:119:43)
    at /path/to/proj/node_modules/browserify/node_modules/resolve/lib/async.js:128:21
    at load (/path/to/proj/node_modules/browserify/node_modules/resolve/lib/async.js:60:43)
    at /path/to/proj/node_modules/browserify/node_modules/resolve/lib/async.js:66:22
    at /path/to/proj/node_modules/browserify/node_modules/resolve/lib/async.js:21:47
    at Object.oncomplete (fs.js:107:15)

ちなみに,echo "var _ = require('underscore');" > a.jsでは問題は発生しない.

原因分析

以下の内容は,browserify/debowerify/jstifyのソースコードをくまなく調べた結果ではないので,誤りが含まれているかもしれない.誤りを見つけた方は,指摘していただけるとありがたい.

まず,jstifyのソースを確認した.変換後のファイルにvar _ = require('underscore');が含まれており,これが見つからなというエラーであることがわかった.

次に,console.logなどでdebowerifyとjstifyの呼び出しログを確認した.

  • transformの適用順番と-tパラメーターによるtransformの指定順番の間には関係はないようだ
    • transformの名前の辞書順で適用しているように見える
    • 今回の場合だと,debowerify jstifyの順番で適用する
  • 1つのファイルに対するtransformは実行前に確定
    • そのため,再適用されないようだ
    • 今回の場合だと,jstify後に再び一連のtransformを適用するということはないようだ

どうにかしてtransformの順番を入れ替えることができれば問題が解決するのではないかと考えたが,transformの先頭で適用対象のファイルを拡張子で選別していることがわかった.

指定したtransformをファイルにすべて適用するみたいなので,当然と言えば当然か.

browserifyの用途から考えて,入力ファイルを改名する機能はなさそうだ.少し調べただけでは見つからない.

では,どうすればいいのか?

解決法1

templateifyを使う.

$ cd /path/to/proj
$ npm install bower browerify debowerify templateify
$ node_modules/.bin/bower install underscore
$ echo "var t = require('underscore').template(require('./t.template'));" > a.js
$ echo -n foobar > t.jst
$ node_modules/.bin/browserify -t debowerify -t templateify a.js

テンプレートファイルの拡張子は.templateとなる点に注意.

解決法2

bowerを使うのをやめて,フロントエンドのサードパーティ・ライブラリの管理にもnpmを使用する.

サーバーとフロントエンドのプロジェクトが分離されているなら,特に管理上の問題もないので,これでもいい気がする.

解決法3

変換を2回に分けてしまう.

  1. テンプレートを変換し,一旦結果をJSファイルに出力
  2. テンプレートのJSファイルをrequireするようにし,これをbrowserifyで変換

ソースファイルに変換後のテンプレートのJSファイル名を書くことになるため,おすすめはできない.

補足

jstify以外のtransform後の結果にrequireを含むようなtransformでは同じ問題が発生する.例えば,browserify-compile-templatesでも同じ問題が発生する.

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?