CommonJSはサーバーサイドJavaScriptを支える標準APIです。
クライアントサイドJavaScriptにはDOMという標準の拡張APIがありました。 しかし、サーバサイドJavaScriptやその他のJavaScript実行環境には このような標準APIがなく独自APIが多数存在し、ライブラリ利用者に大きな負担となっていました。
このため2009年頃からCommonJSという標準APIを定める活動が現れました。
そして、現在サーバサイドJavaScriptとして多く使われるNode.jsやJavaScriptを組み込んだアプリケーションはこのCommonJSに準拠したライブラリを備え、多数の開発者がCommonJS準拠のライブラリを使用しています。
このJavaScript実行環境OgOも、CommonJSに準拠したAPIを部分的に実装しています。今後 必要に応じてCommonJS APIを追加実装していく予定です。
Buffer | バイナリデータ操作 |
File System (fs) | ファイル操作 |
Module | モジュール機能 |
Path | Path操作 |
Buffer クラスは、バイナリデータを操作するためのクラスです。
プロパティ | |
length | バイナリデータのバイト数 |
コンストラクタ | |
Buffer | Bufferオブジェクトを作成 |
メソッド関数 | |
copy | バッファ間でコピー |
fill | 指定された値でバッファを埋める |
read{Type}
readUInt8,
readUInt16LE, readUInt16BE, readUInt32LE, readUInt32BE, readInt8, readInt16LE, readInt16BE, readInt32LE, readInt32BE |
バッファから整数を取り出す |
toString | バッファの内容を文字列化 |
write | 文字列をバイト化して書き込む |
write{Type}
writeUInt8,
writeUInt16LE, writeUInt16BE, writeUInt32LE, writeUInt32BE, writeInt8, writeInt16LE, writeInt16BE, writeInt32LE, writeInt32BE |
バッファへ整数を書き込む |
inspect | バッファの内容を文字列化 |
クラスプロパティ | |
INSPECT_MAX_BYTES | inspectメソッドで表示するバイト数 |
クラス関数 | |
byteLength | 文字列のエンコード(encoding)バイト列にサイズを得る |
concat | バッファを結合 |
isBuffer | Bufferオブジェクトかどうかを判定 |
var buffer; buffer = new Buffer(8); print( buffer.length ); // 8 buffer = new Buffer("あいう", "uft8"); print( buffer.length ); // 9
var buffer; buffer = new Buffer(8); print( buffer.inspect() ); // バッファの内容を表示不定 buffer = new Buffer([8,9,10]); print( buffer.inspect() ); // <Buffer 08 09 0a> buffer = new Buffer("あいう"); // buffer = new Buffer("あいう", "utf8"); print( buffer.inspect() ); // <Buffer e3 81 82 e3 81 84 e3 81 86> buffer = new Buffer("CAkKCwwN", "base64"); print( buffer.inspect() ); // <Buffer 08 09 0a 0b 0c 0d> buffer = new Buffer("08090a0b0c0d", "hex"); print( buffer.inspect() ); // <Buffer 08 09 0a 0b 0c 0d>
var buffer, bufferTarget; buffer = new Buffer([1,2,3,4,5,6,7,8]); bufferTarget = new Buffer(4); buffer.copy(bufferTarget); print( bufferTarget.inspect() ); // バッファの内容を表示 <Buffer 01 02 03 04> buffer.copy(buffer, 3); print( buffer.inspect() ); // <Buffer 01,02,03,01,02,03,04,05>
埋める値
埋める開始位置
埋める終了次位置
var buffer = new Buffer(8); buffer.fill(0); print( bufferTarget.inspect() ); // バッファの内容を表示 <Buffer 00 00 00 00 00 00 00 00> buffer.fill(0xff, 4); print( bufferTarget.inspect() ); // バッファの内容を表示 <Buffer 00 00 00 00 ff ff ff ff>
trueならoffsetの是非をチェックしない. false(省略時)ならチェックします.
readUInt8 | --- | 1バイト 符号なし整数 |
readUInt16LE | --- | 2バイト 符号なし整数(Little-Endian) |
readUInt16GE | --- | 2バイト 符号なし整数(Big-Endian) |
readUInt32LE | --- | 4バイト 符号なし整数(Little-Endian) |
readUInt32GE | --- | 4バイト 符号なし整数(Big-Endian) |
readInt8 | --- | 1バイト 符号あり整数 |
readInt16LE | --- | 2バイト 符号あり整数(Little-Endian) |
readInt16GE | --- | 2バイト 符号あり整数(Big-Endian) |
readInt32LE | --- | 4バイト 符号あり整数(Little-Endian) |
readInt32GE | --- | 4バイト 符号あり整数(Big-Endian) |
var buffer = new Buffer(6); buffer.writeUInt32LE(0xffffffff); buffer.writeUInt16LE(0x8000,4); print(buffer.readInt32LE(0)); // -1 print(buffer.readInt16LE(4)); // -32768
var buf = new Buffer([0x41, 0x42, 0x43, 0x44, 0x45]); print( buf.toString('utf8', 2) ); // "CDE"
var buf = new Buffer([0x41, 0x42, 0x43, 0x44, 0x45]); print( buf.toString() ); // "ABCDE" var buf2 = new Buffer("あい"); buf.write(buf2, 2); print( buf.toString() ); // "ABあ"
書き込む整数
バッファの先頭位置を指定する.
trueならoffsetの是非をチェックしない. false(省略時)ならチェックします.
writeUInt8 | --- | 1バイト 符号なし整数 |
writeUInt16LE | --- | 2バイト 符号なし整数(Little-Endian) |
writeUInt16GE | --- | 2バイト 符号なし整数(Big-Endian) |
writeUInt32LE | --- | 4バイト 符号なし整数(Little-Endian) |
writeUInt32GE | --- | 4バイト 符号なし整数(Big-Endian) |
writeInt8 | --- | 1バイト 符号あり整数 |
writeInt16LE | --- | 2バイト 符号あり整数(Little-Endian) |
writeInt16GE | --- | 2バイト 符号あり整数(Big-Endian) |
writeInt32LE | --- | 4バイト 符号あり整数(Little-Endian) |
writeInt32GE | --- | 4バイト 符号あり整数(Big-Endian) |
バッファの内容の表示バイト数を指定します。省略時はBuffer.INSPECT_MAX_BYTES.
print(Buffer.byteLength("あいう")); // 9 print("あいう".length); // 3
var buf1 = new Buffer([1,2,3]); var buf2 = new Buffer([0x10,0x20]); var buf = Buffer.concat( [buf1, buf2] ); print( buffer.inspect() ); // <Buffer 01 02 03 10 20>
調べたいオブジェクト.
var array = [1,2,3]; var buffer = new Buffer(array); print( Buffer.isBuffer(array) ); // false print( Buffer.isBuffer(buffer)); // true
File Systemは、ファイル操作を扱うモジュールです。
このモジュールを使うには、最初にrequire関数でモジュールをロードします。
var fs = require('fs'); print( fs.rename("test.dat", "text.txt) );
rename, renameSync | ファイル名変更 |
truncate, truncateSync | ファイルのサイズを変更 |
unlink, unlinkSync | ファイルの削除 |
exists, existsSync | パスがあるかチェック |
chmod, chmodSync | ファイルのモードを変更 |
readFile, readFileSync | ファイルからデータを読み出す |
writeFile, writeFileSync | ファイルを作成し、データを書き込む |
appendFile, appendFileSync | ファイルにデータを追記する |
mkdir, mkdirSync | ディレクトリ作成 |
rmdir, rmdirSync | ディレクトリの削除 |
open, openSync | ファイルを開く |
close, closeSync | ファイルを閉じる |
write, writeSync | ファイルへデータを書く |
read, readSync | ファイルからデータを読む |
var fs = require('fs'); try{ fs.rename("d:\\work\\t.dat", "d:\\work\\t.txt"); // t.datファイル名を t.txtに変更 }catch(e){ // ファイル名変更失敗 }
var fs = require('fs'); try{ fs.rename("d:\\work\\t.dat", 128); // t.datファイルのサイズを 128バイト変更 }catch(e){ // ファイルのイズ変更失敗 }
var fs = require('fs'); try{ fs.unlink("d:\\work\\t.dat"); }catch(e){ // ファイル削除を失敗 }
var fs = require('fs'); print( fs.exists("d:\\work\\t.dat"); //あればtrue, なければfalse
var fs = require('fs'); fs.chmod("d:\\work\\t.dat", 0666); //書き込みと読み取り(6 => 2|4)の権限をセットします
var fs = require('fs'); var txt = fs.readFile("d:\\work\\t.dat", 'utf8');
var fs = require('fs'); var buf = new Buffer([1,2,3,4,5]); try{ fs.writeFile("d:\\work\\t.dat", "あいうえお', 'utf8'); fs.writeFile("d:\\work\\bin.dat", buf); }catch(e){ //書き込み失敗 }
var fs = require('fs'); var buf = new Buffer([1,2,3,4,5]); var buf2 = new Buffer([6,7,8,9,10]); try{ fs.writeFile("d:\\work\\t.dat", "abcd", 'utf8'); fs.appendFile("d:\\work\\t.dat", "あいうえお', 'utf8'); fs.writeFile("d:\\work\\bin.dat", buf); fs.appendFile("d:\\work\\bin.dat", buf2); }catch(e){ //追記 失敗 }
var fs = require('fs'); try{ fs.mkdir("d:\\work\\A"); }catch(e){ //削除失敗 }
var fs = require('fs'); try{ fs.rmdir("d:\\work"); }catch(e){ //削除失敗 }
'r' | ファイルを読み込み専用でオープンします。 ファイルが存在しない場合は例外が発生します。 | |
'r+' | ファイルを読み書き両用でオープンします。 ファイルが存在しない場合は例外が発生します。 | |
'rs' | 'r'と同じ。 | |
'rs+' | 'r+'と同じ。 | |
'w' | ファイルを書き込み専用でオープンします。 ファイルは作成されるか (存在しない場合)、または長さ 0 に切り詰められます (存在する場合)。 | |
'wx' | 'w' と似ていますが、path が存在すると失敗します。 | |
'w+' | ファイルを読み書き両用でオープンします。 ファイルは作成されるか (存在しない場合)、または長さ 0 に切り詰められます (存在する場合)。 | |
'wx+' | 'w+' と似ていますが、path が存在すると失敗します。 | |
'a' | ファイルを追記用でオープンします。 ファイルが存在しない場合は作成されます。 | |
'ax' | 'a' と似ていますが、path が存在すると失敗します。 | |
'a+' | ファイルを読み込みおよび追記用でオープンします。 ファイルが存在しない場合は作成されます。 | |
'ax+' | 'a+' と似ていますが、path が存在すると失敗します。 |
var fs = require('fs'); var fd = -1; var buffer, len; try{ // write fd = fs.open("mytext.data", "w", 0666); fs.write(fd, "I like OgO."); fs.close(fd); // read fd = fs.open("mytext.data", "r"); buffer = new Buffer(128); len = fs.read(fd, buffer); print(buffer.toString()); // I like OgO. fs.close(fd); }catch(e){ //失敗 }
var fs = require('fs'); var fd = -1; var buffer; try{ fd = fs.open("mydata.dat", "w", 0666); buffer = new Buffer("あいう"); fs.write(fd, buffer); fs.close(fd); }catch(e){ //失敗 }
var fs = require('fs'); var fd = -1; var buffer; try{ fd = fs.open("mydata.dat", "r"); buffer = new Buffer(128); fs.read(fd, buffer, 0, buffer.length); print( buffer.toString() ); fs.close(fd); }catch(e){ //失敗 }
CommonJSではモジュール機能を exports, moduleオブジェクトとrequire関数を使ってを実現します。
モジュールとして読み込まれる側のコードと、モジュールを読む側のコードをそれぞれ以下のように書きます。
■ モジュールとして読み込まれる側のコード smath.js
// smath.js function add(x,y) { return x + y; } function mul(x,y) { return x * y; } exports.add = add; //add関数を他のモジュールから使えるようにexportします。 exports.mul = mul; //mull関数を ・・・
■ モジュールを読む側のコード sample.js
var smath = require('./smath'); // このコードと同じフォルダーにあるモジュールをロード alert( smath.add(10, 20) ); // 30 alert( smath.mul(10, 20) ); // 200 //=別バージョン= var {add, mul} = require('./smath'); // このコードと同じフォルダーにあるモジュールをロード alert( add(10, 20) ); // 30 alert( mul(10, 20) ); // 200
JavaScriptでは、複数のコードに同名のグローバル変数が定義されることを「変数の衝突」と呼んでいます。この「変数の衝突」がバグを起こす原因を多く作っています。
そこで exports変数,require関数を使ってモジュール化すれば、モジュールとして読み込まれる側のコードにある変数はすべてローカル変数となり「変数の衝突」を防げます。
そして モジュールの情報はmoduleオブジェクトにセットされています。
exports | exportしたい変数や関数をプロパティにセットする |
module | モジュール情報 |
module.exports | exportしたい変数や関数をプロパティにセットする |
module.filename | モジュールのフルパス名 |
module.id | モジュールの識別子 |
require関数 | ファイルモジュールをロード |
require.main関数 | メインモジュール |
__dirname | 現在実行されているスクリプトのディレクトリ |
__filename | 現在実行されているスクリプトのフルパス名 |
exportsはモジュールとして読み込まれる側のコードにおいて、外部に公開したい関数やデータをexportsオブジェクトのプロパティにセットします。 各モジュールのexportsは異なるオブジェクトであり、このモジュールを読む側のコードのrequire関数の返値はこのexportsオブジェクトです。 exportsはmodule.exportsオブジェクトがセットされたモジュール内のローカル変数です。 例 ■ モジュールとして読み込まれる側のコード smath.js // smath.js function add(x,y) { return x + y; } function mul(x,y) { return x * y; } exports.add = add; //add関数を他のモジュールから使えるようにexportします。 exports.mul = mul; //mull関数を ・・・ ■ モジュールを読む側のコード sample.js var smath = require('./smath'); // このコードと同じフォルダーにあるモジュールをロード alert( smath.add(10, 20) ); // 30 alert( smath.mul(10, 20) ); // 200 //=別バージョン= var {add, mul} = require('./smath'); // このコードと同じフォルダーにあるモジュールをロード alert( add(10, 20) ); // 30 alert( mul(10, 20) ); // 200
moduleは実行中のモジュールの情報を含んだオブジェクトです。 各モジュールのmoduleは異なるオブジェクトであり、外部公開しない限り他のモジュールから参照できません。ただし、メイン(Scriptスタートモジュールの)moduleオブジェクトはrequire.mainで参照できます。 例 モジュールがメイン(Scriptスタート)モジュールかどうかの判定 if (module==require.main) { // このモジュールはメインモジュールである // ・・・ }
module.exportsはモジュールとして読み込まれる側のコードにおいて、外部に公開したい関数やデータをmodule.exportsオブジェクトのプロパティにセットします。 各モジュールのmodule.exportsは異なるオブジェクトであり、このモジュールを読む側のコードのrequire関数の返値はこのmodule.exportsオブジェクトです。 モジュール内のローカル変数 exportsは モジュール実行直前にmodule.exportsオブジェクトがセットされ、exportのコードを簡略にしています。 例 ■ モジュールとして読み込まれる側のコード smath.js // smath.js exportsオブジェクトを関数に変更する例 exports = module.exports = function() { alert("I am a smath-module."); } function add(x,y) { return x + y; } function mul(x,y) { return x * y; } module.exports.add = add; //add関数を他のモジュールから使えるようにexportします。 module.exports.mul = mul; //mull関数を ・・・ ■ モジュールを読む側のコード sample.js var smath = require('./smath'); // このコードと同じフォルダーにあるモジュールをロード alert( smath.add(10, 20) ); // 30 alert( smath.mul(10, 20) ); // 200 smath(); // I am a smath-module.
module.filenameは実行中のモジュールのフルパス名です。 例 ■ モジュールとして読み込まれる側でフルパス名を表示 // smath.js function add(x,y) { return x + y; } function mul(x,y) { return x * y; } exports.add = add; //add関数を他のモジュールから使えるようにexportします。 exports.mul = mul; //mull関数を ・・・ alert(module.filename); // d:\work\smath.js
module.idは実行中のモジュールの識別子です。 現在の仕様では file://モジュールのフルパス名 となっています。(将来変更される可能性あり) 例 ■ モジュールとして読み込まれる側で識別子を表示 // smath.js function add(x,y) { return x + y; } function mul(x,y) { return x * y; } exports.add = add; //add関数を他のモジュールから使えるようにexportします。 exports.mul = mul; //mull関数を ・・・ alert(module.id); // file://d:\work\smath.js
require関数を使ったモジュールロードは、「名前空間の衝突」を避けます。 さらに、ロードは最初の1回のみで次回からのrequire関数呼出はモジュールのロードされずシステムキャッシュに保存された exportsオブジェクトを返します。
例 ■ モジュールを読む側のコード var smath = require('./smath'); // このコードと同じフォルダーにあるモジュールをロード alert( smath.add(10, 20) ); // 30 alert( smath.mul(10, 20) ); // 200 //=別バージョン= var {add, mul} = require('./smath'); // このコードと同じフォルダーにあるモジュールをロード alert( add(10, 20) ); // 30 alert( mul(10, 20) ); // 200 //OgOの指定パス順序でモジュールをサーチ var {WScript} = require("wsh"); var excel = WScript.CreateObject("Excel.Application"); excel.Visible = true;
require.mainはメイン(Scriptスタートモジュールの)moduleです。 requireは各モジュールの関数であることから、各モジュールはメインモジュールを知ることができます。 例 モジュールがメイン(Scriptスタート)モジュール)かどうかの判定 if (module==require.main) { // このモジュールはスタートモジュールである // ・・・ }
module.filenameと同じ内容です。
Pathは、ファイルパスを扱うモジュールです。
このモジュールを使うには、最初にrequire関数でモジュールをロードします。
var Path = require('path'); print( Path.basename("d:\\work\\test.dat") ); // test.dat
定数 | |
sep | ファイルセパレータ |
delimiter | 環境変数Path内の区切り |
関数 | |
normalize | パス名を正規化 |
join | 文字列を結合してパス名を作成 |
resolve | 絶対パスを作成する |
isAbsolute | 絶対パスかどうかを判定 |
dirname | ディレクトリ名を取得 |
basename | ファイル名を取得 |
extname | 拡張子を取得 |
parse | ファイルパスの各部分を取得 |
var Path = require('path'); 'foo\\bar\\baz'.split(Path.sep); // ['foo', 'bar', 'baz']
var Path = require('path'); print( Path.normalize("d:\\work\\..\\t.dat") ); // d:\t.dat print( Path.normalize("d:/work/../t.dat") ); // d:\t.dat print( Path.normalize("..\\..\\t.dat") ); // ..\..\t.dat
var Path = require('path'); print( Path.join("work", "t.dat") ); // work\t.dat print( Path.join("d:\\work", "..", "t.dat") ); // d:\t.dat
var Path = require('path'); print( Path.resolve("d:\\work", "test", "temp", "..", "t.dat") ); // d:\work\test\t.dat print( Path.resolve("work", "test", "..", "t.dat") ); // d:\work\t.dat
var Path = require('path'); print( Path.isAbsolute("d:\\work\\test.dat") ); // true print( Path.isAbsolute("work\\test.dat") ); // false
var Path = require('path'); print( Path.dirname("d:\\work\\test.dat") ); // d:\work print( Path.dirname("work\\..\\test.dat") ); // work\..\test.dat
var Path = require('path'); print( Path.basename("d:\\work\\test.dat") ); // test.dat print( Path.basename("work\\..\\test.dat") ); // test.dat
var Path = require('path'); print( Path.extname("d:\\work\\test.dat") ); // .dat print( Path.extname("work\\..\\test") ); // 空文字列
var Path = require('path'); var ans = Path.parse("d:\\work\\test.dat"); print( ans.dir ); // d:\work print( ans.root ); // d:\ print( ans.base ); // test.dat print( ans.name ); // test print( ans.ext ); // .dat