
NBïŒããã¯ãnode.jsã®çè«çåºç€ã«æ¢ã«ç²ŸéããŠãããèšãããã«ãããã«ãã®ããŒã«ã䜿çšããŠéçºã«çªå
¥ããã人ã®ããã®è³æã§ãã æ§é€ãªããã³ãŒãã£ã³ã°ã®ã¿ã èå³ããããªããæ¥ããããããã«ãç«ã®äžãéãéããã
翻蚳è
ããïŒç§èªèº«ãããæè¿node.jsãåŠã³å§ããŸããã ééããªããã€ã³ã¿ãŒãããäžã«ã¯ãåå¿è
åãã®å€ãã®åªããïŒïŒïŒããã¥ã¢ã«ããããŸãïŒç¹ã«ããããããªã©ïŒã ããããèè
Krasimir Tsonevã®ãã®ããã¥ã¢ã« ïŒåœŒã®ãã«ããããã¯ããã°ãåç
§ããããšããå§ãããŸãïŒã¯ãMVCãã¿ãŒã³ãšããŒã¹ã䜿çšããŠExpressã¢ãžã¥ãŒã«ã«åºã¥ããæ¬æ Œçãªnode.jsã¢ããªã±ãŒã·ã§ã³ãæ§ç¯ããããã»ã¹ã«ã€ããŠèª¬æããŠãããããç¹ã«æ³šç®ã«å€ããããã«æããŸããã MongoDBããŒã¿ã èè
ã¯ãŸãããã¹ããªã©ã®éèŠãªããšã«æ³šæãæã£ãŠããŸãã翻蚳
ãã®èšäºã§ã¯ãã¯ã©ã€ã¢ã³ãéšåãåããæ¬æ ŒçãªWebãµã€ããšããµã€ãã®ã³ã³ãã³ãçšã®ã³ã³ãããŒã«ããã«ãæ§ç¯ããŸãã ãæ³åã®ãšãããããã°ã©ã ã®æçµããŒãžã§ã³ã«ã¯å€æ°ã®ç°ãªããã¡ã€ã«ãå«ãŸããŠããŸãã ãã®ã¬ã€ããæ®µéçã«äœæããããã»ã¹ã®éçºãå®å
šã«ç£èŠããŸãããããã¹ãŠã®ãã¡ã€ã«ããã®äžã«å«ããããšã¯å§ããŸããã§ããã ãã ãããœãŒã¹ã³ãŒãã¯
GitHubã§å
¥æã§ããŸãããã§ãã¯ã¢ãŠãããããšã匷ããå§ãããŸãã
ãšã³ããªãŒ
Expressã¯ãæé«ã®
Nodeãã¬ãŒã ã¯ãŒã¯ã®1ã€ã§ãã åªããéçºè
ãµããŒããšå€æ°ã®äŸ¿å©ãªæ©èœãåããŠããŸãã Expressã«ã¯ããããæ±ãããã®ãã¹ãŠã®åºæ¬äºé
ãç¶²çŸ
ããçŽ æŽãããèšäºããããããããŸãã ããããä»ã¯ããå°ãæãäžããŠãæ¬æ ŒçãªWebãµã€ããäœæããçµéšãå
±æããããšæããŸãã äžè¬ã«ããã®èšäºã¯Expressèªäœã«é¢ããã ãã§ãªããéçºè
ãå©çšã§ããä»ã®å£ããªãçŽ æŽãããããŒã«ãšã®çµã¿åããã«ã€ããŠã説æããŠããŸãã
Node.jsã«ç²Ÿéããã·ã¹ãã ã«ã€ã³ã¹ããŒã«ããããšãããã³ãã®äžã«ããã€ãã®ã¢ããªã±ãŒã·ã§ã³ãæ¢ã«äœæããŠããããšãä¿¡ããŠããŸãã
Expressãã¬ãŒã ã¯ãŒã¯ã¯
Connectã«åºã¥ããŠã
ãŸã ã ããã¯ãå€ãã®äŸ¿å©ãªæ©èœãåããããã«ãŠã§ã¢æ©èœã®ã»ããã§ãã ããã«ãŠã§ã¢é¢æ°ãšã¯äœãã«èå³ããããªããããã«å°ããªäŸããããŸãïŒ
var connect = require('connect'), http = require('http'); var app = connect() .use(function(req, res, next) { console.log("That's my first middleware"); next(); }) .use(function(req, res, next) { console.log("That's my second middleware"); next(); }) .use(function(req, res, next) { console.log("end"); res.end("hello world"); }); http.createServer(app).listen(3000);
ããã«ãŠã§ã¢é¢æ°ã¯ãåºæ¬çã«ããªã¯ãšã¹ããªããžã§ã¯ããšå¿çãªããžã§ã¯ãããã©ã¡ãŒã¿ãŒãšããŠåãå
¥ãã颿°ã§ãããæ¬¡ã«åŒã³åºãããã³ãŒã«ããã¯é¢æ°ã§ããããŸãã åããã«ãŠã§ã¢é¢æ°ã¯ãå¿çãªããžã§ã¯ãã䜿çšããŠå¿çããããã¹ããªãŒã ãæ¬¡ã®ã³ãŒã«ããã¯é¢æ°ã«æž¡ãããæ±ºå®ããŸãã äžèšã®äŸã§ã¯ã2çªç®ã®é¢æ°ã§
nextïŒïŒã¡ãœããåŒã³åºããåé€ãããšãæååãhello worldãã¯ã¯ã©ã€ã¢ã³ãã«éä¿¡ãããŸããã äžè¬çã«ããããExpressã®ä»çµã¿ã§ãã ããã¯ééããªãããªãã®æéãç¯çŽããããã€ãã®å®çŸ©æžã¿ã®ããã«ãŠã§ã¢æ©èœãåããŠããŸãã ããšãã°ããªã¯ãšã¹ãããã£ãè§£æããã³ã³ãã³ãã¿ã€ã
application / json ã
application / x-www-form-urlencodedããã³
multipart / form-dataããµããŒããã
ããã£ããŒãµãŒã§ãã ãŸãã¯ã
CookieããããŒãè§£æããããŒãCookieã®ååã§
ãããªããžã§ã¯ãã
req.cookiesãã£ãŒã«ãã«å
¥åãã
CookieããŒãµãŒã
å®éãExpressã¯ããèªäœãConnectãã¬ãŒã ã¯ãŒã¯ã§ã©ããããã«ãŒãã£ã³ã°ããžãã¯ãªã©ã®ããã€ãã®æ©èœã§è£å®ããŠãã«ãŒãã£ã³ã°ããã»ã¹ãã¹ã ãŒãºã«é²ããŸãã 以äžã¯ãGETèŠæ±ãåŠçããäŸã§ãã
app.get('/hello.txt', function(req, res){ var body = 'Hello World'; res.setHeader('Content-Type', 'text/plain'); res.setHeader('Content-Length', body.length); res.end(body); });
èšçœ®
Expressã®ã€ã³ã¹ããŒã«ã«ã¯2ã€ã®ãªãã·ã§ã³ããããŸãã 1ã€ç®ã¯ããã®èª¬æã
package.jsonãã¡ã€ã«ã«é
眮ããŠ
npm installã³ãã³ããå®è¡ããããšã§ãïŒãã®ããã±ãŒãžãããŒãžã£ãŒã®ååã¯ãno problem manãã衚ããŠãããããªãžã§ãŒã¯ããããŸã:)ïŒã
{ "name": "MyWebSite", "description": "My website", "version": "0.0.1", "dependencies": { "express": "3.x" } }
ãã¬ãŒã ã¯ãŒã¯ã³ãŒãã¯
node_modulesãã£ã¬ã¯ããªã«é
眮ãããã€ã³ã¹ã¿ã³ã¹ãäœæã§ããŸãã ç§ã¯ä»£æ¿ææ®µã奜ã¿ãŸãïŒã³ãã³ãã©ã€ã³ã
npm install -g expressãå®è¡ããŠExpressãã€ã³ã¹ããŒã«ããã ãã§ãã ããã«ãããæ°ããCLIããŒã«ãäœæãããŸãã ããšãã°ã次ã®å ŽåïŒ
express --sessions --css less --hogan app
Expressã¯ãæ§ææžã¿ã®ã¢ããªã±ãŒã·ã§ã³ãã¬ãŒã ã¯ãŒã¯ãçæããŸãã 以äžã¯ã
ãšã¯ã¹ãã¬ã¹ïŒ1ïŒã³ãã³ããªãã·ã§ã³ã®ãªã¹ãã§ãã
Usage: express [options] Options: -h, --help output usage information -V, --version output the version number -s, --sessions add session support -e, --ejs add ejs engine support (defaults to jade) -J, --jshtml add jshtml engine support (defaults to jade) -H, --hogan add hogan.js engine support -c, --css add stylesheet support (less|stylus) (defaults to plain css) -f, --force force on non-empty directory
ã芧ã®ãšããã䜿çšå¯èœãªãªãã·ã§ã³ã®ãªã¹ãã¯å°ããã§ãããããã§ååã§ãã éåžžã
lessã©ã€ãã©ãªãCSSããªããã»ããµãšããŠäœ¿çšãã
hoganãã³ãã¬ãŒã
ãšã³ãžã³ã䜿çšããŸãã ãã®äŸã§ã¯ãã»ãã·ã§ã³ã®ãµããŒããå¿
èŠã§ã
ã--sessionsãªãã·ã§ã³ã¯ãã®åé¡ã解決ããŸãã ããŒã ãå®äºãããšããããžã§ã¯ãã®æ§é ã¯æ¬¡ã®ããã«ãªããŸãã
/public /images /javascripts /stylesheets /routes /index.js /user.js /views /index.hjs /app.js /package.json
package.jsonãã¡ã€ã«ãèŠããšãå¿
èŠãªãã¹ãŠã®äŸåé¢ä¿ãããã«è¿œå ãããŠããããšãããããŸãã ãããããŸã ã€ã³ã¹ããŒã«ãããŠããŸããã ãããè¡ãã«ã¯ãnpm installã³ãã³ããå®è¡ã
ãŸã ããã®åŸã
node_modulesãã£ã¬ã¯ããª
ã衚瀺ãããŸã ã
äžèšã®ã¢ãããŒãã¯ããŠãããŒãµã«ãšåŒã¶ã«å€ããªãããšãçè§£ããŠããŸãã ããšãã°ãã«ãŒããã³ãã©ãå¥ã®ãã£ã¬ã¯ããªãªã©ã«é
眮ããå¿
èŠãããå ŽåããããŸãã ããããæ¬¡ã®ããã€ãã®ç« ã§ç€ºãããããã«ãçæãããæ§é ã«å€æŽãå ããŸããããã¯éåžžã«ç°¡åã§ãã ããã«åºã¥ããŠã
expressïŒ1ïŒã³ãã³ããåã«ãã³ãã¬ãŒããžã§ãã¬ãŒã¿ãšããŠäœ¿çšããããšããå§ãããŸãã
é«éé
ä¿¡
ãã®ãã¥ãŒããªã¢ã«ã§ã¯ãFastDeliveryãšããæ¶ç©ºã®äŒç€Ÿã®ç°¡åãªWebãµã€ããäœæããŸããã 宿ãããã¶ã€ã³ã®ã¹ã¯ãªãŒã³ã·ã§ãããæ¬¡ã«ç€ºããŸãã

ãã®ã¬ã€ãã®æåŸã«ãæ©èœããã³ã³ãããŒã«ããã«ãåããæ¢è£œã®Webã¢ããªã±ãŒã·ã§ã³ããããŸãã ã¢ã€ãã¢ã¯ããµã€ãã®åéšåãåéšåã®å¥ã
ã®é åã§ç®¡çããæ©èœãäœæããããšã§ãã ã¬ã€ã¢ãŠãã¯Photoshopã§äœæãããCSSïŒlessïŒããã³HTMLïŒhoganïŒãã¡ã€ã«ã«ã«ãããããŸããã ããã§ã¯ã¹ã©ã€ã¹ããã»ã¹ã«ã€ããŠã¯èª¬æããŸãããããã¯ããã®èšäºã§ã®è°è«ã®äž»é¡ã§ã¯ãªãããã§ããããã®éšåã«é¢ããŠè³ªåãããå Žåã¯ããæ°è»œã«è³ªåããŠãã ããã ã¹ã©ã€ã¹ãçµäºãããšãã¢ããªã±ãŒã·ã§ã³ãã¡ã€ã«ã®æ¬¡ã®æ§é ãåŸãããŸãã
/public /images (there are several images exported from Photoshop) /javascripts /stylesheets /home.less /inner.less /style.css /style.less (imports home.less and inner.less) /routes /index.js /views /index.hjs (home page) /inner.hjs (template for every other page of the site) /app.js /package.json
以äžã«ã管çã§ãããµã€ãèŠçŽ ã®ãªã¹ãã瀺ããŸãã
- ããŒã ããŒãžïŒäžå€®ã®ãããŒ-ã¿ã€ãã«ãšããã¹ãïŒ
- ããã°ïŒèšäºã®è¿œå ãåé€ãç·šéïŒ
- ãµãŒãã¹ããŒãž
- æ¡ç³å ŽããŒãžïŒç å Žã§ã¯ãªãå°éçãªæé·:)ïŒ
- ãåãåããããŒãž
æ§æ
å§ããåã«ãããªããã°ãªããªãããšãããã€ããããŸãã æ§æã®ã»ããã¢ããã¯ãã®ãããªãã®ã®1ã€ã§ãã å°èŠæš¡ãªãµãŒããŒããããŒã«ã«ãäžéãæŠéã®3ã€ã®ç°ãªããµãŒããŒã«å±éãããããšãæ³åããŠã¿ãŸãããã åœç¶ã3ã€ã®ç°å¢ãã¹ãŠã®èšå®ã¯ç°ãªãããããã®ãããªç¶æ³ã«ååã«æè»ãªã¡ã«ããºã ãå®è£
ããå¿
èŠããããŸãã ãåç¥ã®ããã«ãånodejsã¹ã¯ãªããã¯ã³ã³ãœãŒã«ã¢ããªã±ãŒã·ã§ã³ãšããŠå®è¡ãããŸãã ã€ãŸããçŸåšã®ç°å¢ã決å®ããã³ãã³ãã«ãã©ã¡ãŒã¿ãŒãç°¡åã«å²ãåœãŠãããšãã§ããŸãã åŸã§ãã¹ããæžãã®ã䟿å©ã«ãªãããã«ããã®éšåãå¥ã®ã¢ãžã¥ãŒã«ã«ã©ããããŸããã
/config/index.jsãã¡ã€ã«ïŒ
var config = { local: { mode: 'local', port: 3000 }, staging: { mode: 'staging', port: 4000 }, production: { mode: 'production', port: 5000 } } module.exports = function(mode) { return config[mode || process.argv[2] || 'local'] || config.local; }
çŸæç¹ã§ã¯ãã¢ãŒãïŒã¢ãŒãïŒãšããŒãïŒããŒãïŒã®2ã€ã®ãã©ã¡ãŒã¿ãŒãããããŸããã ãæ³åã®ãšãããã¢ããªã±ãŒã·ã§ã³ã¯ç°ãªããµãŒããŒäžã®ç°ãªãããŒãã䜿çšããŸãã ãã®ããã
app.jsãã¡ã€ã«ã§ãµã€ãã®ãšã³ããªãã€ã³ããæŽæ°ããå¿
èŠããããŸãã
... var config = require('./config')(); ... http.createServer(app).listen(config.port, function(){ console.log('Express server listening on port ' + config.port); });
æ§æãåãæ¿ããã«ã¯ãç°å¢ã®ååãã³ãã³ãã®æåã®ãã©ã¡ãŒã¿ãŒã«è¿œå ããã ãã§ãã äŸïŒ
node app.js staging
åºåãããŸãïŒ
Express server listening on port 4000
çŸåšããã¹ãŠã®èšå®ã¯1ãæã«ä¿åãããŠããã管çã容æã§ãã
ãã¹ã
ç§ã¯
TDDã®å€§ãã¡ã³ã§ãã ãã®èšäºã§åãäžãããã¹ãŠã®åºæ¬ã¯ã©ã¹ããã¹ãã§ã«ããŒããããã«ããŸãã 絶察ã«ãã¹ãŠã®ãã¹ããäœæããã®ã«ã¯å€ãã®æéããããããšã«åæããŸãããäžè¬ã«ããããã¢ããªã±ãŒã·ã§ã³ã®äœææ¹æ³ã§ãã ç§ã®ãæ°ã«å
¥ãã®ãã¹ããã¬ãŒã ã¯ãŒã¯ã®1ã€ã¯
ãžã£ã¹ãã³ã§ãã ãã¡ããã
npmããã±ãŒãžãããŒãžã£ãŒã§å©çšã§ããŸãã
npm install -g jasmine-node
ãã¹ããä¿åãããã£ã¬ã¯ããªãäœæããŸãããã æåã«ãã¹ãããã®ã¯ãæ§æãã¡ã€ã«ã§ãã ãã¹ããã¡ã€ã«ã®ååã¯
.spec.jsã§çµããå¿
èŠãããããããã¡ã€ã«
config.spec.jsãåŒã³åºããŸãã
describe("Configuration setup", function() { it("should load local configurations", function(next) { var config = require('../config')(); expect(config.mode).toBe('local'); next(); }); it("should load staging configurations", function(next) { var config = require('../config')('staging'); expect(config.mode).toBe('staging'); next(); }); it("should load production configurations", function(next) { var config = require('../config')('production'); expect(config.mode).toBe('production'); next(); }); });
jasmine-node ./testsã³ãã³ããå®è¡ãããšã次ã®ããã«è¡šç€ºãããŸãã
Finished in 0.008 seconds 3 tests, 6 assertions, 0 failures, 0 skipped
ä»ãç§ã¯æåã«å®è£
ãæžããæ¬¡ã«ãã¹ããæžããŸããã ããã¯TDDã¢ãããŒãã§ã¯ãããŸããããæ¬¡ã®ç« ã§ã¯å察ã®ããšãè¡ããŸãã
ãã¹ããæžãã®ã«ååãªæéããããããšã匷ããå§ãããŸãã å®å
šã«ãã¹ããããã¢ããªã±ãŒã·ã§ã³ã«åããã®ã¯ãããŸããã
æ°å¹Žåãç§ã¯éåžžã«éèŠãªäœããããè¯ãã¢ããªã±ãŒã·ã§ã³ãäœæããã®ã«åœ¹ç«ã€äœãã«æ°ä»ããŸããã æ°ããã¯ã©ã¹ãæ°ããã¢ãžã¥ãŒã«ããŸãã¯åãªãããžãã¯ã®äœæãéå§ãããã³ã«ã次ã®ããšãèªåããŠãã ããã
ãããã©ã®ããã«ãã¹ãã§ããŸããïŒ
ãã®è³ªåã«å¯Ÿããçãã¯ãã³ãŒããããå¹ççã«èšè¿°ããåªããAPIãäœæãããã¹ãŠãé©åã«åé¢ããããããã¯ã«åå²ããã®ã«åœ¹ç«ã¡ãŸãã ã¹ãã²ããã£ã³ãŒãã®ãã¹ãã¯äœæã§ããŸããã ããšãã°ãäžèšã®æ§æãã¡ã€ã«ïŒ
/config/index.js ïŒã§ãã¢ãžã¥ãŒã«ã³ã³ã¹ãã©ã¯ã¿ãŒã«ã¢ãŒããéä¿¡ããæ©èœã远å ããŸããã ããªãã¯é©ããããããŸããïŒäž»ãªã¢ã€ãã¢ã¯ã³ãã³ãã©ã€ã³åŒæ°ããã¢ãŒãã®å€ãååŸããããšãªã®ã§ããªãç§ã¯ãããããã®ã§ããïŒ ç°¡åã§ãããã¹ãããå¿
èŠãããããã§ãã 1ãæåŸã«æŠéãµãŒããŒã®æ§æã䜿çšããŠäœãããã¹ãããå¿
èŠããããããŒãã¹ã¯ãªããã代æ¿ãã©ã¡ãŒã¿ãŒã§å®è¡ãããããšãæ³åããŠã¿ãŸãããã ãããŠããã®å°ããªæ¹åããªããã°å€æŽãå ããããšã¯ã§ããŸããã ãã®åã®å°ããªã¹ãããã¯ãå°æ¥ã®ã¢ããªã±ãŒã·ã§ã³ã®å±éã§èµ·ããããåé¡ãé²ããŸãã
ããŒã¿ããŒã¹
åçãªWebãµã€ããæ§ç¯ããå Žåãæ
å ±ãä¿åããããŒã¿ããŒã¹ãå¿
èŠã§ãã ãã®ãããç§ã¯ãã®æç€ºã®ããã«
mongodbãéžæã
ãŸãã ã Mongoã¯NoSQLããŒã¿ããŒã¹ã§ãã
ããã«
ã€ã³ã¹ããŒã«æé ããããŸã ãç§ã¯WindowsãŠãŒã¶ãŒãªã®ã§ãWindows
ã®ã€ã³ã¹ããŒã«æé ã«åŸããŸã
ã ã ã€ã³ã¹ããŒã«ãå®äºããããããã©ã«ãã§ããŒã27017ããªãã¹ã³ããMongoDBããŒã¢ã³ãèµ·åããŸãããããã£ãŠãçè«çã«ã¯ããã®ããŒãã«æ¥ç¶ããŠmongodbãµãŒããŒãšã¡ãã»ãŒãžã亀æããæ©äŒããããŸãã ããŒãã¹ã¯ãªãããä»ããŠãããè¡ãã«ã¯ã
mongodb module / driverãå¿
èŠ
ã§ã ã ãã®æé ã®
ãœãŒã¹ãã¡ã€ã«ãããŠã³ããŒãããå Žåãã¢ãžã¥ãŒã«ã¯æ¢ã«
package.jsonãã¡ã€ã«ã«è¿œå ãããŠããŸãã ããã§ãªãå Žåã¯ã
äŸåé¢ä¿ããããã£ã«ãmongodbãïŒã1.3.10ãã远å ãã
npm installã³ãã³ããå®è¡ããŸãã æ¬¡ã«ãmongodbãµãŒããŒãå®è¡ãããŠãããã©ããã確èªãããã¹ããäœæããŸãã
/tests/mongodb.spec.jsãã¡ã€ã«ïŒ
describe("MongoDB", function() { it("is there a server running", function(next) { var MongoClient = require('mongodb').MongoClient; MongoClient.connect('mongodb://127.0.0.1:27017/fastdelivery', function(err, db) { expect(err).toBe(null); next(); }); }); });
mongodbã¯ã©ã€ã¢ã³ã
ã¡ãœãã.connectã®ã³ãŒã«ããã¯é¢æ°ã¯ã
dbãªããžã§ã¯ããåãåããŸãã åŸã§ããŒã¿ã®ç®¡çã«äœ¿çšããŸãã ããã¯ãã¢ãã«å
ã§ã¢ã¯ã»ã¹ããå¿
èŠãããããšãæå³ããŸãã ããŒã¿ããŒã¹ãç
§äŒãããã³ã«æ°ãã
MongoClientãªããžã§ã¯ããäœæããããšã¯ãå§ãã§ããŸããã ãã®ãããExpressãµãŒããŒã®èµ·åãããŒã¿ããŒã¹ã«æ¥ç¶ããã³ãŒã«ããã¯é¢æ°ã«è»¢éããŸããã
MongoClient.connect('mongodb://127.0.0.1:27017/fastdelivery', function(err, db) { if(err) { console.log('Sorry, there is no mongo db server running.'); } else { var attachDB = function(req, res, next) { req.db = db; next(); }; http.createServer(app).listen(config.port, function(){ console.log('Express server listening on port ' + config.port); }); } });
ç°å¢æ§æèšå®ãã¡ã€ã«ããããããmongodbãµãŒããŒã®ãã¹ãåãšããŒããããã«é
眮ããæ¥ç¶URLãæ¬¡ã®ããã«å€æŽããããšããå§ãããŸãã
'mongodbïŒ//' + config.mongo.host + 'ïŒ' + config.mongo.port + '/ fastdelivery'
http.createServer颿°ã®åŒã³åºãã®çŽåã«è¿œå ããããã«ãŠã§ã¢é¢æ°
attachDBã«ç¹ã«æ³šæããŠ
ãã ãã ã ãã®å°ããªè¿œå ã®ãããã§ããªã¯ãšã¹ããªããžã§ã¯ãã®
.dbããããã£ãå
¥åããŸãã è¯ããã¥ãŒã¹ã¯ãã«ãŒã決å®äžã«ããã€ãã®æ©èœãèšå®ã§ããããšã§ãã äŸïŒ
app.get('/', attachDB, function(req, res, next) { ... })
ãããã£ãŠãExpressã¯ããããã
attachDB颿°
ãåŒã³åºããŠãã«ãŒããã³ãã©ãŒã«å
¥ãããã«ããŸãã ãããçºçãããšããªã¯ãšã¹ããªããžã§ã¯ãã«
.dbããããã£ãèšå®ãããããã䜿çšããŠããŒã¿ããŒã¹ã«ã¢ã¯ã»ã¹ã§ããŸãã
MVC
ç§ãã¡ã¯ãã¹ãŠ
MVCãã¿ãŒã³ã«ç²Ÿéã
ãŠããŸã ã åé¡ã¯ãExpressã§ãããé©çšããæ¹æ³ã§ãã ãããã«ãããããã¯è§£éã®åé¡ã§ãã æ¬¡ã®ããã€ãã®ç« ã§ã¯ãã¢ãã«ããã¥ãŒãã³ã³ãããŒã©ãŒãšããŠæ©èœããã¢ãžã¥ãŒã«ãäœæããŸãã
ã¢ãã«
ã¢ãã«ã¯ãã¢ããªã±ãŒã·ã§ã³ã®ããŒã¿ãåŠçãããã®ã§ãã
MongoClientãªããžã§ã¯ãã«ãã£ãŠè¿ããã
dbãªããžã§ã¯ããžã®ã¢ã¯ã»ã¹æš©ãå¿
èŠã§ãã ããŸããŸãªã¿ã€ãã®ã¢ãã«ãå¿
èŠã«ãªãå¯èœæ§ããããããã¢ãã«ã«ã¯ãããæ¡åŒµããæ¹æ³ãå¿
èŠã§ãã ããšãã°ã
BlogModelãŸãã¯
ContactsModelã¢ãã«ãäœæãã
å ŽåããããŸãã ãããè¡ãã«ã¯ãæåã«ãã¹ã
/tests/base.model.spec.jsãäœæããå¿
èŠããããŸãã ãããŠããããã®ãã¹ããäœæããããšã«ãããã¢ãã«ãå¿
èŠãªããšã ããè¡ãããã以å€ã¯äœãããªãããšãä¿èšŒã§ããŸãã
var Model = require("../models/Base"), dbMockup = {}; describe("Models", function() { it("should create a new model", function(next) { var model = new Model(dbMockup); expect(model.db).toBeDefined(); expect(model.extend).toBeDefined(); next(); }); it("should be extendable", function(next) { var model = new Model(dbMockup); var OtherTypeOfModel = model.extend({ myCustomModelMethod: function() { } }); var model2 = new OtherTypeOfModel(dbMockup); expect(model2.db).toBeDefined(); expect(model2.myCustomModelMethod).toBeDefined(); next(); }) });
å®éã®
dbãªããžã§ã¯ãã®ä»£ããã«ãã¢ãã¯ãªããžã§ã¯ããæž¡ãããšã«ããŸããã ããã¯ãåŸã§ç¹å®ã®äœãããã¹ããããå Žåã«è¡ãããŸããããã¯ãããŒã¿ããŒã¹ããã®ããŒã¿ã«äŸåããŸãã ãã®ããŒã¿ãæåã§å®çŸ©ããæ¹ãã¯ããã«ç°¡åã§ãã
ãããã¿ã€ã
module.exportsã倿Žããå¿
èŠããããŸãããå
ã®ã³ã³ã¹ãã©ã¯ã¿ãŒã¯ãã®ãŸãŸã«ããŠããå¿
èŠããããããã¡ãœããæ¡åŒµã®å®è£
ã¯å°ã
é£ããã§ãã 幞ããªããšã«ãã³ãŒãã®ããã©ãŒãã³ã¹ããã§ãã¯ãããã¹ãããã§ã«äœæããŠããŸãã äžèšã®ã³ãŒãã¹ããããã®ããŒãžã§ã³ã¯æ¬¡ã®ããã«ãªããŸãã
module.exports = function(db) { this.db = db; }; module.exports.prototype = { extend: function(properties) { var Child = module.exports; Child.prototype = module.exports.prototype; for(var key in properties) { Child.prototype[key] = properties[key]; } return Child; }, setDB: function(db) { this.db = db; }, collection: function() { if(this._collection) return this._collection; return this._collection = this.db.collection('fastdelivery-content'); } }
ããã§ã¯ã2ã€ã®ãã«ããŒã¡ãœãããå®çŸ©ãããŠããŸãã ããŒã¿ããŒã¹ããã®ã³ã¬ã¯ã·ã§ã³ã®
dbãªããžã§ã¯ããšã²ãã¿ãŒã®ã»ãã¿ãŒã
æåº
ãã¥ãŒã¯ç»é¢ã«æ
å ±ã衚瀺ããŸãã ç°¡åã«èšãã°ããã¥ãŒã¯ãã©ãŠã¶ãŒã«å¿çãéä¿¡ããã¯ã©ã¹ã§ãã Expressã¯ããããè¡ãç°¡åãªæ¹æ³ãæäŸããŸãã
res.render('index', { title: 'Express' });
å¿çãªããžã§ã¯ãã¯ãçæŽ»ã楜ã«ããåªããAPIãåããã©ãããŒã§ãã ãã ããç¬èªã®ã¢ãžã¥ãŒã«ãäœæããŠããã®æ©èœã«çµã¿èŸŒãããšã奜ã¿ãŸãã ãã¥ãŒã®æšæºãã£ã¬ã¯ããªã¯ãã³ãã¬ãŒãã«çœ®ãæãããããã¥ãŒã®å€ããã£ã¬ã¯ããªã¯
ããŒã¹ãã¥ãŒã¯ã©ã¹ãæäŸããŸãã
ãã®å°ããªå€æŽã«ã¯ãå¥ã®å€æŽãå¿
èŠã§ãã ãã³ãã¬ãŒããã¡ã€ã«ãå¥ã®ãã£ã¬ã¯ããªã«ããããšãExpressã«éç¥ããå¿
èŠããããŸãã
app.set('views', __dirname + '/templates');
ãŸããå¿
èŠãªãã®ããã¹ãŠæ±ºå®ãããã¹ããäœæããŸãããã®åŸãå®è£
ãéå§ããŸãã æ¬¡ã®èŠä»¶ãæºããã¢ãžã¥ãŒã«ãå¿
èŠã§ãã
- ãã®ã³ã³ã¹ãã©ã¯ã¿ãŒã¯ãå¿çãªããžã§ã¯ããšãã³ãã¬ãŒãåãåãåãå¿
èŠããããŸã
- ããŒã¿ãªããžã§ã¯ããåãå
¥ãããã³ãã¬ãŒãåºåã¡ãœãããå¿
èŠã§ãã
- æ¡åŒµå¯èœã§ãªããã°ãªããŸããã
é©ããããããŸããïŒãªããã¬ãŒã³ããŒã·ã§ã³ã¯ã©ã¹ãæ¡åŒµããå¿
èŠããã£ãã®ã§ããïŒ åœŒã¯
response.renderã¡ãœãããåŒã³åºãã ãã§ã¯ãããŸãããïŒ å®éãå®éã«ã¯ãå¥ã®ããããŒãéä¿¡ããããå¿çãªããžã§ã¯ããæäœãããããå¿
èŠãããå ŽåããããŸãã ããšãã°ãJSONã§éä¿¡ãããããŒã¿ãåŠçããŸãã
var data = {"developer": "Krasimir Tsonev"}; response.contentType('application/json'); response.send(JSON.stringify(data));
ãããæ¯åè¡ã代ããã«ã
HTMLView ã¯ã©ã¹ãš
JSONViewã¯ã©ã¹ã
çšæããããšã¯çŽ æŽãããããšã§ãã ãŸãã¯ãXMLããŒã¿ããã©ãŠã¶ã«éä¿¡ãã
XMLViewã¯ã©ã¹ã åãã³ãŒããç¹°ãè¿ãã³ããŒããŠè²Œãä»ãããããããã®ãããªæ©èœãæ¢ã«å®è£
ãããŠãã倧ããªWebã¢ããªã±ãŒã·ã§ã³ãäœæããæ¹ãç°¡åã§ãã
以äžã¯ã
/ views / Base.jsã¯ã©ã¹ã®ãã¹ãã§ãã
var View = require("../views/Base"); describe("Base view", function() { it("create and render new view", function(next) { var responseMockup = { render: function(template, data) { expect(data.myProperty).toBe('value'); expect(template).toBe('template-file'); next(); } } var v = new View(responseMockup, 'template-file'); v.render({myProperty: 'value'}); }); it("should be extendable", function(next) { var v = new View(); var OtherView = v.extend({ render: function(data) { expect(data.prop).toBe('yes'); next(); } }); var otherViewInstance = new OtherView(); expect(otherViewInstance.render).toBeDefined(); otherViewInstance.render({prop: 'yes'}); }); });
ã¬ã³ããªã³ã°ïŒèŠèŠåïŒããã¹ãããã«ã¯ãã¬ã€ã¢ãŠããäœæããå¿
èŠããããŸããã ãã®å Žåããã¹ãã®æåã®éšåã§ãExpressãã¬ãŒã ã¯ãŒã¯ã®å¿çãªããžã§ã¯ããã·ãã¥ã¬ãŒããããªããžã§ã¯ããäœæããŸããã ãã¹ãã®2çªç®ã®éšåã§ã¯ãåºæ¬ã¯ã©ã¹ãç¶æ¿ããç¬èªã®ã¬ã³ããªã³ã°ã¡ãœããã䜿çšããå¥ã®
Viewã¯ã©ã¹ãäœæããŸããã
ã¯ã©ã¹ã³ãŒã
/views/Base.js ïŒ
module.exports = function(response, template) { this.response = response; this.template = template; }; module.exports.prototype = { extend: function(properties) { var Child = module.exports; Child.prototype = module.exports.prototype; for(var key in properties) { Child.prototype[key] = properties[key]; } return Child; }, render: function(data) { if(this.response && this.template) { this.response.render(this.template, data); } } }
ããã§ããã¹ãçšã®ãã£ã¬ã¯ããªã«3ã€ã®ãã¹ããããã
jasmine-node ./testsã³ãã³ããå®è¡ãããšãçµæã¯æ¬¡ã®ããã«ãªããŸãã
Finished in 0.009 seconds 7 tests, 18 assertions, 0 failures, 0 skipped
ã³ã³ãããŒã©ãŒ
ã«ãŒãã«ã€ããŠè©±ããã©ã®ããã«æ±ºå®ããã®ãèŠããŠããŸããïŒ
app.get('/', routes.index);
äžèšã®äŸã®ã«ãŒãã®åŸã«ããèšå·ã/ãã¯ã³ã³ãããŒã©ãŒã§ãã ããã¯ã
ãªã¯ãšã¹ã ã
ã¬ã¹ãã³ã¹ ãã³ãŒã«ããã¯é¢æ°
nextïŒïŒãåãåãããã«ãŠã§ã¢é¢æ°ã§ãã
exports.index = function(req, res, next) { res.render('index', { title: 'Express' }); };
äžèšã¯ãExpressã䜿çšããå Žåã®ã³ã³ãããŒã©ãŒã®å€èгã説æããŠããŸãã
expressïŒ1ïŒã³ãã³ãã¯ã
routesãšããååã§ãã£ã¬ã¯ããªãäœæããŸãããç§ãã¡ã®å Žåã¯ã
controllersãšåŒã°ããæ¹ãè¯ãã§ãããã ãã¡ã€ã«æ§é ããã®ãã¿ãŒã³ã«äžèŽããããã«ååã倿ŽããŸããã
åãªãå°ããªã¢ããªã±ãŒã·ã§ã³ä»¥äžã®ãã®ãæ§ç¯ããŠãããããæ¡åŒµå¯èœãªåºæ¬ã¯ã©ã¹ãäœæããããšããå§ãããŸãã ãã¹ãŠã®ã³ã³ãããŒã©ãŒã«æ©èœã远å ããå¿
èŠãããå Žåããã®åºæ¬ã¯ã©ã¹ã¯ã¢ããªã³ãå®è£
ããã®ã«æé©ãªå Žæã§ãã ç¹°ãè¿ããŸãããç§ã¯æåã«ãã¹ããæžããŠããã®ã§ãåºæ¬ã¯ã©ã¹ã«å¿
èŠãªãã®ãå®çŸ©ããŸãããïŒ
- ãªããžã§ã¯ããååŸããŠæ°ããåã€ã³ã¹ã¿ã³ã¹ãè¿ãæ¡åŒµå¯èœãªã¡ãœãããå¿
èŠã§ã
- åã€ã³ã¹ã¿ã³ã¹ã«ã¯runã¡ãœãããå¿
èŠã§ããããã¯å€ãè¯ãããã«ãŠã§ã¢é¢æ°ã§ã
- ã³ã³ãããŒã©ãèå¥ããååããããã£ãå¿
èŠã§ã
- åºæ¬ã¯ã©ã¹ããç¶æ¿ãããç¬ç«ãããªããžã§ã¯ããäœæã§ããã¯ãã§ãã
ã»ãã®æ°ç¹ã§ãããåŸã§æ©èœã远å ããããšãã§ããŸãã
ãã¹ãã¯æ¬¡ã®ããã«ãªããŸãã
var BaseController = require("../controllers/Base"); describe("Base controller", function() { it("should have a method extend which returns a child instance", function(next) { expect(BaseController.extend).toBeDefined(); var child = BaseController.extend({ name: "my child controller" }); expect(child.run).toBeDefined(); expect(child.name).toBe("my child controller"); next(); }); it("should be able to create different childs", function(next) { var childA = BaseController.extend({ name: "child A", customProperty: 'value' }); var childB = BaseController.extend({ name: "child B" }); expect(childA.name).not.toBe(childB.name); expect(childB.customProperty).not.toBeDefined(); next(); }); });
以äžã¯
/controllers/Base.jsã®å®è£
ã§ãïŒ
var _ = require("underscore"); module.exports = { name: "base", extend: function(child) { return _.extend({}, this, child); }, run: function(req, res, next) { } }
ãã¡ãããååå«ã¯ã©ã¹ã«ã¯ãç¬èªã®ããžãã¯ãå®è£
ããç¬èªã®
runã¡ãœãããå¿
èŠã§ãã
FastDelivery Webãµã€ã
ãŸããMVCã¢ãŒããã¯ãã£ã«é©ããã¯ã©ã¹ã®ã»ãããããããã¹ãŠã®ã¢ãžã¥ãŒã«ããã¹ãã§ã«ããŒããŸããã ããã§ãæ¶ç©ºã®äŒç€ŸFastDeliveryã®ãµã€ããåŒãç¶ãæ±ãæºåãã§ããŸããã ãµã€ãã2ã€ã®éšåïŒãŠãŒã¶ãŒéšåãšç®¡çããã«ïŒã§æ§æãããããšãæ³åããŠã¿ãŸãããã ãŠãŒã¶ãŒéšåã¯ãããŒã¿ããŒã¹ã«ä¿åãããŠããæ
å ±ããšã³ããŠãŒã¶ãŒã«æç€ºããããã®ãã®ã§ãã
管çããã«ã¯ããã®æ
å ±ã管çããããã®ãã®ã§ããæåŸããå§ããŸããããå¶åŸ¡ç€
æåã«ã管çããã«ããŒãžãæäŸããã·ã³ãã«ãªã³ã³ãããŒã©ãŒãäœæããŸãããããã¡ã€ã«/controllers/Admin.jsïŒ var BaseController = require("./Base"), View = require("../views/Base"); module.exports = BaseController.extend({ name: "Admin", run: function(req, res, next) { var v = new View(res, 'admin'); v.render({ title: 'Administration', content: 'Welcome to the control panel' }); } });
ã³ã³ãããŒã©ãŒãšãã¥ãŒã®äºåã«äœæãããåºæ¬ã¯ã©ã¹ã䜿çšããŠã管çããã«ã®ãšã³ããªãã€ã³ããç°¡åã«äœæã§ããŸããViewã¯ã©ã¹ã¯ããã³ãã¬ãŒããã¡ã€ã«ã®ååãåãå
¥ããŸããäžèšã®ã³ãŒãã«ãããšããã¡ã€ã«ã¯admin.hjsãšããååã§ã/ templatesãã£ã¬ã¯ããªã«é
眮ããå¿
èŠããããŸãããã®å
å®¹ã¯æ¬¡ã®ããã«ãªããŸãã <!DOCTYPE html> <html> <head> <title>{{ title }}</title> <link rel='stylesheet' href='/stylesheets/style.css' /> </head> <body> <div class="container"> <h1>{{ content }}</h1> </div> </body> </html>
ïŒãã®æç€ºãçãèªã¿ãããããããã«ãããã§ã¯åãã³ãã¬ãŒãã®ã³ãŒããæäŸããŸãããGitHubãããœãŒã¹ã³ãŒããããŠã³ããŒãããããšã匷ããå§ãããŸããïŒæ¬¡ã«ãã³ã³ãããŒã©ãŒã衚瀺ããããã«ãã¢ããªã«ã«ãŒãã远å ããå¿
èŠããããŸãã.jsïŒ var Admin = require('./controllers/Admin'); ... var attachDB = function(req, res, next) { req.db = db; next(); }; ... app.all('/admin*', attachDB, function(req, res, next) { Admin.run(req, res, next); });
Admin.runã¡ãœãããããã«ãŠã§ã¢é¢æ°ãšããŠçŽæ¥éä¿¡ããªãããšã«æ³šæããŠãã ãããããã¯ãã³ã³ããã¹ããä¿æããããã§ãããããè¡ãå ŽåïŒ app.all('/admin*', Admin.run);
Adminãªããžã§ã¯ãã®thisãšããåèªã¯ããŸã£ããå¥ã®å ŽæãæããŸãã管çããã«ã®ä¿è·
/ adminã§å§ãŸãåããŒãžã¯ä¿è·ããå¿
èŠããããŸãããããå®çŸããããã«ãçµã¿èŸŒã¿ã®Expressããã«ãŠã§ã¢æ©èœã§ããSessionsã䜿çšããŸããã»ãã·ã§ã³ãšåŒã°ãããªã¯ãšã¹ãã«ãªããžã§ã¯ãã远å ããã ãã§ããæ¬¡ã®2ã€ã®ããšãè¡ãããã«ã管çã³ã³ãããŒã©ãŒã倿Žããå¿
èŠããããŸãã- ã»ãã·ã§ã³ãå©çšå¯èœãã©ããã確èªããå¿
èŠããããŸããããã§ãªãå Žåã¯ãèªèšŒãã©ãŒã ã衚瀺ããŸã
- ãŠãŒã¶ãŒåãšãã¹ã¯ãŒããããŒã¿ããŒã¹ã®ãŠãŒã¶ãŒåãšãã¹ã¯ãŒããšäžèŽããå Žåãæ¿èªãã©ãŒã ããéä¿¡ãããããŒã¿ãåãå
¥ãããŠãŒã¶ãŒãæ¿èªããå¿
èŠããããŸã
以äžã¯ãäžèšã®èŠä»¶ãæºããå°ããªãã«ããŒé¢æ°ã§ãã authorize: function(req) { return ( req.session && req.session.fastdelivery && req.session.fastdelivery === true ) || ( req.body && req.body.username === this.username && req.body.password === this.password ); }
æåã«ãã»ãã·ã§ã³ãªããžã§ã¯ããä»ããŠãŠãŒã¶ãŒãèªèããããšããã¹ã¯ãªãããå®è¡ãããŸããæ¬¡ã«ããã©ãŒã ããã®ããŒã¿ãéä¿¡ããããã©ããã確èªããŸãããã®å Žåãããã«ãŠã§ã¢é¢æ°bodyParserãçšæããrequest.bodyãªããžã§ã¯ããããã©ãŒã ã®ããŒã¿ãå©çšã§ããŸããæ¬¡ã«ããŠãŒã¶ãŒåãšãã¹ã¯ãŒããäžèŽãããã©ããã確èªããŸãããããŠãã³ã³ãããŒã©ãŒããrunã¡ãœãããå®è¡ãããšããæ¥ãŸããããã®ã¡ãœããã¯ãæ°ããäœæããããã«ããŒïŒãã¹ãŠã®ã³ã³ãããŒã©ãŒã®åºæ¬ã©ãããŒïŒã䜿çšããŸãããã§ãã¯ïŒãŠãŒã¶ãŒãæ¿èªãããŠããå Žåãã³ã³ãããŒã«ããã«ã衚瀺ããããã§ãªãå Žåã¯æ¿èªããŒãžã衚瀺ããŸãã run: function(req, res, next) { if(this.authorize(req)) { req.session.fastdelivery = true; req.session.save(function(err) { var v = new View(res, 'admin'); v.render({ title: 'Administration', content: 'Welcome to the control panel' }); }); } else { var v = new View(res, 'admin-login'); v.render({ title: 'Please login' }); } }
ã³ã³ãã³ã管ç
ãã®èšäºã®åé ã§è¿°ã¹ãããã«ã管çãããã®ããããããããŸããããã»ã¹ãç°¡çŽ åããããã«ã1ã€ã®ã³ã¬ã¯ã·ã§ã³ã«ãã¹ãŠã®ããŒã¿ãä¿æããŸããããåãšã³ããªã«ã¯ãã¿ã€ãã«ãããã¹ããç»åãããã³ã¿ã€ãã®ããããã£ããããŸããåŸè
ãã¬ã³ãŒãã®ææè
ãæ±ºå®ããŸããããšãã°ãé£çµ¡å
ããŒãžã«ã¯ãé£çµ¡å
ãã¿ã€ãã®ãšã³ããªã1ã€ã ãå¿
èŠã§ãããããã°ããŒãžã«ã¯ããã«å€ãã®ãšã³ããªãå¿
èŠã§ãããã®ããããšã³ããªã远å ãåé€ãç·šéããã«ã¯ã3ã€ã®æ°ããããŒãžã远å ããå¿
èŠããããŸããæ°ãããã³ãã¬ãŒãã®äœæãã¹ã¿ã€ãªã³ã°ãããã³ã³ã³ãããŒã©ãŒãžã®æ°ãããã®ã®è¿œå ãéå§ããåã«ãMongoDBãµãŒããŒãšã¢ããªã±ãŒã·ã§ã³ã®éã«ããã¢ãã«ã®ã¯ã©ã¹ãäœæããå¿
èŠããããŸãããã¡ããã䟿å©ãªAPIãæäŸããŸãã
ã¢ãã«ã¯ãåã¬ã³ãŒãã«äžæã®IDãçæããŸããåŸã§æ
å ±ãæŽæ°ããããã«å¿
èŠã«ãªããŸããé£çµ¡å
ããŒãžã«æ°ãããšã³ããªã远å ããå¿
èŠãããå Žåãæ¬¡ã®ããã«èšè¿°ã§ããŸãã var model = new (require("../models/ContentModel")); model.insert({ title: "Contacts", text: "...", type: "contacts" });
ãã®ãããmongodbã³ã¬ã¯ã·ã§ã³ã«ã¯éåžžã«åªããããŒã¿ç®¡çAPIããããŸããããã§ããã®ãã¹ãŠã®æ©èœã䜿çšããUIãäœæããæºåãã§ããŸãããä»åã¯ã管çã³ã³ãããŒã©ãŒãããªã倿ŽãããŸããã¿ã¹ã¯ãç°¡çŽ åããããã«ã远å ããã¬ã³ãŒãã®ãªã¹ããšãã¬ã³ãŒãã远å /ç·šéããããã®ãã©ãŒã ãçµã¿åãããããšã«ããŸãããäžã®ã¹ã¯ãªãŒã³ã·ã§ããã§ãããããã«ãããŒãžã®å·ŠåŽã¯ãªã¹ãçšã«ãå³åŽã¯ãã©ãŒã çšã«äºçŽãããŠããŸãã
ãã¹ãŠã®ã³ã³ãããŒã«ã1ããŒãžã«è¡šç€ºãããšããããšã¯ããã®ããŒãžãã¬ã³ããªã³ã°ããéšåã«çŠç¹ãåãããå¿
èŠãããããšãæå³ããŸããå
·äœçã«ã¯ããã³ãã¬ãŒãã«éä¿¡ããããŒã¿ã«çŠç¹ãåãããå¿
èŠããããŸãããããã£ãŠã次ã®ãããªããã€ãã®çµ±åããããã«ããŒé¢æ°ãäœæããŸããã var self = this; ... var v = new View(res, 'admin'); self.del(req, function() { self.form(req, res, function(formMarkup) { self.list(function(listMarkup) { v.render({ title: 'Administration', content: 'Welcome to the control panel', list: listMarkup, form: formMarkup }); }); }); });
ã¯ããããã¯å°ãlooksãã§ãããããã¯ç§ãæãããã«æ£ç¢ºã«åäœããŸããæåã®ãã«ããŒã¯delã¡ãœããã§ãçŸåšã®GETãã©ã¡ãŒã¿ãŒããã§ãã¯ããaction = deleteïŒid = [ã¬ã³ãŒãã®ID]ã®çµã¿åãããèŠã€ããå Žåã察å¿ããããŒã¿ãã³ã¬ã¯ã·ã§ã³ããåé€ããŸãã2çªç®ã®é¢æ°ã¯formãšåŒã°ããäž»ã«ããŒãžã®å³åŽã«ãã©ãŒã ã衚瀺ããŸãããã®é¢æ°ã¯ããã©ãŒã ããµãŒããŒã«å°çãããã©ããã確èªããããŒã¿ããŒã¹å
ã®ã¬ã³ãŒããé©åã«æŽæ°ãŸãã¯äœæããŸããæåŸã«ãlistã¡ãœããã¯æ
å ±ãååŸããåŸã§ãã³ãã¬ãŒãã«éä¿¡ãããHTMLããŒãã«ãæºåããŸããããã3ã€ã®ãã«ããŒã®å®è£
ã¯ããã®åœä»€ã®ãœãŒã¹ã³ãŒãã«ãããŸãã以äžã¯ããã¡ã€ã«ã®ã¢ããããŒããåŠçãã颿°ã§ãã handleFileUpload: function(req) { if(!req.files || !req.files.picture || !req.files.picture.name) { return req.body.currentPicture || ''; } var data = fs.readFileSync(req.files.picture.path); var fileName = req.files.picture.name; var uid = crypto.randomBytes(10).toString('hex'); var dir = __dirname + "/../public/uploads/" + uid; fs.mkdirSync(dir, '0777'); fs.writeFileSync(dir + "/" + fileName, data); return '/uploads/' + uid + "/" + fileName; }
ãã¡ã€ã«ããµãŒããŒã«éä¿¡ããããšãèŠæ±ãªããžã§ã¯ãã®.filesããããã£ã«å¯Ÿå¿ããããŒã¿ãå
¥åãããŸãããã®å Žåãæ¬¡ã®HTMLèŠçŽ ããããŸãã <input type="file" name="picture" />
ããã¯ãreq.files.pictureãä»ããŠéä¿¡ãããããŒã¿ã«ã¢ã¯ã»ã¹ã§ããããšãæå³ããŸããäžèšã®äŸã«ç€ºãããã«ãreq.files.picture.pathã䜿çšããŠããã¡ã€ã«ã®æªå å·¥ïŒæªå å·¥ïŒã³ã³ãã³ããååŸããŸããããã«ãéä¿¡ããããã¡ã€ã«ã¯ããŠã³ããŒãçšã«äœæããããã£ã¬ã¯ããªã«ä¿åãããæåŸã«ããã®ãã¡ã€ã«ã«å¯Ÿå¿ããURLãè¿ãããŸãããããã®æäœã¯ãã¹ãŠåæã§ãããéåæããŒãžã§ã³ã®readFileSyncãmkdirSyncãããã³writeFileSyncã¡ãœããã䜿çšããããšããå§ãããŸãããŠãŒã¶ãŒéš
æãé£ããéšåã®æºåãã§ããŸããã管çããã«ãåäœããããŒã¿ããŒã¹ã«ä¿åãããŠããæ
å ±ã«ã¢ã¯ã»ã¹ã§ããContentModelã¯ã©ã¹ããããŸããããã§å¿
èŠãªã®ã¯ããŠãŒã¶ãŒéšåã®ã³ã³ãããŒã©ãŒãäœæããä¿åãããã³ã³ãã³ãã«ãã€ã³ãããããšã§ãããããããŒã ããŒãžã®ã³ã³ãããŒã©ãŒã§ã- /controllers/Home.js module.exports = BaseController.extend({ name: "Home", content: null, run: function(req, res, next) { model.setDB(req.db); var self = this; this.getContent(function() { var v = new View(res, 'home'); v.render(self.content); }) }, getContent: function(callback) { var self = this; this.content = {}; model.getlist(function(err, records) { ... storing data to content object model.getlist(function(err, records) { ... storing data to content object callback(); }, { type: 'blog' }); }, { type: 'home' }); } });
ããŒã ããŒãžã«ã¯ãã¿ã€ãããhomeãã®1ã€ã®ãšã³ããªãšãã¿ã€ãããblogãã®4ã€ã®ãšã³ããªãå¿
èŠã§ããã³ã³ãããŒã©ãŒã®æºåãã§ããããapp.jsã§ã³ã³ãããŒã©ãŒãžã®ã«ãŒãã远å ããå¿
èŠããããŸãã app.all('/', attachDB, function(req, res, next) { Home.run(req, res, next); });
å床dbãªããžã§ã¯ãããªã¯ãšã¹ããªããžã§ã¯ãã«ã¢ã¿ããããŸããã»ãšãã©ã®å Žåã管çããã«ã®äœææã«å®è¡ããããã»ã¹ãšåãã§ãããŠãŒã¶ãŒããŒãã®ä»ã®ããŒãžã¯ãã¢ãã«ã¯ã©ã¹ã䜿çšããŠããŒã¿ãåä¿¡ããã³ã³ãããŒã©ãŒãããããã¡ããã«ãŒãããããšããç¹ã§ãã»ãšãã©åãã§ããããã«è©³ãã説æããã2ã€ã®è峿·±ãåŽé¢ããããŸããæåã¯ããã°ããŒãžã«ãªã³ã¯ãããŠããŸãããã®ããŒãžã«ã¯ããã¹ãŠã®èšäºãš1ã€ã®èšäºã衚瀺ãããŸããã«ãŒãã®ãã¢ãå®çŸ©ããŸãã app.all('/blog/:id', attachDB, function(req, res, next) { Blog.runArticle(req, res, next); }); app.all('/blog', attachDB, function(req, res, next) { Blog.run(req, res, next); });
äž¡æ¹ãšãåãã³ã³ãããŒã©ãŒïŒBlogã䜿çšããŸããã2ã€ã®ç°ãªãrunã¡ãœãããåŒã³åºããŸããè¡/ blog /ïŒidã«æ³šæããŠãã ããããã®ã«ãŒãã¯ã/ blog / 4e3455635b4a6f6dccfaa1e50ee71f1cde75222bãªã©ã®URLã«äžèŽããŸãããã®é·ãããã·ã¥ã«ã¯ãreq.params.idããããã£ããã¢ã¯ã»ã¹ã§ããŸããã€ãŸããåçãã©ã¡ãŒã¿ãŒãå®çŸ©ã§ããŸããç§ãã¡ã®å Žåãããã¯ãšã³ããªïŒèšäºïŒã®IDã«ãªããŸããããã«ã€ããŠåŠç¿ããã®ã§ãèšäºããšã«äžæã®ããŒãžãçæã§ããŸãã2çªç®ã®è峿·±ãåŽé¢ã¯ããµãŒãã¹ããã£ãªã¢ãé£çµ¡å
ã®ããŒãžãã©ã®ããã«äœæãããã§ãããããã®ãã¹ãŠãããŒã¿ããŒã¹ã®1ã€ã®ã¬ã³ãŒãã®ã¿ã䜿çšããããšã¯æããã§ããåããŒãžã«ã³ã³ãããŒã©ãŒãäœæããå¿
èŠãããå Žåã¯ãåãã³ãŒããã³ããŒããŠè²Œãä»ãããã®äžã®typeãã£ãŒã«ãã倿Žããã ãã§ããrunã¡ãœããã§ã¬ã³ãŒãã¿ã€ããåãå
¥ããåäžã®ã³ã³ãããŒã©ãŒã䜿çšããŠããããè¡ãããè¯ãæ¹æ³ããããŸããã«ãŒãã¯æ¬¡ã®ãšããã§ãã app.all('/services', attachDB, function(req, res, next) { Page.run('services', req, res, next); }); app.all('/careers', attachDB, function(req, res, next) { Page.run('careers', req, res, next); }); app.all('/contacts', attachDB, function(req, res, next) { Page.run('contacts', req, res, next); });
ãããŠãã³ã³ãããŒã©ãŒã¯æ¬¡ã®ããã«ãªããŸãã module.exports = BaseController.extend({ name: "Page", content: null, run: function(type, req, res, next) { model.setDB(req.db); var self = this; this.getContent(type, function() { var v = new View(res, 'inner'); v.render(self.content); }); }, getContent: function(type, callback) { var self = this; this.content = {} model.getlist(function(err, records) { if(records.length > 0) { self.content = records[0]; } callback(); }, { type: type }); } });
å±é
Express Webãµã€ãããããã€ããããšã¯ãNode.jsã«ä»ã®ã¢ããªã±ãŒã·ã§ã³ããããã€ããããšãšæ¬è³ªçã«éãã¯ãããŸããã- ãã¡ã€ã«ã¯ãµãŒããŒã«ã¢ããããŒããããŸã
- ããŒãããã»ã¹ã忢ããå¿
èŠããããŸãïŒå®è¡äžã®å ŽåïŒ
- å¿
èŠãªäŸåé¢ä¿ããã¹ãŠã€ã³ã¹ããŒã«ããã«ã¯ãnpm installã³ãã³ããå®è¡ããŸã
- ã¡ã€ã³ããŒãã¹ã¯ãªãããå床å®è¡ãããŸã
Nodeã¯éåžžã«æ°ãã補åã§ããããã¹ãŠãæåŸ
ã©ããã«æ©èœããããã§ã¯ãããŸããããåžžã«æ¹åãè¡ãããŠããããšã«æ³šæããŠãã ãããããšãã°ãforeverã¢ãžã¥ãŒã«ã¯Node.jsã®ç¶ç¶çãªåäœãä¿èšŒããŸããæ¬¡ã®ã³ãã³ããå®è¡ããŠå®è¡ã§ããŸãã forever start yourapp.js
ããã¯ãµãŒããŒã§äœ¿çšãããã®ã§ãããã®å°ããªããŒã«ã¯ã1ã€ã®å€§ããªåé¡ã解決ããŸããnode yourapp.jsã³ãã³ãã䜿çšããŠã¢ããªã±ãŒã·ã§ã³ãèµ·åãããšãã¹ã¯ãªããã倱æãããšããã«ãµãŒããŒãã¯ã©ãã·ã¥ããŸãããæ°žä¹
ã«ã¢ããªã±ãŒã·ã§ã³ãåèµ·åããã ãã§ããç§ã¯ã·ã¹ãã 管çè
ã§ã¯ãããŸããããApacheãšNginxã§ããŒãã¢ããªã±ãŒã·ã§ã³ãçµ±åããçµéšãå
±æããããšæããŸããçµ±åã¯éçºããã»ã¹ã®äžéšã ãšèããŠããããã§ãããåãã®ããã«ãApacheã¯éåžžããŒã80ã§å®è¡ãããŸããã€ãŸããlocalhostãŸãã¯localhostã®ãã©ãŠã¶ãŒã«ã¢ã¯ã»ã¹ãããšïŒ80ãApacheãµãŒããŒãæäŸããããŒãžã衚瀺ãããŸãããããããããŒãã¹ã¯ãªããã¯å¥ã®ããŒãã§ãªãã¹ã³ããŠããŸãããããã£ãŠãèŠæ±ãåä¿¡ããŠââç®çã®ããŒãã«éä¿¡ããä»®æ³ãã¹ãã远å ããå¿
èŠããããŸããããšãã°ãã¢ãã¬ã¹expresscompletewebsite.devã®äžã§ãããŒã«ã«ã®ApacheãµãŒããŒã§äœæããã°ããã®ãµã€ãããã¹ãããå¿
èŠããããŸããæåã«è¡ãå¿
èŠãããã®ã¯ããã¹ããã¡ã€ã«ã«ãã¡ã€ã³ã远å ããããšã§ãã 127.0.0.1 expresscompletewebsite.dev
ãã®åŸãApacheãµãŒããŒã®æ§æãã£ã¬ã¯ããªã«ããhttpd-vhosts.confãã¡ã€ã«ã倿Žããå¿
èŠããããŸãã
ãµãŒããŒã¯ããŒã80ããã®èŠæ±ãåãå
¥ããŸãããããŒãã¹ã¯ãªããããªãã¹ã³ããããŒã3000ã«èŠæ±ã転éããŸããNginxã®æ§æã¯ã¯ããã«ç°¡åã§ãççŽã«èšã£ãŠãNode.jsããŒã¹ã®ã¢ããªã±ãŒã·ã§ã³ããã¹ãããããã®æè¯ã®éžæã§ãã Apacheæ§æãšåæ§ã«ãhostsãã¡ã€ã«ã«ãã¡ã€ã³ã远å ããå¿
èŠããããŸãããã®åŸãNginxãã€ã³ã¹ããŒã«ãããŠããå Žæã«ãã/ sites-enabledãã£ã¬ã¯ããªã«æ°ãããã¡ã€ã«ãäœæããŸãããã¡ã€ã«ã®å
å®¹ã¯æ¬¡ã®ããã«ãªããŸãã server { listen 80; server_name expresscompletewebsite.dev location / { proxy_pass http://127.0.0.1:3000; proxy_set_header Host $http_host; } }
åããã¹ãæ§æã§ApacheãšNginxãåæã«èµ·åããããšã¯ã§ããªãããšã«æ³šæããŠãã ãããããã¯ãã©ã¡ããããŒã80ã§ãªãã¹ã³ããããã§ããããã«ãæŠéãµãŒããŒã§äžèšã®ã³ãŒãã¹ããããã䜿çšããå Žåã¯ãã€ã³ã¿ãŒãããã§ãã詳现ãªãµãŒããŒæ§ææ
å ±ãæ€çŽ¢ã§ããŸããç§ãèšã£ãããã«ãç§ã¯ãã®åéã®å°éå®¶ã§ã¯ãããŸããããããã«
Expressã¯ãWebã¢ããªã±ãŒã·ã§ã³ãæ§ç¯ããããã®åªããåºç€ãæäŸããåªãããã¬ãŒã ã¯ãŒã¯ã§ããããªãèªèº«ãèŠãããšãã§ããããã«ãããã¯éžæã®åé¡ããããã©ã®ããã«æ¡åŒµãããããããŠããã§äœã䜿ããã ãã§ããããã€ãã®çŽ æŽãããããã«ãŠã§ã¢ã䜿çšããŠã«ãŒãã³ã¿ã¹ã¯ãç°¡çŽ åããéçºè
ã«ãšã£ãŠæããããããã®ãå®è£
ããããã»ã¹ãæ®ããŸãããœãŒã¹ã³ãŒã
GitHubã®ãã®èšäºã§äœæããWebãµã€ãã®ãœãŒã¹ã³ãŒãã¯https://github.com/tutsplus/build-complete-website-expressjsã§ããåå²ããŠã¢ããã°ã¬ãŒãããŠãã ããããŠã§ããµã€ããç«ã¡äžããããã®æ®µéçãªã¬ã€ãã¯æ¬¡ã®ãšããã§ãã- ãœãŒã¹ã³ãŒããããŠã³ããŒããã
- ããŠã³ããŒãããã¢ããªã±ãŒã·ã§ã³ã®ãã£ã¬ã¯ããªã«ç§»åããŸã
- npm installãå®è¡ãã
- mongodbããŒã¢ã³ãå®è¡ãã
- ããŒãapp.jsãå®è¡ããŸã