require.jsの使い方(最小コード)
すぐに使える短いコードを書いた。
成果物
方法
- 1.CDN
- 2.Local file
- 3.ES6 class
1.CDN
要ネット接続。require.jsをネットから取得するためローカルに配置せずに済む。
- index.html
- app.js
- src/
- main.js
- sub.js
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="utf-8"> <title>require.js CDN</title> <script data-main="app.js" src="https://cdnjs.cloudflare.com/ajax/libs/require.js/2.3.5/require.min.js"></script> </head> <body></body> </html>
requirejs(['js/app/main.js']);
js/app/mian.js
define(function(require, exports, module) { var sub = require('js/app/sub'); sub.print("MESSAGE!!"); });
js/app/sub.js
define(function() { return { print: function(msg) { alert(msg); console.log(msg); } }; });
2.Local file
3.ES6 class
require.jsの使い方まとめ
require.jsを使ってモジュール化する方法。
成果物
モジュール化とは
モジュール化とは、別ファイルに分割することである。
require.jsとは
require.jsとは、モジュール化するためのライブラリである。
require.jsの使い方
公式サイトのAPIリファレンスを参照した。
これさえあればいい
- 1.最小コード
- 2.ベストプラクティス
- 3.外部ライブラリ使用
こんなときどうする?
- 4.JSONP受信
- 5.循環依存
こんなときどうする?
- 4.テキストファイル受信
- 5.DOM読込完了待機
- 6.国際化(i18n)
こんな書き方もできる
- 6.テキストファイル受信
最小コード
1. HTML内
index.html
<html> <head> <script>alert("JavaScript!!");</script> </head> </html>
HTML内にJSが混在。JSが極小でコードを変更しないなら問題も少ない。
2. 外部ファイル化
index.html
<html> <head> <script src="main.js"></script> </head> </html>
main.js
alert("JavaScript!!");
HTMLとJSを分離してスッキリ。でも……
JSからJSを呼び出せない
JSコードの規模が大きくなると、JSファイルを複数に分割したくなる。なのにJSには外部呼出する言語仕様がない。(現在はimport
文がある)
index.html
<html> <head> <script src="main.js"></script> </head> </html>
main.js
class Human { constractor(name=null) { this._name = name; } Speak() { alert(this._name); } } const h = new Human(); h.Speak();
クラス定義と呼出を別ファイルに分離したいのに……。
3. 順序呼出
JSのファイル分割はできる。ただ、苦肉の策である。HTMLの<script>
タグでJSコードを順に呼び出すことになる。
index.html
<html> <head> <script src="Human.js"></script> <script src="main.js"></script> </head> </html>
main.js
const h = new Human(); h.Speak();
Human.js
class Human { constractor(name=null) { this._name = name; } Speak() { alert(this._name); } }
依存順序を把握せねばならない
呼出の順序が重要である。main.jsではHuman
を使用しているので、main.jsをロードする前にHuman
を定義してあるHuman.jsをロードせねばならない。さもなくば参照エラーになる。
<script src="Human.js"></script> <script src="main.js"></script>
もしJSコードの依存順序を変更することになれば、それに伴いHTMLの<script>
タグ順序も変更せねばならない。開発者はJSコード全体の依存順序をすべて把握している必要がある。これは規模が大きくなると非常に苦痛である。
HTMLを変更せねばならない
JSのファイル名やパスが変更されるとsrc
属性値を変更せねばならない。
JSの変更なのにHTMLファイルを編集するのだ。リビジョン管理するときの対象ファイルにHTMLが入ってしまう。
4 DOMでscriptタグ追加
JSコード内でHTMLへ<script>
タグを動的に追加する方法もある。
コード自体はJSで書けるので、HTMLファイルを修正する必要は最小限で済む。ただ、依存する順序に沿ってロードせねばならない問題は残る。
index.html
<html> <head> <script src="jsloader.js"></script> </head> </html>
jsloader.js
function Load(path) { var script=document.createElement('script'); script.setAttribute("src", path); document.body.appendChild(script); } Load("Human.js"); Load("main.js");
5. require.js
require.jsというライブラリを使う。依存順序を気にせず書ける。
ただ、ライブラリ固有の表現や設定をせねばならない。
index.html
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="utf-8"> <title>require.js</title> <script data-main="app.js" src="js/lib/require/require.min.js"></script> </head> <body></body> </html>
他のライブラリを使うときは以下のようにrequire.config
を設定する。
app.js
require.config({ paths: { 'text': 'js/lib/require/text', 'jquery': 'js/lib/jquery/jquery-3.3.1.min', } }); requirejs(['js/app/main.js']);
js/app/main.js
define(function(require, exports, module) { var sub = require('js/app/sub'); var $ = require('jquery'); sub.print("ABC"); });
js/app/sub.js
define(function() { return { print: function(source) { alert(source); console.log(source); } }; });
6. ES Module
ES6からimport
とexport
文が言語仕様に加わる。
ついにJavaScriptは標準でモジュール化できるようになった。
しかし、使える環境は限られる。ES Moduleを実装したブラウザは新しいものだ。Linuxは古いOSだと、ES Moduleを実装した新しいブラウザに更新できない。たとえばRaspbian8.0(Jessie)。
それの何が問題か?
- JSの依存関係なのにHTMLでしか記述できない
- HTMLの内容は変更しないのに、HTMLファイルを修正せねばならない
- モジュールができるたびに
- JSファイル名が変更されるたびに
- HTMLの内容は変更しないのに、HTMLファイルを修正せねばならない
呼出順序が
しかし、JSファイルから別のJSファイルを呼び出せない! 苦肉の策としてHTMLから順に呼び出す。
前回まで
私の環境Raspbian8.0ではimport
が使えない。Raspbian8.0(Jessie)ではChromium56までだが、import
,export
サポートはChromium61以上。※
そこで、require.jsを使ってみた。
今回
もっと簡単に書きたい。require.jsの使い方を研究してみる。
require(){...}
define({...})
define(function () {... return {...};})
define(["./foo", "./bar"], function(foo, bar) {... return {...};})
define(["./foo", "./bar"], function(foo, bar) {... return function(){...};})
define(function(require, exports, module) {... return {...};})
コード概要 | 説明URL |
---|---|
require(){...} |
1.2 data-main Entry Point |
define({...}) |
1.3.1 Simple Name/Value Pairs |
define(function () {... return {...};}) |
1.3.2 Definition Functions |
define(["./foo", "./bar"], function(foo, bar) {... return {...};}) |
1.3.3 Definition Functions with Dependencies |
define(["./foo", "./bar"], function(foo, bar) {... return function(){...};})
|1.3.4 Define a Module as a Function
define(function(require, exports, module) {... return {...};})
|1.3.5 Define a Module with Simplified CommonJS Wrapper
define("foo/title", ["a/A", "a/B"], function(A, B) {...});
|1.3.6 Define a Module with a Name
define(["require", "./relative/name"], function(require) { var mod = require("./relative/name"); });
|1.3.7 Other Module Notes
define(function(require) { var mod = require("./relative/name"); });
|1.3.7 Other Module Notes Better
define(["require", "a"], function(require, a) { return function(title) { return require("a").doSomething(); }});
|1.3.8 Circular Dependencies 循環参照
|
|
|
|
require(){...}
require(['foo'], function(foo) { });