24
25

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.

require.js の require関数が同期的に動く理由

Last updated at Posted at 2013-04-17

require.jsで、他のモジュールに依存するモジュールを、次の2つのような書き方で定義できる。(他にもある)

define(['a'], function(a){
  // モジュールaがコールバックに渡ってくる
});
define(function(require){
  // モジュールaをロード
  var a = require("a");
})

下の書き方はなんとなく前から知ってたんだけど、クライアント側じゃ仕組み的に無理くね?と思ってたから、勘違いだと思ってた。
しかし下の書き方はできるのであった。同期っぽく読み込める。
a.js は非同期で読み込まれてるはずなのに、aに代入されてる。why?

ソースを覗いてみると。。

...
            if (callback.length) {
                callback
                    .toString()
                    .replace(commentRegExp, '')
                    .replace(cjsRequireRegExp, function (match, dep) {
                        deps.push(dep);
                    });
...

わーお、予めdefineが呼ばれた時点で、中身の関数を1度文字列にして、それを解析して読むべきモジュールを予めロードしていた。

というか、 require.jsのサイトにも書いてありましたね。

This wrapper relies on Function.prototype.toString() to give a useful string value of the function contents. This does not work on some devices like the PS3 and some older Opera mobile browsers. Use the optimizer to pull out the dependencies in the array format for use on those devices.

昔のOperaだと動かないらしい。optimizer(r.jsのこと?)をつかえば、配列でフォーマットされる方に変換されるとのこと。

Function.prototype.toString を使ってrequire関数を呼んでる場所を解析している関係で、以下のコードは動かないことに注意

define(function(require){
  var superRequire = require;
  var a = superRequire('a');  // モジュールはないと言われる
  require = function(arg){ ... }
  require("abcd");  // 意図せず abcd.js の読み込みが走る
})

require関数を使うほうが可読性が高いので、使っていこうと思う。

24
25
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
24
25

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?