LoginSignup
32

More than 5 years have passed since last update.

JavaScriptでよく見る`var hoge=require('hoge')`ってなに?

Last updated at Posted at 2015-06-12

要約

  • JavaScript界隈でrequireをよく見るので使いたかったが、ブラウザ上でどうすれば使えるかわからなかったので調べた
  • requireはCommonJSという規格で決まっている
  • Require.JSであればブラウザのみでrequireの仕組みを享受できる事が分かった
    • ただし、var hoge=require('hoge');/* use hoge code */というCommonJSの規格通りにはかけず、require(['hoge'],function(hoge){ /* use hoge code */});という形で書く必要がある。残念に思う。

背景

最近、ちょっと動きがあるWeb画面を書いており、JavaScriptのコードでちょっと便利なライブラリがないかな?と調べたりしていると、まさしくこれがやりたかった!というものは見つかるけど大半はいきなりrequire('...')という記述で始まる。実際にその通り書いても「requireなんて関数はない」とか言われるし、使おうとしてもnodejsを入れないといけないみたいな雰囲気の情報しか出ない。ブラウザで動かしたいだけなのに。

自分の中でJavaScriptはブラウザのための言語だという認識が強かったのもあり、htmlファイルにscriptタグ書いてその中にコードをコピペしてブラウザで開けば動くものだと思っていたが、最近はどうも違うらしい。

歴史(適当)

今日、nodejs(v8?)のおかげでブラウザ以外でも実行できる環境が出てきた。今後クライアントサイドでもサーバサイドでもJavaScriptが使われるのだから、requireなど共通で使える便利なものはCommonJSという規格で定めていきましょう、ということになったらしい。

requireとは?

requireはCommonJSの規格のModulesを構成する1つとして定義されている。requireはhtmlファイルのscriptタグに相当する処理を、JavaScript内だけで出来るようにしてくれるものに見える。(実際は名前空間とかあるのだろうから、そこまで単純ではないとは思うけど。)
Javaでいうimport、Perlでいうuse、Cでいう#includeに相当するものだと思う

requireの実装はどこにある?

CommonJSは規格だけで、実装は提供していない。絵に描いた餅で。
ブラウザで使えるrequireの実装はどこにあるのか?というと、いろいろある。

  • Require.JS
  • browserify
  • Webpack

細かく調べればもっとあるんだろうけど、とりあえずここまで。ユーザが勝手に規格を実装すれば作れてしまうからキリがない。

で、上の3つのうち、browserifyとWebpackはrequireを使ったコードに対して「ビルド」を行う形で使う。ビルドではコード中のrequireというものを見つけていい感じにコードを組み替えて、requireでライブラリの機能を取り込んだのと同等なコードを出してくれる模様。あとはブラウザでビルド済みのコードをscriptタグで読み込めばOKという形だ。最近はWebpackがよさそうな感じがする。ビルドがbrowserifyより早いと聞いただけだけど。

でもbrowserifyとWebpackはNode.js導入が前提らしい。ブラウザでちょっと動作確認できればいいのに。よって、却下。(※プロダクトで使うなら使った方が良いと思います。)

そして最後に残った一番上のRequire.jsはブラウザさえあれば動作する。やった!

遊ぶ

サンプルとしてReact.jsでhello worldするのをrequireを通してやってみたい。

まずRequire.jsをgetしてきてbuild/require.jsへ配備しておく。
次に、React.jsもgetしてきてbuild/react.jsへ配備しておく。
次に、React.jsを扱うコードbuild/hello.jsを書く。
最後に、hello.jsを扱うコードhello.htmlを書く。

ただ、ここで少し悲しいお知らせがある。CommonJSで決めたrequireの使い方と、Require.JSの使い方が違う。(規格とはなんだったのか)
すごく文句をつけたいところだけど、ブラウザの力だけではどうにもできなかったのかもしれないし、規格を捨ててでも同等の機能を実装するには、きっと仕方がないことだと思いながら使うことにする。

build/hello.js
// var React = require('react'); // ... とはかけない。恨むならRequire.jsを恨め。

// 第1引数のarrayで読み込むライブラリを並べて、第2引数のfunctionで受ける。
require(['react'], function(React){ // require.jsを使わない場合ここの行を削除
    var App = React.createClass({displayName: "App",
        render: function(){
            return (
                React.createElement("p", null, "Hello React")
            );
        }
    });

    React.render(
        React.createElement("h1", null, React.createElement(App, null)),
        document.getElementById('app')
    );
}); // require.jsを使わない場合ここの行を削除

これをブラウザで呼びたいので、htmlはこうする

hello.html
<!DOCTYPE html>
<html>
  <head>
    <title>Hello React!</title>
  </head>
  <body>
     <div id="app"></div>
    <!-- require.jsを使う前はこんな感じ
    <script src="build/react.js"></script>
    <script src="build/hello.js"></script>
    <!-- -->
    <!-- require.jsを使うときはこんな感じ -->
     <script data-main="build/hello" src="build/require.js"></script>
   <!-- -->
  </body>
</html>

data-main属性に呼び出したい処理を書いて、src属性にはrequire.jsを指定する。require.jsはdata-main属性で指定したファイル(今回はbuild/hello.js)を読み取り、さらに内部でrequireされているファイルを読み取ってくれるらしい。今回はReact.jsのみしか読んでいないのでその動きまでは見れないけど。

また、hello.htmlhello.jsのコメントアウトしている箇所にある通り、該当行を修正するとrequire.jsを使わない形に出来る。

あとはブラウザだけで手軽にやりたいか、nodejsとライブラリを使って「ビルド」する形にしたいか、実装を選んで使い分けましょう、ということかと思う。

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
32