µ¼Óï
Ëæ×Å Backbone µÈÀÏÅÆ¿ò¼ÜµÄÖð½¥Ë¥ÍË£¬Ç°¶Ë MVC ·¢Õ¹»ºÂý£¬ÓÐÖð½¥±» MVVM/Flux ËùÈ¡´úµÄÇ÷ÊÆ¡£
È»¶ø£¬×ݹ۽ü¼¸ÄêµÄ·¢Õ¹£¬¿ÉÒÔ·¢ÏÖÒ»µã£¬React/Vue ºÍ Redux/Vuex ÊÇ·Ö±ðÔÚ MVC
ÖÐµÄ View ²ãºÍ Model ²ã×öÁ˽øÒ»²½·¢Õ¹¡£Èç¹û MVC ÖÐµÄ Controller ²ãÒ²ÍÆ½øÒ»²½£¬½«µÃµ½Ò»ÖÖÉý¼¶°æµÄ
MVC£¬ÎÒÃdzÆÖ®Îª IMVC£¨Í¬¹¹ MVC£©¡£
IMVC ¿ÉÒÔʵÏÖÒ»·Ý´úÂëÔÚ·þÎñ¶ËºÍä¯ÀÀÆ÷¶Ë½Ô¿ÉÔËÐУ¬¾ß±¸µ¥Ò³Ó¦ÓúͶàÒ³Ó¦ÓõÄËùÓÐÓÅÊÆ£¬²¢ÇÒ¿ÉÒÔÕâÁ½ÖÖģʽÀïͨ¹ýÅäÖÃÏî½øÐÐ×ÔÓÉÇл»¡£ÅäºÏ
Node.js¡¢Webpack¡¢Babel µÈ»ù´¡ÉèÊ©£¬ÎÒÃÇ¿ÉÒԵõ½Ïà±È֮ǰ¸ü¼ÓÍêÉÆµÄÒ»ÖÖǰ¶Ë¼Ü¹¹¡£
1¡¢Í¬¹¹µÄ¸ÅÄîºÍÒâÒå
1.1¡¢isomorphic ÊÇʲô£¿
isomorphic£¬¶Á×÷[?a?s?¡¯m?:f?k]£¬Òâ˼ÊÇ£ºÍ¬Ðεģ¬Í¬¹¹µÄ¡£
ά»ù°Ù¿Æ¶ÔËüµÄÃèÊöÊÇ£ºÍ¬¹¹ÊÇÔÚÊýѧ¶ÔÏóÖ®¼ä¶¨ÒåµÄÒ»ÀàÓ³Éä,ËüÄܽÒʾ³öÔÚÕâЩ¶ÔÏóµÄÊôÐÔ»òÕß²Ù×÷Ö®¼ä´æÔڵĹØÏµ¡£ÈôÁ½¸öÊýѧ½á¹¹Ö®¼ä´æÔÚͬ¹¹Ó³É䣬ÄÇôÕâÁ½¸ö½á¹¹½Ð×öÊÇͬ¹¹µÄ¡£Ò»°ãÀ´Ëµ£¬Èç¹ûºöÂÔµôͬ¹¹µÄ¶ÔÏóµÄÊôÐÔ»ò²Ù×÷µÄ¾ßÌ嶨Ò壬µ¥´Ó½á¹¹ÉϽ²£¬Í¬¹¹µÄ¶ÔÏóÊÇÍêÈ«µÈ¼ÛµÄ¡£
ͬ¹¹£¬Ò²±»»¯ÓÃÔÚÎïÀí¡¢»¯Ñ§ÒÔ¼°¼ÆËã»úµÈÆäËûÁìÓò¡£
1.2¡¢isomorphic javascript
isomorphic javascript£¨Í¬¹¹ js£©£¬ÊÇÖ¸Ò»·Ý js ´úÂ룬¼ÈÈ»¿ÉÒÔÅÜÔÚä¯ÀÀÆ÷¶Ë£¬Ò²¿ÉÒÔÅÜÔÚ·þÎñ¶Ë¡£

ͼ1
ͬ¹¹ js µÄ·¢Õ¹ÀúÊ·£¬±È progressive web app »¹ÒªÔçºÜ¶à¡£2009 Ä꣬ node.js
ÎÊÊÀ£¬¸øÓèÎÒÃÇǰºó¶ËͳһÓïÑÔµÄÏëÏ󣻸ü½øÒ»²½µÄ£¬Ç°ºó¶Ë¹«ÓÃÒ»Ì×´úÂ룬Ҳ²»ÊDz»¿ÉÄÜ¡£
ÓÐÒ»¸öÍøÕ¾ isomorphic.net£¬×¨ÃÅÊÕ¼¯¸úͬ¹¹ js Ïà¹ØµÄÎÄÕºÍÏîÄ¿¡£´ÓÀïÃæµÄÎÄÕÂÁбíÀ´¿´£¬ÔçÔÚ
2011 ÄêµÄʱºò£¬Òµ½çÒѾ¿ªÊ¼Ì½ÌÖͬ¹¹ js£¬²¢ÈÏΪÕ⽫ÊÇδÀ´µÄÇ÷ÊÆ¡£
¿ÉϧµÄÊÇ£¬Í¬¹¹ js Æäʵ²¢Ã»Óеõ½ÕæÕýÒâÒåÉϵķ¢Õ¹¡£ÒòΪ£¬ÔÚ 2011 Ä꣬node.js ºÍ ECMAScript
¶¼²»¹»³ÉÊ죬ÎÒÃDz¢Ã»ÓкܺõĻù´¡ÉèÊ©£¬È¥Âú×ãͬ¹¹µÄÄ¿±ê¡£
ÏÖÔÚÊÇ 2017 Ä꣬Çé¿öÒѾÓÐËù²»Í¬¡£ECMAScript 2015 ±ê×¼¶¨°¸£¬ÌṩÁËÒ»¸ö±ê×¼µÄÄ£¿é¹æ·¶£¬Ç°ºó¶ËͨÓ᣾¡¹ÜĿǰ
node.js ºÍä¯ÀÀÆ÷¶¼Ã»ÓÐʵÏÖ ES2015 Ä£¿é±ê×¼£¬µ«ÊÇÎÒÃÇÓÐ Babel ºÍ Webpack
µÈ¹¤¾ß£¬¿ÉÒÔÌáǰÏíÓÃеÄÓïÑÔÌØÐÔ´øÀ´µÄ±ãÀû¡£
2¡¢Í¬¹¹µÄÖÖÀàºÍ²ã´Î
2.1¡¢Í¬¹¹µÄÖÖÀà
ͬ¹¹ js ÓÐÁ½¸öÖÖÀࣺ¡¸ÄÚÈÝͬ¹¹¡¹ºÍ¡¸ÐÎʽͬ¹¹¡¹¡£
ÆäÖУ¬¡¸ÄÚÈÝͬ¹¹¡¹Ö¸·þÎñ¶ËºÍä¯ÀÀÆ÷¶ËÖ´ÐеĴúÂëÍêÈ«µÈ¼Û¡£±ÈÈ磺
function add(a, b) { return a + b } |
²»¹ÜÔÚ·þÎñ¶Ë»¹ÊÇä¯ÀÀÆ÷¶Ë£¬add º¯Êý¶¼ÊÇÒ»ÑùµÄ¡£
¶ø¡¸ÐÎʽͬ¹¹¡¹Ôò²»Í¬£¬´ÓÔ½ÌÖ¼Ö÷ÒåµÄ½Ç¶ÈÉÏ¿´£¬Ëü²»ÊÇͬ¹¹¡£ÒòΪ£¬ÔÚä¯ÀÀÆ÷¶ËÓÐÒ»²¿·Ö´úÂëÓÀÔ¶²»»áÖ´ÐУ¬¶øÔÚ·þÎñ¶ËÁíÒ»²¿·Ö´úÂëÓÀÔ¶²»»áÖ´ÐС£±ÈÈ磺
function doSomething() { if (isServer) { // do something in server-side } else if (isClient) { // do something in client-side } } |
ÔÚ npm ÀÓкܶà package ±ê°ñ×Ô¼ºÊÇͬ¹¹µÄ£¬Óõķ½Ê½¾ÍÊÇ¡¸ÐÎʽͬ¹¹¡¹¡£Èç¹û²»×÷ÌØÊâ´¦Àí£¬¡¸ÐÎʽͬ¹¹¡¹¿ÉÄÜ»áÔö¼Óä¯ÀÀÆ÷¶Ë¼ÓÔØµÄ
js ´úÂëµÄÌå»ý¡£±ÈÈç React£¬ËüµÄ 140+kb µÄÌå»ý£¬ÊǰÑÖ»ÔÚ·þÎñ¶ËÔËÐеĴúÂëÒ²°üº¬Á˽øÈ¥¡£
2.2¡¢Í¬¹¹µÄ²ã´Î
ͬ¹¹²»ÊÇÒ»¸ö²¼¶ûÖµ£¬true »òÕß false£»Í¬¹¹ÊÇÒ»¸ö¹âÆ×ÐÎ̬£¬¿ÉÒÔÔÚºÜС·¶Î§ÀïÉÏʵÏÖͬ¹¹£¬Ò²¿ÉÒÔÔںܴó·¶Î§ÀïʵÏÖͬ¹¹¡£
-function ²ã´Î£ºÁãËéµÄ´úÂëÆ¬¶Ï»òÕߺ¯Êý£¬Ö§³Öͬ¹¹¡£±ÈÈçä¯ÀÀÆ÷¶ËºÍ·þÎñ¶Ë¶¼ÊµÏÖÁË setTimeout
º¯Êý£¬±ÈÈç lodash/underscore µÄ¹¤¾ßº¯Êý¶¼ÊÇͬ¹¹µÄ¡£
-feature ²ã´Î£ºÔÚÕâ¸ö²ã´ÎÀïµÄͬ¹¹´úÂ룬ͨ³£»á³Ðµ£Ò»¶¨µÄÒµÎñÖ°ÄÜ¡£±ÈÈç React ºÍ Vue
¶¼½èÖú virtual-dom ʵÏÖÁËͬ¹¹£¬ËüÃÇÊÇ·þÎñÓÚ View ²ãµÄäÖȾ£»±ÈÈç Redux ºÍ Vuex
Ò²ÊÇͬ¹¹µÄ£¬ËüÃǸºÔð Model ²ãµÄÊý¾Ý´¦Àí¡£
-framework ²ã´Î£ºÔÚ¿ò¼Ü²ãÃæÊµÏÖͬ¹¹£¬Ëü¿ÉÄܰüº¬ÁËËùÓвã´ÎµÄͬ¹¹£¬ÐèÒª¾«ÐÄ´¦ÀíÖ§³Öͬ¹¹ºÍ²»Ö§³Öͬ¹¹µÄÁ½¸ö²¿·Ö£¬ÈçºÎÍ×ÉÆµØÕûºÏÔÚÒ»Æð¡£
ÎÒÃǽñÌìËùÌÖÂÛµÄ isomorphic-mvc£¨¼ò³Æ IMVC£©£¬ÊÇÔÚ framework ²ã´ÎÉÏʵÏÖͬ¹¹¡£
3¡¢Í¬¹¹µÄ¼ÛÖµºÍ×÷ÓÃ
3.1¡¢Í¬¹¹µÄ¼ÛÖµ
ͬ¹¹ js£¬²»½ö½öÓгéÏóÉϵÄÃÀ¸Ð£¬Ëü»¹ÓкܶàʵÓüÛÖµ¡£
SEO ÓѺãºView ²ãÔÚä¯ÀÀÆ÷¶ËºÍ·þÎñ¶Ë¶¼¿ÉÒÔÔËÐУ¬Òâζ×Å¿ÉÒÔÔÚ·þÎñ¶Ëͳö html£¬Ö§³ÖËÑË÷ÒýÇæµÄץȡ¡£
¼Ó¿ì·ÃÎÊÌåÑ飺·þÎñ¶ËäÖȾ¿ÉÒÔ¼Ó¿ìä¯ÀÀÆ÷¶ËµÄÊ״ηÃÎʵÄäÖȾËÙ¶È£¬¶øä¯ÀÀÆ÷¶ËäÖȾ£¬¿ÉÒÔ¼Ó¿ìÓû§½»»¥Ê±µÄ·´À¡ËÙ¶È¡£
´úÂëµÄ¿Éά»¤ÐÔ£ºÍ¬¹¹¿ÉÒÔ¼õÉÙÓïÑÔÇл»µÄ³É±¾£¬¼õС´úÂëµÄÖØ¸´ÂÊ£¬Ôö¼Ó´úÂëµÄ¿Éά»¤ÐÔ¡£
²»Ê¹ÓÃͬ¹¹·½°¸£¬Ò²¿ÉÒÔÓñðµÄ°ì·¨ÊµÏÖǰÁ½¸öµÄÄ¿±ê£¬µ«ÊDZðµÄ°ì·¨È´ÄÑÒÔͬʱÂú×ãÈý¸öÄ¿±ê¡£
3.2¡¢Í¬¹¹ÈçºÎ¼Ó¿ì·ÃÎÊÌåÑé
´¿ä¯ÀÀÆ÷¶ËäÖȾµÄÎÊÌâÔÚÓÚ£¬Ò³ÃæÐèÒªµÈ´ý js ¼ÓÔØÍê±ÏÖ®ºó£¬²Å¿É¼û¡£

ͼ2 client-side renderging
·þÎñ¶ËäÖȾ¿ÉÒÔ¼ÓËÙÊ״ηÃÎʵÄÌåÑ飬ÔÚ js ¼ÓÔØÖ®Ç°£¬Ò³Ãæ¾ÍäÖȾÁËÊׯÁ¡£µ«ÊÇ£¬Óû§Ö»¶ÔÊ״μÓÔØÓÐÄÍÐÄ£¬Èç¹û²Ù×÷¹ý³ÌÖУ¬Æµ·±Ë¢ÐÂÒ³Ãæ£¬Ò²»á´ø¸øÓû§»ºÂýµÄ¸Ð¾õ¡£

ͼ3 SERVER-SIDE RENDERING
ͬ¹¹äÖȾÔò¿ÉÒԵõ½Á½Öֺô¦£¬ÔÚÊ״μÓÔØÊ±Ó÷þÎñ¶ËäÖȾ£¬ÔÚ½»»¥¹ý³ÌÖÐÔò²ÉÈ¡ä¯ÀÀÆ÷¶ËäÖȾ¡£
3.3¡¢Í¬¹¹ÊÇδÀ´µÄÇ÷ÊÆ
´ÓÀúÊ··¢Õ¹µÄ½Ç¶È¿´£¬Í¬¹¹È·ÊµÊÇδÀ´µÄÒ»´óÇ÷ÊÆ¡£
ÔÚ Web ¿ª·¢µÄÔçÆÚ£¬²ÉÓõĿª·¢Ä£Ê½ÊÇ£ºfat-server, thin-client

ͼ4
ǰ¶ËÖ»ÊDZ¡±¡µÄÒ»²ã£¬¸ºÔðһЩ±íµ¥ÑéÖ¤£¬DOM ²Ù×÷ºÍ JS ¶¯»¡£ÔÚÕâ¸ö½×¶Î£¬Ã»ÓС¸Ç°¶Ë¹¤³Ìʦ¡¹Õâ¸ö¹¤ÖÖ£¬·þÎñ¶Ë¿ª·¢Ë³±ã¾Í°Ñǰ¶Ë´úÂë¸øÐ´ÁË¡£
ÔÚ Ajax ±»·¢¾ò³öÀ´Ö®ºó£¬Web ½øÈë 2.0 ʱ´ú£¬ÎÒÃÇÆÕ±éÍÆ³çµÄģʽÊÇ£ºthin-server,
fat-client

ͼ5
Ô½À´Ô½¶àµÄÒµÎñÂß¼£¬´Ó·þÎñ¶ËÇ¨ÒÆµ½Ç°¶Ë¡£¿ªÊ¼ÓС¸Ç°ºó¶Ë·ÖÀ롹µÄ×ö·¨£¬Ç°¶ËÏ£Íû·þÎñ¶ËÖ»Ìṩ restful
½Ó¿ÚºÍÊý¾Ý³Ö¾Ã»¯¡£
µ«ÊÇÔÚÕâ¸ö½×¶Î£¬×öµÃ²»¹»³¹µ×¡£Ç°¶Ë²¢Ã»ÓÐÍêÈ«ÕÆ¿ØäÖȾ²ã£¬ÆðÂë html ¹Ç¼ÜÐèÒª·þÎñ¶ËäÖȾ£¬ÒÔ¼°Ç°¶ËʵÏÖ²»ÁË·þÎñ¶ËäÖȾ¡£
ΪÁ˽â¾öÉÏÊöÎÊÌ⣬ÎÒÃÇÕýÔÚ½øÈëÏÂÒ»¸ö½×¶Î£¬Õâ¸ö½×¶ÎËù²ÉÈ¡µÄģʽÊÇ£ºshared, fat-server,
fat-client¡£

ͼ6
ͨ¹ý node.js ÔËÐÐʱ£¬Ç°¶ËÍêÈ«ÕÆ¿ØäÖȾ²ã£¬²¢ÇÒʵÏÖäÖȾ²ãµÄͬ¹¹¡£¼È²»ÎþÉü·þÎñ¶ËäÖȾµÄ¼ÛÖµ£¬Ò²²»·ÅÆúä¯ÀÀÆ÷¶ËäÖȾµÄ±ãÀû¡£
Õâ¾ÍÊÇδÀ´µÄÇ÷ÊÆ¡£
4¡¢Í¬¹¹µÄʵÏÖ²ßÂÔ
ҪʵÏÖͬ¹¹£¬Ê×ÏÈÒªÕýÊÓÒ»µã£¬È«ÅÌͬ¹¹ÊÇûÓÐÒâÒåµÄ¡£ÎªÊ²Ã´£¿
·þÎñ¶ËºÍä¯ÀÀÆ÷¶Ë±Ï¾¹ÊÇÁ½¸ö²»Í¬µÄƽ̨ºÍ»·¾³£¬ËüÃÇרעÓÚ½â¾ö²»Í¬µÄÎÊÌ⣬ÓÐ×ÔÉíµÄÌØµã£¬È«ÅÌͬ¹¹¾ÍĨɱÁËËüÃǹÌÓеIJîÒ죬Ҳ¾ÍÎÞ·¨·¢»ÓËüÃǸ÷×ÔµÄÓÅÊÆ¡£
Òò¶ø£¬ÎÒÃÇÖ»»áÔÚ client ºÍ server Óн»¼¯µÄ²¿·ÖʵÏÖͬ¹¹¡£¾ÍÊÇÔÚ·þÎñ¶ËäÖȾ html ºÍÔÚä¯ÀÀÆ÷¶Ë¸´ÓÃ
html µÄÕû¸ö¹ý³ÌÀʵÏÖͬ¹¹¡£
ÎÒÃDzÉÈ¡µÄÖ÷Òª×ö·¨ÓÐÁ½¸ö£º1£©Äܹ»Í¬¹¹µÄ´úÂ룬ֱ½Ó¸´Óã»2£©ÎÞ·¨Í¬¹¹µÄ´úÂ룬·â×°³ÉÐÎʽͬ¹¹¡£
¾Ù¼¸¸öÀý×Ó¡£
»ñÈ¡ User-Agent ×Ö·û´®¡£

ͼ7
ÎÒÃÇ¿ÉÒÔÔÚ·þÎñ¶ËÓà req.get(¡®user-agent¡¯) Ä£Äâ³ö navigator È«¾Ö¶ÔÏó£¬Ò²¿ÉÒÔÌṩһ¸ö
getUserAgent µÄ·½·¨»òº¯Êý¡£
»ñÈ¡ Cookies¡£

ͼ8
Cookies ´¦ÀíÔÚÎÒÃǵij¡¾°À´æÔÚ¿ì½ÝͨµÀ£¬ÒòΪÎÒÃÇֻרעÊ×´ÎäÖȾµÄͬ¹¹£¬ÆäËüµÄ²Ù×÷¿ÉÒÔ·ÅÔÚä¯ÀÀÆ÷¶Ë¶þ´ÎäÖȾµÄʱºòÔÙ´¦Àí¡£
Cookies µÄÖ÷ÒªÓÃ;·¢ÉúÔÚ ajax ÇëÇóµÄʱºò£¬ÔÚä¯ÀÀÆ÷¶Ë ajax ÇëÇó¿ÉÒÔÉèÖÃΪ×Ô¶¯´øÉÏ
Cookies£¬ËùÒÔÖ»ÐèÒªÔÚ·þÎñ¶ËĬĬµØÔÚÿ¸ö ajax ÇëÇóÍ·Àï²¹ÉÏ Cookies ¼´¿É¡£
Redirects ÖØ¶¨Ïò´¦Àí

ͼ9
ÖØ¶¨ÏòµÄ³¡¾°±È½Ï¸´ÔÓ£¬ÆðÂëÓÐÈýÖÖÇé¿ö£º
·þÎñ¶Ë 302 ÖØ¶¨Ïò: res.redirect(xxx)
ä¯ÀÀÆ÷¶Ë location ÖØ¶¨Ïò£ºlocation.href = xxx ºÍ location.replace(xxx)
ä¯ÀÀÆ÷¶Ë pushState ÖØ¶¨Ïò£ºhistory.push(xxx) ºÍ history.replace(xxx)
ÎÒÃÇÐèÒª·â×°Ò»¸ö redirect º¯Êý£¬¸ù¾ÝÊäÈëµÄ url ºÍ»·¾³ÐÅÏ¢£¬Ñ¡ÔñÕýÈ·µÄÖØ¶¨Ïò·½Ê½¡£
5¡¢IMVC ¼Ü¹¹
5.1¡¢IMVC µÄÄ¿±ê
IMVC µÄÄ¿±êÊÇ¿ò¼Ü²ãÃæµÄͬ¹¹£¬ÎÒÃÇÒªÇóËü±ØÐëʵÏÖÒÔϹ¦ÄÜ
Ó÷¨¼òµ¥£¬³õѧÕßÒ²ÄÜ¿ìËÙÉÏÊÖ
ֻά»¤Ò»Ì× ES2015+ µÄ´úÂë
¼ÈÊǵ¥Ò³Ó¦Óã¬ÓÖÊǶàÒ³Ó¦Óã¨SPA + SSR£©
¿ÉÒÔ²¿Êðµ½ÈÎÒâ·¢²¼Â·¾¶ (Basename/RootPath)
Ò»ÌõÃüÁîÆô¶¯Í걸µÄ¿ª·¢»·¾³
Ò»ÌõÃüÁîÍê³É´ò°ü/²¿Êð¹ý³Ì
ÓÐЩ¹¦ÄÜÊôÓÚÔËÐÐʱµÄ£¬ÓÐЩ¹¦ÄÜÔòÖ»·þÎñÓÚ¿ª·¢»·¾³¡£JavaScript ËäÈ»ÊÇһÎâÊÍÐÍÓïÑÔ£¬µ«Ç°¶ËÐÐÒµ·¢Õ¹µ½Ïֽ׶Σ¬ËüµÄ¿ª·¢Ä£Ê½ÒѾ±äµÃ·Ç³£·á¸»£¬¼È¿ÉÒÔÓÃ×îÆÓËØµÄ·½Ê½£¬Ò»¸ö¼Çʱ¾¼ÓÉÏÒ»¸öä¯ÀÀÆ÷£¬Ò²¿ÉÒÔÓÃÒ»¸ö
IDE ¼ÓÉÏһϵÁпª·¢¡¢²âÊԺͲ¿ÊðÁ÷³ÌµÄÖ§³Ö¡£
5.2¡¢IMVC µÄ¼¼ÊõÑ¡ÐÍ
Router: create-app = history + path-to-regexp
View: React = renderToDOM || renderToString
Model: relite = redux-like library
Ajax: isomorphic-fetch
ÀíÂÛÉÏ£¬IMVC ÊÇÒ»Öּܹ¹Ë¼Â·£¬Ëü²¢²»ÏÞ¶¨ÎÒÃÇʹÓÃÄÄЩ¼¼ÊõÕ»¡£²»¹ý£¬ÒªÊ¹ IMVC Â䵨£¬×ܵÃ×ö³öÑ¡Ôñ¡£ÉÏÃæ¾ÍÊÇÎÒÃǵ±Ç°Ñ¡ÔñµÄ¼¼ÊõÕ»£¬½«À´ËüÃÇ¿ÉÄÜÉý¼¶»òÕßÌæ»»ÎªÆäËü¼¼Êõ¡£
5.3¡¢ÎªÊ²Ã´²»Ö±½ÓÓà React È«¼ÒͰ£¿
´ó¼Ò¿ÉÄÜ×¢Òâµ½£¬ÎÒÃÇʹÓÃÁËÐí¶à React Ïà¹ØµÄ¼¼Êõ£¬µ«È´²»ÊÇËùνµÄ React È«¼ÒͰ£¬ÔÒòÈçÏ£º
ĿǰµÄ React È«¼ÒͰÆäʵÊÇÒ°ÉúµÄ£¬Facebook ²¢²»ÓÃ
React-Router µÄÀíÄîÄÑÒÔÂú×ãÒªÇó
Redux ÊÊÓÃÓÚ´óÐÍÓ¦Ó㬶øÎÒÃǵÄÖ÷Òª³¡¾°ÊÇÖÐСÐÍ
Éý¼¶Æµ·±µ¼ÖÂѧϰ³É±¾¹ý¸ß£¬Ðè·â×°Ò»²ã¸ü¼ò½àµÄ API
ĿǰµÄÈ«¼ÒͰ£¬Ö»ÊÇÉçÇøÀïµÄһЩÈÈÃÅ¿âµÄ×éºÏ°ÕÁË¡£Facebook ÕæÕýÓõÄÈ«¼ÒͰÊÇ react|flux|relay|graphql£¬ÉõÖÁËûÃDz¢²»ÓÃ
React ×ö·þÎñ¶ËäÖȾ£¬ÓõÄÊÇ PHP¡£
ÎÒÃÇÈÏΪ React-Router µÄÀíÄîÔÚͬ¹¹ÉÏÊÇ´íÎóµÄ¡£ËüºöÊÓÁËÒ»¸öÖØ´óÊÂʵ£º·þÎñ¶ËÊÇ Router
·ÓÉÇý¶¯µÄ£¬°Ñ Router ºÍ×÷Ϊ View µÄ React À¦°óÆðÀ´£¬View ÒѾʵÀý»¯ÁË£¬Router
ÔõôÔÙ¼ÓÔØ Controller »òÕßÒì²½ÇëÇóÊý¾ÝÄØ£¿
´Óº¯Êýʽ±à³ÌµÄ½Ç¶È¿´£¬React ÍÆ³ç´¿×é¼þ£¬ÐèÒª¸ôÀ븱×÷Ó㬶ø Router ÔòÊǸ±×÷ÓÃÀ´Ô´£¬½«Á½Õß»ìºÏÔÚÒ»Æð£¬ÊÇÒ»ÖÖÎÛȾ¡£ÁíÍ⣬Router
²¢²»ÊÇ UI£¬È´±»Ð´³É JSX ×é¼þµÄÐÎʽ£¬ÕâÒ²ÊÇÓдýÉÌȶµÄ¡£
ËùÒÔ£¬¼´±ãÊǵ±Ç°×îаæµÄ React-Router-v4£¬ÊµÏÖͬ¹¹äÖȾʱ£¬×ö·¨Ò²¸´ÔÓ¶øÓ·Ö×£¬·þÎñ¶ËºÍä¯ÀÀÆ÷¶Ë¸÷ÓÐÒ»¸ö·ÓɱíºÍ·¢
ajax ÇëÇóµÄÂß¼¡£
ÖÁÓÚ Redux£¬Æä×÷ÕßÒ²ÒÑÔÚ¹«¿ª³¡ºÏ±íʾ£º¡¸Äã¿ÉÄܲ»ÐèÒª Redux¡¹¡£ÔÚÒýÈë redux ʱ£¬ÎÒÃǵÃÏÈ·´Ë¼Ò»ÏÂÒýÈëµÄ±ØÒªÐÔ¡£
ºÁÎÞÒÉÎÊ£¬Redux µÄģʽÊÇÓÅÐãµÄ£¬½á¹¹ÇåÎú£¬Ò×ά»¤¡£È»¶øÍ¬Ê±ËüÒ²ÊÇ·±ËöµÄ£¬ÊµÏÖÒ»¸ö¹¦ÄÜ£¬Äã¿ÉÄܵÿçÎļþ¼ÐµØ²Ù×÷Êý¸öÎļþ£¬²ÅÄÜÍê³É¡£ÕâЩ´ú¼ÛËù´øÀ´µÄÏÔÖøºÃ´¦£¬ÒªÔÚ
app ¸´ÔÓµ½Ò»¶¨³Ì¶Èʱ£¬²ÅÄÜÕæÕýÌå»á¡£ÆäËüģʽÀapp ¸´ÔÓµ½Ò»¶¨³Ì¶Èºó£¬¾ÍÄÑÒÔά»¤ÁË£»¶ø Redux
µÄ¿Éά»¤ÐÔ»¹ÒÀÈ»¼áͦ£¬Õâ¾ÍÊÇÆä¼ÛÖµËùÔÚ¡££¨ÖµµÃÒ»ÌáµÄÊÇ£¬»ùÓÚ redux ÔÙ·â×°Ò»²ã¼ò»¯µÄ API£¬ÎÒÈÏΪÕâºÜ¿ÉÄÜÊÇ´íÎóµÄ×ö·¨¡£Redux
µÄÔ´ÂëºÜ¼ò½à£¬ÒâͼҲºÜÃ÷È·£¬Òª¼ò»¯¹ÌȻҲÊÇ¿ÉÒԵ쬵«ËüΪʲô×Ô¼º²»È¥×ö£¿ËüÊDz»ÊÇ¿ÌÒâÕâÑùÉè¼ÆÄØ£¿ÄãµÄ·â×°ÊÇ·ñËðº¦ÁËËüµÄÉè¼ÆÄ¿µÄÄØ£¿£©
ÔÚʹÓà Redux ֮ǰҪ¿¼ÂǵÄÊÇ£¬ÎÒÃÇ web-app ÊôÓÚ´óÐÍÓ¦Óõķ¶³ëÂð£¿
ǰ¶ËÁìÓòÈÕÐÂÔÂÒ죬¿ò¼ÜºÍ¿âµÄƵ·±Éý¼¶Èÿª·¢ÕßÓ¦½Ó²»Ï¾¡£ÎÒÃÇÐèÒª¸ù¾Ý×ÔÉíµÄÐèÇ󣬽øÐжþ´Î·â×°£¬µÃµ½Ò»×é¸ü¼ò½àµÄ
API£¬½«²¿·Ö¸´ÔÓ¶ÈÒþ²ØÆðÀ´£¬ÒÔ½µµÍѧϰ³É±¾¡£
5.4¡¢ÓÃ create-app ´úÌæ react-router
create-app ÊÇÎÒÃÇΪÁËͬ¹¹¶øÊµÏÖµÄÒ»¸ö library£¬ËüÓÉÏÂÃæÈý²¿·Ö×é³É£º
history£º react-router ÒÀÀµµÄµ×²ã¿â
path-to-regexp£º expressjs ÒÀÀµµÄµ×²ã¿â
Controller£ºÔÚ View(React) ²ãºÍ Model ²ãÖ®ÍâʵÏÖ Controller ²ã
create-app ¸´Óà React-Router µÄÒÀÀµ history.js£¬ÓÃÒÔÔÚä¯ÀÀÆ÷¶Ë¹ÜÀí
history ״̬£»¸´Óà expressjs µÄ path-to-regexp£¬ÓÃÒÔ´Ó path pattern
ÖнâÎö²ÎÊý¡£
ÎÒÃÇÈÏΪ£¬React ºÍ Redux ·Ö±ð¶ÔÓ¦ MVC µÄ View ºÍ Model£¬ËüÃǶ¼ÊÇͬ¹¹µÄ£¬ÎÒÃÇÐèÒªµÄÊÇʵÏÖ
Controller ²ãµÄͬ¹¹¡£
5.4.1¡¢create-app µÄͬ¹¹ÀíÄî

ͼ10
create-app ʵÏÖͬ¹¹µÄ·½Ê½ÊÇ£º
ÊäÈë url£¬router ¸ù¾Ý url µÄ¸ñʽ£¬Æ¥Åä³ö¶ÔÓ¦µÄ controller Ä£¿é
µ÷Óà module-loader ¼ÓÔØ controller Ä£¿é£¬Äõ½ Controller Àà
View ºÍ Model ´ÓÊôÓÚ Controller ÀàµÄÊôÐÔ
new Controller(location, context) µÃµ½ controller ʵÀý
µ÷Óà controller.init ·½·¨£¬¸Ã·½·¨±ØÐë·µ»Ø view µÄʵÀý
µ÷Óà view-engine ½« view µÄʵÀý¸ù¾Ý»·¾³äÖȾ³É html »òÕß dom »òÕß native-ui
µÈ
ÉÏÊö¹ý³ÌÔÚ·þÎñ¶ËºÍä¯ÀÀÆ÷¶Ë¶¼±£³ÖÒ»Ö¡£
5.4.2¡¢create-app µÄÅäÖÃÀíÄî
·þÎñ¶ËºÍä¯ÀÀÆ÷¶Ë¼ÓÔØÄ£¿éµÄ·½Ê½²»Í¬£¬·þÎñ¶ËÊÇͬ²½¼ÓÔØ£¬¶øä¯ÀÀÆ÷¶ËÔòÊÇÒì²½¼ÓÔØ£»ËüÃÇµÄ view-engine
Ò²ÊDz»Í¬µÄ¡£ÈçºÎ´¦ÀíÕâЩ²»Ò»Ö£¿
´ð°¸ÊÇÅäÖá£
const app = createApp({ type: 'createHistory', container: '#root', context: { isClient: true|false, isServer: false|true, ...injectFeatures }, loader: webpackLoader|commonjsLoader, routes: routes, viewEngine: ReactDOM|ReactDOMServer, }) app.start() || app.render(url, context) |
·þÎñ¶ËºÍä¯ÀÀÆ÷¶Ë·Ö±ðÓÐ×Ô¼ºµÄÈë¿ÚÎļþ£ºclient-entry.js ºÍ server.entry.js¡£ÎÒÃÇÖ»ÐèÌṩ²»Í¬µÄÅäÖü´¿É¡£
ÔÚ·þÎñ¶Ë£¬¼ÓÔØ controller Ä£¿éµÄ·½Ê½ÊÇ commonjsLoader£»ÔÚä¯ÀÀÆ÷¶Ë£¬¼ÓÔØ controller
Ä£¿éµÄ·½Ê½ÔòΪ webpackLoader¡£
ÔÚ·þÎñ¶ËºÍä¯ÀÀÆ÷¶Ë£¬view-engine Ò²±»ÅäÖÃΪ²»Í¬µÄ ReactDOM ºÍ ReactDOMServer¡£
ÿ¸ö controller ʵÀý£¬¶¼ÓÐ context ²ÎÊý£¬ËüÒ²ÊÇÀ´×ÔÅäÖá£Í¨¹ýÕâÖÖ·½Ê½£¬ÎÒÃÇ¿ÉÒÔÔÚÔËÐÐʱעÈ벻ͬµÄÆ½Ì¨ÌØÐÔ¡£ÕâÑù¼È·Ö¸îÁË´úÂ룬ÓÖʵÏÖÁËÐÎʽͬ¹¹¡£
5.4.3¡¢create-app µÄ·þÎñ¶ËäÖȾ
ÎÒÃÇÈÏΪ£¬¼ò½àµÄ£¬²ÅÊÇÕýÈ·µÄ¡£create-app ʵÏÖ·þÎñ¶ËäÖȾµÄ´úÂëÈçÏ£º
const app = createApp(serverSettings) router.get('*', async (req, res, next) => { try { const { content } = await app.render(req.url, serverContext) res.render('layout', { content }) } catch(error) { next(error) } }) |
ûÓжàÓàµÄÐÅÏ¢£¬Ò²Ã»ÓжàÓàµÄ´úÂ룬ÊäÈëÒ»¸ö url ºÍ context£¬·µ»Ø¾ßÓÐÕæÊµÊý¾Ý html ×Ö·û´®¡£
5.4.4¡¢create-app µÄ±âƽ»¯Â·ÓÉÀíÄî
React-Router Ö§³Ö²¢¹ÄÀøÇ¶Ì×·ÓÉ£¬Æä¼ÛÖµ´æÒÉ¡£ËüÔö¼ÓÁË´úÂëµÄÔĶÁ³É±¾£¬ÒÔ¼°¸÷¸ö·ÓÉÄ£¿éÖ®¼äµÄ¹ØÏµÓë
UI£¨React ×é¼þ£©µÄǶÌ×ñîºÏÔÚÒ»Æð£¬²¢²»Áé»î¡£
ʹÓÃ±âÆ½»¯Â·ÓÉ£¬¿ÉÒÔʹ´úÂë½âñÈÝÒ×ÔĶÁ£¬²¢ÇÒ¸üΪÁé»î¡£ÒòΪ£¬UI Ö®¼äµÄ¸´Ó㬿ÉÒÔͨ¹ý React
×é¼þµÄÖ±½ÓǶÌ×À´ÊµÏÖ¡£
»ùÓÚ·ÓÉǶÌ×¹ØÏµÀ´¸´Óà UI£¬ÈÝÒ×ÓöÉÏÒ»¸öÞÏÞγ¡¾°£ºÇ¡ºÃÖ»ÓÐÒ»¸öÒ³Ãæ²»ÐèÒª¹²ÏíÍ·²¿£¬¶øÍ·²¿È´²»ÔÚËüµÄ¿ØÖÆ·¶³ëÄÚ¡£
// routes export default [{ path: '/demo', controller: require('./home/controller') }, { path: '/demo/list', controller: require('./list/controller') }, { path: '/demo/detail', controller: require('./detail/controller') }] |
ÈçÄãËù¼û£¬ÎÒÃÇµÄ path ¶ÔÓ¦µÄ²¢²»ÊÇ component£¬¶øÊÇ controller¡£Í¨¹ýÐÂÔö controller
²ã£¬ÎÒÃÇ¿ÉÒÔʵÏÖÔÚ view ²ãµÄ component ʵÀý»¯Ö®Ç°£¬¾Í½èÖú controller »ñÈ¡ÊׯÁÊý¾Ý¡£
next.js Ò²ÊÇÒ»¸öͬ¹¹¿ò¼Ü£¬Ëü±¾ÖÊÉÏÊǼò»¯°æµÄ IMVC£¬Ö»²»¹ýËüµÄ C ²ã·Ç³£±¡£¬ÒÔÖÁÓÚÖ±½Ó¹ÒÔÚ
View ×é¼þµÄ¾²Ì¬·½·¨Àï¡£ËüµÄ·ÓÉÅäÖÃĿǰÊÇ»ùÓÚ View µÄÎļþÃû£¬Æä Controller ²ãÊÇ
View.getInitialProps ¾²Ì¬·½·¨£¬Ö»·þÎñÓÚ»ñÈ¡³õʼ»¯ props¡£
ÕâÒ»²ãÌ«±¡ÁË£¬ËüÆäʵ¿ÉÒÔ¸üΪ·á¸»£¬±ÈÈçÌṩ fetch ·½·¨£¬ÄÚÖû·¾³Åжϣ¬Ö§³Ö jsonp£¬Ö§³Ö mock
Êý¾Ý£¬Ö§³Ö³¬Ê±´¦ÀíµÈÌØÐÔ£¬±ÈÈç×Ô¶¯°ó¶¨ store µ½ view£¬±ÈÈçÌṩ¸üΪ·á¸»µÄÉúÃüÖÜÆÚ pageWillLeave£¨Ò³Ãæ½«Ìø×ªµ½ÆäËû·¾¶£©
ºÍ windowWillUnload £¨´°¿Ú¼´½«¹Ø±Õ£©µÈ¡£
×ܶøÑÔÖ®£¬¸±×÷Óò»¿ÉÄܱ»ÏûÃð£¬Ö»Äܱ»¸ôÀ룬Èç½ñ View ºÍ Model ¶¼ÊÇ pure-function
ºÍ immutabel-data µÄÎÞ¸±×÷ÓÃģʽ£¬×ܵÃÓнÇÉ«³Ðµ£´¦Àí¸±×÷ÓõÄÖ°ÄÜ¡£ÐµijéÏó²ã Controller
Ó¦Ô˶øÉú¡£
5.4.5¡¢create-app µÄĿ¼½á¹¹
©À©¤©¤ src // Ô´´úÂëĿ¼ ©¦ ©À©¤©¤ app-demo // demoĿ¼ ©¦ ©À©¤©¤ app-abcd // ÏîÄ¿ abcd ƽ̨Ŀ¼ ©¦ ©¦ ©À©¤©¤ components // ÏîÄ¿¹²Ïí×é¼þ ©¦ ©¦ ©À©¤©¤ shared // ÏîÄ¿¹²Ïí·½·¨ ©¦ ©¦ ©¸©¤©¤ BaseController // ¼Ì³Ð»ùÀà Controller µÄÏîÄ¿²ã Controller ©¦ ©¦ ©À©¤©¤ home // ¾ßÌåÒ³Ãæ ©¦ ©¦ ©¦ ©À©¤©¤ controller.js // ¿ØÖÆÆ÷ ©¦ ©¦ ©¦ ©À©¤©¤ model.js // Ä£ÐÍ ©¦ ©¦ ©¦ ©¸©¤©¤ view.js // ÊÓͼ ©¦ ©¦ ©À©¤©¤ * // ÆäËûÒ³Ãæ ©¦ ©¦ ©¸©¤©¤ routes.js // abc ÏîÄ¿±âƽ»¯Â·ÓÉ ©¦ ©À©¤©¤ app-* // ÆäËûÏîÄ¿ ©¦ ©À©¤©¤ components // È«¾Ö¹²Ïí×é¼þ ©¦ ©À©¤©¤ shared // È«¾Ö¹²ÏíÎļþ ©¦ ©¦ ©¸©¤©¤ BaseController // »ùÀà Controller ©¦ ©À©¤©¤ index.js // È«¾Ö js Èë¿Ú ©¦ ©¸©¤©¤ routes.js // È«¾Ö±âƽ»¯Â·ÓÉ ©À©¤©¤ static // Ô´Âë build µÄÄ¿±ê¾²Ì¬Îļþ¼Ð |
ÈçÉÏËùʾ£¬create-app ÍÆ³çµÄĿ¼½á¹¹¸ú redux ·Ç³£²»Í¬¡£Ëü²»Êǰ´ÕÕ³éÏóµÄÖ°ÄÜ actionCreator|actionType|reducers|middleware|container
À´°²Åŵģ¬ËüÊÇ»ùÓÚ page Ò³ÃæÀ´»®·ÖµÄ£¬Ã¿¸öÒ³Ãæ¶¼ÓÐÈý¸ö×é³É²¿·Ö£ºcontroller£¬model
ºÍ view¡£
Óà routes ·ÓÉ±í£¬½« page ´®ÆðÀ´¡£
create-app ²ÉÈ¡ÁË¡¸ÕûÕ¾ SPA¡¹ µÄģʽ£¬È«¾ÖÖ»ÓÐÒ»¸öÈë¿ÚÎļþ£¬index.js¡£src
Ŀ¼ÏµÄÎļþ¶¼ËùÓÐÏîÄ¿¹²ÏíµÄ¿ò¼Ü²ã´úÂ룬¸÷¸öÏîÄ¿×ÔÉíµÄÒµÎñ´úÂëÔòÔÚ app-xxx µÄÎļþ¼ÐÏ¡£
ÕâÖÖÉè¼ÆµÄÄ¿µÄÊÇΪÁ˽µµÍÇ¨ÒÆ³É±¾£¬Áé»îÇзֺͺϲ¢¸÷¸öÏîÄ¿¡£
µ±Ä³¸öÏîÄ¿´¦ÓÚÃÈÑ¿½×¶Î£¬Ëü¿ÉÒÔÒÀ¸½ÔÚÁíÒ»¸öÏîÄ¿µÄ git ²Ö¿âÀʹÓÃËüÏֳɵĻù´¡ÉèÊ©½øÐпìËÙ¿ª·¢¡£
µ±Á½¸öÏîÄ¿×ã¹»¸´ÔÓ£¬ÖµµÃ·Ö¸îΪÁ½¸öÏîĿʱ£¬ËüÃÇ¿ÉÒÔ·Ö¸îΪÁ½¸öÏîÄ¿£¬¸÷×Ô½«¶Ô·½µÄÎļþ¼ÐÕû¸öɾ³ý¼´¿É¡£
µ±Á½¸öÏîĿҪºÏ²¢£¬½«ËüÃǷŵ½Í¬Ò» git ²Ö¿âµÄ²»Í¬ app-xxx Àï¼´¿É¡£
ÎÒÃÇʹÓñ¾µØÂ·Óɱí routes.js ºÍ nginx ÅäÖÃе÷ url µÄ·ÃÎʹæÔò
ÿ¸ö page µÄ controller.js£¬model.js ºÍ view.js ÒÔ¼°ËüÃǵÄ˽ÓÐÒÀÀµ£¬½«»á±»µ¥¶À´ò°üµ½Ò»¸öÎļþ£¬Ö»ÓÐÆ¥Åä
url ³É¹¦Ê±£¬²Å»á°´Ðè¼ÓÔØ¡£±£Ö¤¶àÏîÄ¿²¢´æ²»»á´øÀ´ js Ìå»ýµÄÅòÕÍ¡£
5.5¡¢controller µÄ»ù±¾Ä£Ê½
ÎÒÃÇÐÂÔöÁË controller Õâ¸ö³éÏó²ã£¬Ëü½«³Ðµ£Á¬½Ó Model£¬View£¬History£¬LocalStorage£¬Server
µÈ¶ÔÏóµÄÖ°ÄÜ¡£
Controller ±»Éè¼ÆÎª OOP ±à³Ì·¶Ê½µÄÒ»¸ö class£¬Ö÷ҪĿµÄ¾ÍÊÇΪÁËÈÃËü³ÐÊܸ±×÷Óã¬ÒÔ±ã
View ºÍ Model ²ã±£³Öº¯ÊýʽµÄ´¿´â¡£
Controller µÄ»ù±¾Ä£Ê½ÈçÏ£º
class MyController extends BaseController { requireLogin = true // ÊÇ·ñÒÀÀµµÇ½̬£¬BaseController Àï×Ô¶¯´¦Àí View = View // ÊÓͼ initialState = { count: 0 } // model ³õʼ״̬initialState actions = actions // model ״̬±ä»¯µÄº¯Êý¼¯ºÏ actions handleIncre = () => { // ʼþ´¦ÀíÆ÷£¬×Ô¶¯ÊÕ¼¯ÆðÀ´£¬´«µÝ¸ø View ×é¼þ let { history, store, fetch, location, context } = this // ¹¦ÄÜ·Ö²ã let { INCREMENT } = store.actions INCREMENT() // µ÷Óà action£¬¸üРstate£¬ view ËæÖ®×Ô¶¯¸üР} async shouldComponentCreate() {} // ÔÚÕâÀï¼øÈ¨£¬return false async componentWillCreate() {} // ÔÚÕâÀï fetch ÊׯÁÊý¾Ý componentDidMount() {} // ÔÚÕâÀï fetch ·ÇÊׯÁÊý¾Ý pageWillLeave() {} // ÔÚÕâÀïÖ´ÐзÓÉÌø×ªÀ뿪ǰµÄÂß¼ windowWillUnload() {} // ÔÚÕâÀïÖ´ÐÐÒ³Ãæ¹Ø±ÕǰµÄÂß¼ } |
ÎÒÃǽ«ËùÓÐÖ°ÄܶÔÏó·Åµ½ÁË controller µÄÊôÐÔÖУ¬¿ª·¢ÕßÖ»ÐèÌṩÏàÓ¦µÄÅäÖúͶ¨Ò壬ÔڷḻµÄÉúÃüÖÜÆÚÀï°´Ðèµ÷ÓÃÏà¹Ø·½·¨¼´¿É¡£
ËüµÄ½á¹¹ºÍģʽ¸ú vue ºÍ΢ÐÅС³ÌÐòÓеãÏàËÆ¡£
5.6¡¢redux µÄ¼ò»¯°æ relite
¾¡¹Ü×÷ΪÖÐСÐÍÓ¦Óõļܹ¹£¬ÎÒÃDz»Ê¹Óà Redux£¬µ«ÊǶÔÓÚ Redux ÖеÄÓÅÐãÀíÄ»¹ÊÇ¿ÉÒÔÎüÊÕ½øÀ´¡£
ËùÒÔ£¬ÎÒÃÇʵÏÖÁËÒ»¸ö¼ò»¯°æµÄ redux£¬½Ð×ö relite¡£
actionType, actionCreator, reducer ºÏ²¢
×Ô¶¯ bindActionCreators£¬ÄÚÖÃÒì²½ action µÄÖ§³Ö
let EXEC_BY = (state, input) => { let value = parseFloat(input, 10) return isNaN(value) ? state : { ...state, count: state.count + value } } let EXEC_ASYNC = async (state, input) => { await delay(1000) return EXEC_BY(state, input) } let store = createStore( { EXEC_BY, EXEC_ASYNC }, { count: 0 } ) |
ÎÒÃÇÏ£ÍûµÃµ½µÄÊÇ redux µÄÁ½¸öºËÐÄ£º1£©pure-function£¬2£©immutable-data¡£
ËùÒÔ action º¯Êý±»Éè¼ÆÎª´¿º¯Êý£¬ËüµÄº¯ÊýÃû¾ÍÊÇ redux µÄ action-type£¬ËüµÄº¯ÊýÌå¾ÍÊÇ
redux µÄ reducer£¬ËüµÄµÚÒ»¸ö²ÎÊýÊǵ±Ç°µÄ state£¬ËüµÄµÚ¶þ¸ö²ÎÊýÊÇ redux µÄ actionCreator
Я´øµÄÊý¾Ý¡£²¢ÇÒ£¬relite ÄÚÖÃÁË redux-promise ºÍ redux-thunk µÄ¹¦ÄÜ£¬¿ª·¢Õß¿ÉÒÔʹÓÃ
async/await Óï·¨£¬ÊµÏÖÒì²½ action¡£
relite Ò²ÒªÇó state ¾¡¿ÉÄÜÊÇ immutable£¬²¢ÇÒ¿ÉÒÔͨ¹ý¶îÍâµÄ recorder
²å¼þ£¬ÊµÏÖ time-travel µÄ¹¦ÄÜ¡£
5.7¡¢Isomorphic-MVC µÄ¹¤³Ì»¯ÉèÊ©
ÉÏÃæ½²ÊöÁË IMVC ÔÚÔËÐÐʱÀïµÄһЩ¹¦ÄܺÍÌØµã£¬ÏÂÃæ¼òµ¥µØÃèÊöһϠIMVC µÄ¹¤³Ì»¯ÉèÊ©¡£ÎÒÃDzÉÓÃÁË£º
node.js ÔËÐÐʱ£¬npm °ü¹ÜÀí
expressjs ·þÎñ¶Ë¿ò¼Ü
babel ±àÒë ES2015+ ´úÂëµ½ ES5
webpack ´ò°üºÍѹËõÔ´Âë
standard.js ¼ì²é´úÂë¹æ·¶
prettier.js + git-hook ´úÂë×Ô¶¯ÃÀ»¯ÅŰæ
mocha µ¥Ôª²âÊÔ
5.7.1¡¢ÈçºÎʵÏÖ´úÂëʵʱÈȸüУ¿
Ä¿±ê£ºÒ»¸öÃüÁîÆô¶¯¿ª·¢»·¾³£¬Ð޸ĴúÂë²»ÐèÖØÆô½ø³Ì
×ö·¨£ºÒ»¸ö webpack ·þÎñÓÚ client£¬ÁíÒ»¸ö webpack ·þÎñÓÚ server
client: express + webpack-dev-middleware ÔÚÄÚ´æÀï±àÒë
server: memory-fs + webpack + vm-module
·þÎñ¶ËµÄ webpack ±àÒëµ½ÄÚ´æÄ£ÄâµÄÎļþϵͳ£¬ÔÙÓà node.js ÄÚÖõÄÐéÄâ»úÄ£¿éÖ´ÐкóµÃµ½ÐµÄÄ£¿é
5.7.2¡¢ÈçºÎ´¦Àí CSS °´Ðè¼ÓÔØ£¿
ÎÊÌâ¸ùÔ´£ºä¯ÀÀÆ÷Ö»ÔÚ dom-ready ֮ǰ»áµÈ´ý css ×ÊÔ´¼ÓÔØºóÔÙäÖÈ¾Ò³Ãæ
ÎÊÌâÃèÊö£ºµ±µ¥Ò³Ìø×ªµ½ÁíÒ»¸ö url£¬css ×ÊÔ´»¹Ã»¼ÓÔØÍê£¬Ò³ÃæÏÔʾ³É»ìÂÒ²¼¾Ö
´¦Àí°ì·¨£º½« css ÊÓΪԤ¼ÓÔØµÄ ajax Êý¾Ý£¬ÒÔ style ±êÇ©µÄÐÎʽ°´ÐèÒýÈë
ÓÅ»¯²ßÂÔ£ºÓà context »º´æÔ¤¼ÓÔØÊý¾Ý£¬±ÜÃâÖØ¸´¼ÓÔØ
5.7.3¡¢ÈçºÎʵÏÖ´úÂëÇи°´Ðè¼ÓÔØ£¿
²»Ê¹Óà webpack-only µÄÓï·¨ require.ensure
ÔÚä¯ÀÀÆ÷Àï require ±»±àÒëΪ¼ÓÔØº¯Êý£¬Òì²½¼ÓÔØ
ÔÚ node.js Àï require ÊÇͬ²½¼ÓÔØ
// webpack.config.js { test: /controller\.jsx?$/, loader: 'bundle-loader', query: { lazy: true, name: '[1]-[folder]', regExp: /[\/\\]app-([^\/\\]+)[\/\\]/.source }, exclude: /node_modules/ } |
5.7.4¡¢ÈçºÎ´¦Àí¾²Ì¬×ÊÔ´µÄ°æ±¾¹ÜÀí£¿
ÒÔ´úÂëµÄ hash ΪÎļþÃû£¬ÔöÁ¿·¢²¼
Óà webpack.stats.plugin.js Éú³É¾²Ì¬×ÊÔ´±í
express ʹÓà stats.json µÄÊý¾ÝäÖÈ¾Ò³Ãæ
// webpack.config.js output = { path: outputPath, filename: '[name]-[hash:6].js', chunkFilename: '[name]-[chunkhash:6].js' } |
5.7.5¡¢ÈçºÎ¹ÜÀíÃüÁîÐÐÈÎÎñ£¿
ʹÓà npm-scripts ÔÚ package.json ÀïÍê³É git¡¢webpack¡¢test¡¢prettier
µÈÈÎÎñµÄ´®²¢ÁªÂß¼
npm start Æô¶¯ÍêÕûµÄ¿ª·¢»·¾³
npm run start:client Æô¶¯²»´ø·þÎñ¶ËäÖȾµÄ¿ª·¢»·¾³
npm run build Æô¶¯×Ô¶¯»¯±àÒ룬¹¹½¨ÓëѹËõ²¿ÊðµÄÈÎÎñ
npm run build:show-prod Óà webpack-bundle-analyzer ¿ÉÊÓ»¯²é¿´±àÒë½á¹û
6¡¢½áÓï
IMVC ¾¹ýʵ¼ùºÍÃþË÷£¬Òѱ»Ö¤Ã÷ÊÇÒ»ÖÖÓÐЧµÄģʽ£¬ËüÒԽϸߵÄÍê³É¶ÈʵÏÖÁËÕæÕýÒâÒåÉϵÄͬ¹¹¡£²»ÔÙ¾ÖÏÞÓÚÖ½ÃæÉϵÄÀíÄîÃèÊö£¬¶øÊÇÒ»¸ö¿ÉÒÔÂ䵨µÄ·½°¸£¬²¢ÇÒʵ¼ÊµØÌáÉýÁË¿ª·¢ÌåÑéºÍЧÂÊ¡£ºóÐøÎÒÃǽ«¼ÌÐøÍùÕâ¸ö·½Ïò̽Ë÷¡£ |