ブログシステムのコードを書き始めた。ダッシュボード・テンプレート SB Admin2 をベースに少しずつUIを作り替えていく作戦で始めた。実装はHubPressを参考にする。
HubPressでは設定情報を保存するデータストアとしてIndexedDBを使用している。IndexedDBはDBライクに操作できるdexieというライブラリを経由してアクセスする。私もこれに倣うことにする。
軽く下記のようなコードを書いてみると、これが動作しない。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var dexie = require('dexie'); | |
var db = new dexie('sfblog'); | |
db.version(1).stores({ | |
github: "username,password,apikey" | |
}); | |
db.open(); | |
db.transaction('rw', db.github, function () { | |
db.github.add({ username: 'sfpgmr', password: 'pass', apikey: 'aaaaa' }); | |
db.github.add({ username: 'sfpgmr3', password: 'pass', apikey: 'aaaaa' }); | |
}); | |
db.github.each(function (r) { | |
console.log(r); | |
}); | |
db.close(); |
調べてみると以下のことが分かった。dexie.jsのコードの外枠は以下のようになっている。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(function (global, publish, undefined) { | |
// dexie の中身(省略) | |
// Export Dexie to window or as a module depending on environment. | |
publish("Dexie", Dexie); | |
}).apply(null, | |
// AMD: | |
typeof define === 'function' && define.amd ? | |
[self || window, function (name, value) { define(name, function () { return value; }); }] : | |
// CommonJS: | |
typeof global !== 'undefined' && typeof module !== 'undefined' && module.exports ? | |
[global, function (name, value) { module.exports = value; }] | |
// Vanilla HTML and WebWorkers: | |
: [self || window, function (name, value) { (self || window)[name] = value; }]); | |
これはAMDとCommonJS、それとブラウザで動かす時によく書かれるコードである。nw.jsはglobalもwindowも両方持っているので、require()
すると上記のコードだとCommonJS対応部分が有効となり、globalオブジェクトがグローバルオブジェクトとして関数の引数に設定される。
それで、IndexedDBのラップする部分のコードを見てみると以下のようであった。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// Dependencies | |
// | |
// These will automatically work in browsers with indexedDB support, or where an indexedDB polyfill has been included. | |
// | |
// In node.js, however, these properties must be set "manually" before instansiating a new Dexie(). For node.js, you need to require indexeddb-js or similar and then set these deps. | |
// | |
var idbshim = global.idbModules && global.idbModules.shimIndexedDB ? global.idbModules : {}; | |
Dexie.dependencies = { | |
// Required: | |
// NOTE: The "_"-prefixed versions are for prioritizing IDB-shim on IOS8 before the native IDB in case the shim was included. | |
indexedDB: idbshim.shimIndexedDB || global.indexedDB || global.mozIndexedDB || global.webkitIndexedDB || global.msIndexedDB, | |
IDBKeyRange: idbshim.IDBKeyRange || global.IDBKeyRange || global.webkitIDBKeyRange, | |
IDBTransaction: idbshim.IDBTransaction || global.IDBTransaction || global.webkitIDBTransaction, | |
// Optional: | |
Error: global.Error || String, | |
SyntaxError: global.SyntaxError || String, | |
TypeError: global.TypeError || String, | |
DOMError: global.DOMError || String, | |
localStorage: ((typeof chrome !== "undefined" && chrome !== null ? chrome.storage : void 0) != null ? null : global.localStorage) | |
}; |
コメントに書いてある通りだが、node.jsで使用するときはindexeddb-jsを事前にrequire
しておかなくてはいけないようだ。
しかしnw.jsはwindowオブジェクトも持っており、IndexedDBもサポートしている。だけどglobalオブジェクトが渡されるのでpolyfillが必要になってしまうのだ。windowオブジェクトのIndexedDBを使わせるにはどうしたらよいかと少し考えたが、ベタな方法で回避することにした。require('dexie')
する前に以下のコードを書くのである。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
global.indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB; |
ちょっと不細工な方法だが、とりあえずこれで進めることにした。