如何评价淘宝 UED 的 Midway Framework 前后端分离

\u5982\u4f55\u8bc4\u4ef7\u6dd8\u5b9d UED \u7684 Midway Framework \u524d\u540e\u7aef\u5206\u79bb

\u3000\u30001\uff0c\u6269\u5927\u4e86\u524d\u7aef\u7684\u52bf\u529b\u8303\u56f4\uff0c
\u3000\u3000\u5bf9\u6280\u672f\u5f71\u54cd\u529b\u3001\u62db\u8058\u3001\u9020\u8f6e\u5b50\u3001\u53d1paper\u3001\u664b\u5347\u7b54\u8fa9\u6781\u4e3a\u91cd\u8981\u3002\u8981\u77e5\u9053\u5728\u963f\u91cc\u524d\u7aef\u6700\u9ad8\u7684\u7ea7\u522b\u662fP8\uff0c\u4eba\u6570\u5219\u4e00\u53ea\u624b\u80fd\u6570\u7684\u8fc7\u6765\u3002\u8fd9\u4e0d\u80fd\u4e0d\u8bf4\u662f\u524d\u7aef\u8fd9\u4e00\u5c42\u8fc7\u4e8e\u8584\u3001\u79bb\u4e1a\u52a1\u6838\u5fc3\u592a\u8fdc\u5bfc\u81f4\u7684\uff0c\u73b0\u5728\u4ece\u6280\u672f\u4e0a\u4fb5\u5165\u670d\u52a1\u7aef\uff0c\u6280\u80fd\u6811\u7ec8\u4e8e\u5f00\u4e86\u65b0\u5206\u652f\uff0c\u53ef\u80fd\u6027\u731b\u7136\u5927\u4e86\u65e0\u6570\u500d\uff0c\u4e00\u4e0b\u5b50\u4f3c\u4e4e\u53d1\u73b0\u4e86\u65b0\u5927\u9646\u3002\u5bf9\u4e2a\u4eba\u6210\u957f\u7684\u6e34\u671b\uff0c\u662f\u5927\u91cf\u9762\u4e34\u74f6\u9888\u7684\u8d44\u6df1\u524d\u7aef\u5de5\u7a0b\u5e08\u65e0\u6cd5\u6297\u62d2\u7684\u8bf1\u60d1\uff01

\u3000\u30002\uff0c\u524d\u7aef\u5f00\u53d1\u6a21\u5f0f\u7684\u53d8\u9769\u3002
\u3000\u3000\u81ea\u5df1\u73a9\u540e\u7aef\uff0c\u6280\u672f\u4e0a\u3001\u9879\u76ee\u4e0a\u90fd\u4e0d\u7528\u53bb\u770b\u540e\u7aef\u9879\u76ee\u7684\u6392\u671f\u548c\u914d\u5408\u4e86\uff0c\u6781\u5927\u63d0\u9ad8\u4e86\u5f00\u53d1\u548c\u6d4b\u8bd5\u7684\u4fbf\u5229\u5ea6\u3001\u81ea\u4e3b\u6027\u3002\u963f\u91cc\u5f88\u65e9\u5c31\u4e86nodejs\u5199\u7684\u5f00\u53d1\u670d\u52a1\u5668\u7528\u4e8e\u5185\u90e8\u6d4b\u8bd5\uff0c\u73b0\u5728\u8d70\u5230\u7ebf\u4e0a\uff0c\u4e5f\u662f\u539a\u79ef\u8584\u53d1\uff0c\u8fd9\u4e3a\u63d0\u9ad8\u5f00\u53d1\u6548\u7387\uff0c\u8fdb\u4e00\u6b65\u69a8\u53d6\u524d\u7aef\u52b3\u529b\u63d0\u4f9b\u4e86\u53ef\u80fd\u3002

\u3000\u30003\uff0c\u4fc3\u8fdb\u963f\u91cc\u540e\u7aefweb\u6846\u67b6\u7684\u8fdb\u5316\u3002
\u3000\u3000\u8fd9\u4e00\u70b9\u662f\u6ca1\u6709\u5f88\u591a\u4eba\u751a\u81f3\u963f\u91cc\u4eba\u6ca1\u6ce8\u610f\u5230\u7684\uff08\u524d\u7aef\u4e0d\u61c2webx\uff0c\u540e\u7aef\u91cd\u5fc3\u540e\u79fb\uff09\uff0cwebx\u6846\u67b6\u53d1\u5e03\u5df2\u7ecf\u5f88\u4e45\uff0c\u8fd1\u671f\u7684\u6280\u672f\u5347\u7ea7\u975e\u5e38\u5c11\uff0c\u6280\u672f\u5f62\u6001\u5df2\u7ecf\u9677\u5165\u50f5\u5316\uff0c\u5bf9\u73b0\u5728\u7684\u79fb\u52a8\u4e92\u8054\u7f51\u8d8b\u52bf\u6ca1\u6709\u654f\u9510\u7684\u53d1\u73b0\u673a\u4f1a\u5e76\u9002\u5e94\u53d8\u9769\uff0c\u5f88\u9057\u61be\u5730\u7f3a\u5e2d\u4e86\u65b0\u65f6\u4ee3\u3002nodejs\u6765\u4e86\uff0c\u6d17\u724c\u5f00\u59cb\uff0c\u524d\u7aef\u4eba\u5458\u5929\u7136\u5bf9\u591a\u7ec8\u7aef\u3001\u591a\u5c4f\u3001\u4ea4\u4e92\u3001\u4f53\u9a8c\u7684\u5173\u6ce8\u4f1a\u4e3a\u540e\u7aef\u6846\u67b6\u5439\u8fc7\u4e00\u7f15\u65b0\u98ce\uff0c\u7ed9\u8fd9\u505c\u6ede\u7684\u6280\u672f\u9886\u57df\u6ce8\u5165\u6d3b\u529b\u3002\u2014\u2014\u6240\u4ee5\u6211\u662f\u8d5e\u6210\u540e\u7aef\u5de5\u7a0b\u5e08\u5b66\u4e60nodejs\u7684\u3002

\u8bc4\u4ef7\u6dd8\u5b9d UED \u7684 Midway Framework \u524d\u540e\u7aef\u5206\u79bb\uff1a
1\uff0c\u6269\u5927\u4e86\u524d\u7aef\u7684\u52bf\u529b\u8303\u56f4\uff0c
\u5bf9\u6280\u672f\u5f71\u54cd\u529b\u3001\u62db\u8058\u3001\u9020\u8f6e\u5b50\u3001\u53d1paper\u3001\u664b\u5347\u7b54\u8fa9\u6781\u4e3a\u91cd\u8981\u3002\u8981\u77e5\u9053\u5728\u963f\u91cc\u524d\u7aef\u6700\u9ad8\u7684\u7ea7\u522b\u662fP8\uff0c\u4eba\u6570\u5219\u4e00\u53ea\u624b\u80fd\u6570\u7684\u8fc7\u6765\u3002\u8fd9\u4e0d\u80fd\u4e0d\u8bf4\u662f\u524d\u7aef\u8fd9\u4e00\u5c42\u8fc7\u4e8e\u8584\u3001\u79bb\u4e1a\u52a1\u6838\u5fc3\u592a\u8fdc\u5bfc\u81f4\u7684\uff0c\u73b0\u5728\u4ece\u6280\u672f\u4e0a\u4fb5\u5165\u670d\u52a1\u7aef\uff0c\u6280\u80fd\u6811\u7ec8\u4e8e\u5f00\u4e86\u65b0\u5206\u652f\uff0c\u53ef\u80fd\u6027\u731b\u7136\u5927\u4e86\u65e0\u6570\u500d\uff0c\u4e00\u4e0b\u5b50\u4f3c\u4e4e\u53d1\u73b0\u4e86\u65b0\u5927\u9646\u3002\u5bf9\u4e2a\u4eba\u6210\u957f\u7684\u6e34\u671b\uff0c\u662f\u5927\u91cf\u9762\u4e34\u74f6\u9888\u7684\u8d44\u6df1\u524d\u7aef\u5de5\u7a0b\u5e08\u65e0\u6cd5\u6297\u62d2\u7684\u8bf1\u60d1\uff01

2\uff0c\u524d\u7aef\u5f00\u53d1\u6a21\u5f0f\u7684\u53d8\u9769\u3002
\u81ea\u5df1\u73a9\u540e\u7aef\uff0c\u6280\u672f\u4e0a\u3001\u9879\u76ee\u4e0a\u90fd\u4e0d\u7528\u53bb\u770b\u540e\u7aef\u9879\u76ee\u7684\u6392\u671f\u548c\u914d\u5408\u4e86\uff0c\u6781\u5927\u63d0\u9ad8\u4e86\u5f00\u53d1\u548c\u6d4b\u8bd5\u7684\u4fbf\u5229\u5ea6\u3001\u81ea\u4e3b\u6027\u3002\u963f\u91cc\u5f88\u65e9\u5c31\u4e86nodejs\u5199\u7684\u5f00\u53d1\u670d\u52a1\u5668\u7528\u4e8e\u5185\u90e8\u6d4b\u8bd5\uff0c\u73b0\u5728\u8d70\u5230\u7ebf\u4e0a\uff0c\u4e5f\u662f\u539a\u79ef\u8584\u53d1\uff0c\u8fd9\u4e3a\u63d0\u9ad8\u5f00\u53d1\u6548\u7387\uff0c\u8fdb\u4e00\u6b65\u69a8\u53d6\u524d\u7aef\u52b3\u529b\u63d0\u4f9b\u4e86\u53ef\u80fd\u3002

3\uff0c\u4fc3\u8fdb\u963f\u91cc\u540e\u7aefweb\u6846\u67b6\u7684\u8fdb\u5316\u3002
\u8fd9\u4e00\u70b9\u662f\u6ca1\u6709\u5f88\u591a\u4eba\u751a\u81f3\u963f\u91cc\u4eba\u6ca1\u6ce8\u610f\u5230\u7684\uff08\u524d\u7aef\u4e0d\u61c2webx\uff0c\u540e\u7aef\u91cd\u5fc3\u540e\u79fb\uff09\uff0cwebx\u6846\u67b6\u53d1\u5e03\u5df2\u7ecf\u5f88\u4e45\uff0c\u8fd1\u671f\u7684\u6280\u672f\u5347\u7ea7\u975e\u5e38\u5c11\uff0c\u6280\u672f\u5f62\u6001\u5df2\u7ecf\u9677\u5165\u50f5\u5316\uff0c\u5bf9\u73b0\u5728\u7684\u79fb\u52a8\u4e92\u8054\u7f51\u8d8b\u52bf\u6ca1\u6709\u654f\u9510\u7684\u53d1\u73b0\u673a\u4f1a\u5e76\u9002\u5e94\u53d8\u9769\uff0c\u5f88\u9057\u61be\u5730\u7f3a\u5e2d\u4e86\u65b0\u65f6\u4ee3\u3002nodejs\u6765\u4e86\uff0c\u6d17\u724c\u5f00\u59cb\uff0c\u524d\u7aef\u4eba\u5458\u5929\u7136\u5bf9\u591a\u7ec8\u7aef\u3001\u591a\u5c4f\u3001\u4ea4\u4e92\u3001\u4f53\u9a8c\u7684\u5173\u6ce8\u4f1a\u4e3a\u540e\u7aef\u6846\u67b6\u5439\u8fc7\u4e00\u7f15\u65b0\u98ce\uff0c\u7ed9\u8fd9\u505c\u6ede\u7684\u6280\u672f\u9886\u57df\u6ce8\u5165\u6d3b\u529b\u3002\u2014\u2014\u6240\u4ee5\u6211\u662f\u8d5e\u6210\u540e\u7aef\u5de5\u7a0b\u5e08\u5b66\u4e60nodejs\u7684\u3002

\u540c\u65f6\u95ee\u9898\u4e5f\u5f88\u591a\uff0c\u8fd9\u4e9b\u56f0\u96be\u548c\u9690\u60a3\u4e0d\u80fd\u4e0d\u63d0\uff1a
1\uff0c\u4e0d\u53ef\u5ffd\u89c6\u7684\u540e\u7aef\u6280\u672f\u95e8\u69db\u3002
\u4e0d\u80fd\u4e0d\u63d0\u8fd9\u832c\uff0c\u5373\u4fbfmidway\u5f88\u52a1\u5b9e\u7684\u53ea\u6311\u9009\u4e86\u89c6\u56fe\u5c42\u4f5c\u4e3a\u4e3b\u653b\u65b9\u5411\uff0c\u4f46\u4e0d\u53ef\u907f\u514d\u7684\u63a7\u5236\u5668\u5c42\u8fd8\u4f1a\u5e26\u8fdb\u6765\u5927\u91cf\u6280\u672f\u95ee\u9898\u9700\u8981\u89e3\u51b3\uff0c\u6bd4\u5982\u914d\u7ba1\u3001\u90e8\u7f72\u3001\u65e5\u5fd7\u76d1\u63a7\u3001\u8fd0\u7ef4\u5de5\u5177\u3001SOA\u3001\u52a0\u89e3\u5bc6\u3001\u4e8b\u52a1\u3001\u7f13\u5b58\u7b56\u7565\u3001\u6d88\u606f\u961f\u5217\u3001\u5f02\u6b65\u8c03\u7528\u3001\u5b89\u5168\u95ee\u9898\uff0c\u603b\u6709\u907f\u4e0d\u5f00\u7684\u6697\u7901\u3002\u5bf9\u963f\u91cc\u76ee\u524d\u7684\u540e\u7aef\u6280\u672f\u6808\u6765\u8bf4\uff0c\u8fd9\u4e9b\u6280\u672f\u80cc\u540e\u662f\u65e0\u6570\u7684\u7cfb\u7edf\u548c\u5e73\u53f0\uff0c\u7f3a\u4e00\u4e0d\u53ef\uff0cmidway\u76ee\u524d\u8fd8\u662f\u4e2a\u73a9\u5177\u3002\u66f4\u4f55\u51b5nodejs/web framework\u672c\u8eab\u90fd\u5728\u98de\u901f\u6f14\u53d8\u4e4b\u4e2d\uff0cES5\u5230ES6\uff0c\u6280\u672f\u7279\u6027\u53d8\u5316\u5267\u70c8\u3002\u5373\u4fbf\u7531\u524d\u671f\u63a2\u8def\u8005\u5b8c\u6210\u4e86\u57fa\u7840\u8bbe\u65bd\u5efa\u8bbe\uff0c\u540e\u671f\u4ed6\u4eba\u8fdb\u5165\u7684\u5b66\u4e60\u6210\u672c\u4e5f\u975e\u5e38\u9ad8\u3002\u65f6\u95f4\u957f\u4e86\uff0c\u524d\u7aef\u5de5\u7a0b\u5e08\u672c\u8eab\u53c8\u81ea\u7136\u4f1a\u5206\u5316\u6210\u7eaf\u524d\u7aef\u548cnodejs\u5de5\u7a0b\u5e08\uff0c\u5982\u6b64\u524d\u540e\u7aef\u5929\u7136\u53c8\u4ea7\u751f\u4e86\u9694\u9602\uff0c\u5475\u5475\uff0c\u5206\u4e45\u5fc5\u5408\uff0c\u5408\u4e45\u5fc5\u5206\u3002

2\uff0c\u524d\u7aef\u4e0d\u52a1\u6b63\u4e1a\u3002
\u6b63\u662f\u56e0\u4e3a\u56f0\u96be\u91cd\u91cd\uff0c\u540e\u7aef\u6280\u672f\u6bd4\u524d\u7aef\u590d\u6742\uff0c\u52a0\u4e0a\u65b0\u9886\u57df\u5bb9\u6613\u51fa\u6210\u679c\uff0c\u5ba2\u89c2\u4e0a\u9020\u6210\u4e86\u524d\u7aef\u7cbe\u82f1\u529b\u91cf\u4f1a\u5927\u91cf\u503e\u659c\u5230\u8fd9\u4e2a\u9886\u57df\uff0c\u8fdb\u800c\u4f7f\u7eaf\u524d\u7aef\u6280\u672f\u505c\u6ede\u4e0d\u524d\uff0c\u5185\u90e8\u4eba\u5fc3\u6d6e\u52a8\uff0c\u5982\u679c\u7ba1\u7406\u4e0a\u4e0d\u80fd\u5f88\u597d\u7406\u6e05\u957f\u671f\u76ee\u6807\u548c\u77ed\u671f\u8ba1\u5212\u3001\u524d\u540e\u7aef\u5982\u4f55\u5206\u79bb\u7b49\u5173\u7cfb\u548c\u5229\u76ca\u7684\u8981\u5bb3\u95ee\u9898\uff0c\u5bf9\u516c\u53f8\u6765\u8bf4\u662f\u559c\u5fe7\u53c2\u534a\u7684\u3002

3\uff0cJS\u7684\u6280\u672f\u7f3a\u9677
\u56e0\u4e3aES\u4e00\u76f4\u5728\u8fdb\u5316\u4e2d\uff0cES6\u7684yield\u90e8\u5206\u89e3\u51b3\u4e86callback hell\uff0cmodule\u4e5f\u521d\u6b65\u6709\u4e86\uff0c\u4f46\u662f\u697c\u4e0a\u63a8\u5d07\u7684\u524d\u540e\u7aef\u4ee3\u7801\u5171\u4eab\u548c\u6a21\u677f\u5171\u4eab\uff0c\u5728\u6211\u770b\u6765\u6070\u6070\u4e0d\u592a\u53ef\u884c\u3002\u5bf9\u963f\u91cc\u6765\u8bf4\uff0c\u540e\u7aef\u4ee3\u7801\u662f\u9700\u8981\u4fdd\u62a4\u7684\uff0c\u5927\u91cf\u6a21\u677f\u3001\u6821\u9a8c\u51fd\u6570\u7b49\u4ee3\u7801\u5982\u679c\u66b4\u9732\u51fa\u53bb\uff0c\u5bf9\u7f51\u7ad9\u7684\u5b89\u5168\u662f\u4e00\u5927\u5a01\u80c1\uff0c\u8fd9\u4e2a\u597d\u5904\u5b9e\u5728\u9e21\u808b\u3002\u8b6c\u5982\u6700\u8fd1\u6211\u4eec\u5c31\u53d1\u73b0JDK\u7684\u4e00\u4e2a\u52a0\u5bc6\u7c7b\u5e93\u5728js\u4e2d\u6839\u672c\u627e\u4e0d\u5230\u66ff\u4ee3\u65b9\u6848\uff0c\u81ea\u5df1\u5199\u7684\u8bdd\u5b9e\u5728\u529b\u6709\u4e0d\u902e\u3002nodejs\u8fd8\u592a\u5e7c\u5c0f\uff0c\u8fd8\u6709\u5f88\u591a\u6280\u672f\u95ee\u9898\u5c31\u4e0d\u5c55\u5f00\u4e86\u3002

4\uff0c\u597d\u5904\u4e0d\u591f\u660e\u663e\uff0c\u63a8\u5e7f\u56f0\u96be\u3002
\u8fd9\u624d\u662fmidway\u771f\u6b63\u7684\u6b7b\u7a74\u3002\u5982\u524d\u6587\u6240\u8bf4\uff0c\u76ee\u524d\u7684\u524d\u540e\u7aef\u5206\u79bb\u8fd0\u52a8\u8fd8\u662f\u90e8\u5206\u524d\u7aef\u5de5\u7a0b\u5e08\u7684\u5b64\u7acb\u884c\u4e3a\uff0c\u7edd\u5927\u591a\u6570\u540e\u7aef\u5de5\u7a0b\u5e08\u548c\u4e00\u7ebf\u4e3b\u7ba1\u5bf9\u6b64\u6beb\u4e0d\u5173\u5fc3\uff08\u6211\u9664\u5916\uff09\uff0c\u56e0\u4e3amidway\u5ba3\u79f0\u7684\u75db\u70b9\u4e0d\u662f\u4ed6\u4eec\u7684\u75db\u70b9\uff0c\u5ba3\u79f0\u7684\u4f18\u70b9\u53ea\u6709\u8282\u7ea6\u540e\u7aef\u4eba\u529b\u8fd9\u4e00\u6761\u5bf9\u4ed6\u4eec\u6709\u70b9\u610f\u4e49\uff0c\u800c\u8fd9\u4e9b\u4eba\u624d\u662f\u51b3\u5b9amidway\u547d\u8fd0\u7684\u4eba\uff01\u968f\u7740\u65f6\u95f4\u7684\u63a8\u79fb\uff0c\u8fd9\u53ef\u80fd\u7f13\u89e3\uff0c\u4e5f\u53ef\u80fd\u5c16\u9510\uff0c\u6bd5\u7adf\u8fd9\u662f\u524d\u7aef\u4eec\u7684\u897f\u90e8\u5927\u5f00\u53d1\u8fd0\u52a8\uff0c\u662f\u6269\u5730\u4e4b\u6218\u3002

\u603b\u7ed3\u3002
\u76ee\u524dmidway\u81f3\u5c11\u8fd8\u6709\u534a\u5e74\u7684\u8def\u8981\u8d70\uff0c\u524d\u7aef\u8981\u514b\u5236\u81ea\u5df1\u7684\u51b2\u52a8\uff0c\u6709\u9650\u5ea6\u4f7f\u7528nodejs\uff0c\u76f8\u4fe1\u5728\u8fd9\u4e2a\u9886\u57df\u5927\u6709\u53ef\u4e3a\uff0c\u4f46\u90a3\u65f6\u5019\u4ed6\u4eec\u5c31\u4e0d\u662f\u524d\u7aef\u4e86\uff0c\u4ed6\u4eec\u4f1a\u6709\u4e00\u4e2a\u54cd\u4eae\u7684\u540d\u5b57\u53eb \u201cNodeJS\u5de5\u7a0b\u5e08\u201d\u3002

【贺师俊的回答(17票)】:
泻药。
1. 这系列文章写得很好。
【注意,熟悉我的同志应该知道,我极少给出“很好”的评价。】
2. 这系列文章以及其背后的实践重新树立了淘宝系前端工程水准的领先地位。
【在此之前的一段时间内,至少从外部来看,淘宝已经落后于狼系和企鹅系了。】
3. 这系列文章及其背后的实践也证明了nodejs对于前端来说不仅在工具链而且在架构层面的意义。
【注意,这系列文章中的思路其实并不新鲜,但是在淘宝这样规模而且业已非常成熟的产品中实施这样的转变,我认为是具有标志意义的。】
4. 具体细节上仍有许多改善空间,如此系列的第4篇《前后端分离的思考与实践(四)》在防御XSS时还是存在一些传统问题。这方面在参加杭JS的时候,我跟淘宝的herman同学有过沟通,具体就不在本问题展开了。因为这是局部问题,对整体架构影响不大。
5. 注意,以上评价的都是架构,或者说是思路。实施效果是不是好,我相信他们自己的说法。但Midway框架本身因为没有看到具体文档和代码,而且其开发的目的首要是满足淘宝的需求,因此其本身或其具体组件是否在普遍意义上适用和优秀,无法作出判断。
【徐飞的回答(19票)】:
早上看到贺老出马,也忍不住写了一篇来谈一下苏宁这样的公司对这方面的考虑。
近两年来,我一直在思考如何改进前端体系的开发模式,这里面最基础的一点就是前后端的分离。谈到前后端分离,也有一个误区,认为仅仅是以浏览器作分界,把这两部分的代码分离出来。但其实是,做这件事情的本意,是要解决开发模式的问题,也就是要分离前后端开发人员的职责。
针对不同类型的Web产品,这个分离方式是有所不同的。对于Web应用,因为它跟服务端的交互基本就是AJAX或者WebSocket接口,所以这个分离是天然的,整个前端基本都是静态HTML模板,JavaScript模块,以及CSS和相关静态资源,但是对于网购产品这样的形态,它的做法就不一样。
## 展示占主要部分的产品
网购产品的展示需求很重要,图片等资源载入非常多,但相对的操作却很少,基本只有搜索商品,加购物车,结算这样的环节。传统这样的产品,多半是这么个工作流程:
交互出高保真图,前端去切图,生成静态HTML加展示效果,然后,注意,他不是自己接着往下做,而是交给另外一群开发人员,把它转换成服务端模板,比如freemarker或者velocity之类,或者是smarty,为什么要这么做呢?因为这类产品讲究一个首屏优化,是首屏而不是首页,这就意味着对于首屏来说,经过的环节应当尽可能少,比如说,就不能先载入客户端模板,再AJAX一个数据,然后去渲染一下。这么做的性能肯定是不如服务端把HTML生成好,然后一次请求加载的。
这个过程肯定是有一些问题的,比如说,如果开发人员B在套模板的过程中,发现原先的静态HTML部分有问题,应该怎么办?大家知道,一个对HTML和CSS都很熟悉,同时又可以写业务逻辑的前端开发人员是很稀缺的,所以,多数情况下,这两边的技能是不同的,如果是简单的页面问题,这个开发人员可能自己也就解决了,如果他解决不了,怎么办?
如果B自己不改,把他已经搞成服务端模板的代码返回给前端人员A,A也没法下手,因为已经是服务端模板,A手里没有环境,改了之后不知道对不对,不能预览。那么,B把问题告诉A,A修改他的原始版本,然后再拿给B又怎样呢?这时候B又麻烦了,他要对比两次修改的部分,把自己前一阵的修改合并进去。
所以,不管怎么搞,这里面都很折腾。
Midway这个产品,他想要解决什么问题呢?既然说前端人员没法预览模板的原因是,后端在使用服务端模板,那么,我能不能找一种两边都可用的模板,你能在服务端渲染,我也能在客户端预览?服务端跟浏览器端同时都能运行的语言是什么?只有JavaScript。
所以,大家就往nodejs里面去发掘了,一个普通的JavaScript模板库,它在浏览器端也可以渲染,在nodejs端也可以输出成HTML,这时候,那些原来负责整合模板和逻辑的人员改用nodejs,是不是就解决这问题了?
想象一下这个场景多么美好:前端来决定某个模板是服务端渲染还是客户端渲染,当首屏的时候,就在nodejs里面生成HTML,不是首屏的时候,就AJAX过来在浏览器端渲染展示。
从技术方案上看,这么做很好了,工程上又带来另外一些问题,那就是对熟练JavaScript开发人员的需求量大增。对阿里这样的公司来说,前端有大几百人,别的公司只能仰望,所以他当然可以放手一搞,但对我们苏宁这样,前端人数不大的,就麻烦了。如果我们也引入这样的方案,就面临把很大一部分Java开发人员转化成JavaScript开发人员这么一个问题,这个事情短期内肯定是无法解决的,所以反过来会增加前端这边的压力。所以暂时还用不了阿里这样的方案,只能努力先提高人员水平再看情况。
服务端引入nodejs还有别的优势,比如说请求合并等等,这个也可以用其他方式变通解决,比如加一个专门的跟现有后端同构的Web服务器,在那边干这些事。
## 展示和业务逻辑较均衡的产品
对于另外一些场景,也有类似的问题,比如支付产品,展示相对没那么重,但是又算不上Web应用,它面临另外一种情况的前后端分离。这种场景下,前端的出静态HTML和DOM操作类的JavaScript,业务开发人员负责写后端,还有另外一部分业务逻辑的JS。
这里的问题是什么呢?是jQuery式代码造成的协作问题。比如说:
$(".okBtn").click(function() { $.ajax(url, data) .success(function(result) { $("someArea").html(_.template("tpl", result)); });});
因为前端人员的稀缺,所以他不可能帮你把业务逻辑写出来,所以说,这里面$.ajax往里的部分,要业务人员自己写。然后,数据得到之后,又要去处理界面部分。
很多场景下,处理界面远不是这么搞个模板放上去就完事的,所以业务开发人员感到很烦闷,为了这么一点小问题,反复去找前端的人来搞,很麻烦,自己搞又特别花时间,所以都很苦闷。
这同样是一种前后端的分离,只是这个分界线不在浏览器,而在于:是否写业务逻辑。对付这种场景,解决办法就是加强JavaScript代码的规划。现在流行那么多在前端做MV*的框架,不考虑Angular这类太重量级的,来看看Backbone这样的,它到底解决了什么问题?
很多人说,Backbone虽然小,但根本不解决问题。这句话有一定道理,但前提条件是你自己的JavaScript代码分层已经做得很好了。如果做得不好,它就可以协助你解决分层的问题。
刚才那段代码,它的问题在哪里呢,在于职责不清晰。一个函数只能做一件事,这是共识,但由于回调等方式,所以不经意就破坏了函数的单一性、完整性。我们试试来拆开它。
对于一个后端开发人员来说,他为什么常常害怕写前端代码?是因为JavaScript语言吗?其实不是,我们用来写业务逻辑的时候,只会使用JavaScript一个很小的子集,对于这个子集来说,它并不存在多大的学习困难,最麻烦的地方在于DOM、BOM等东西,对于一个后端开发人员来说,如果要求他在掌握服务端代码编写的同时,还要去学这些,那真是有些不容易,所以,我们来给他省点事。
现在我们的出发点是,把这段代码拆给两个不同的人写,一个人操作DOM,另外一个人只写逻辑,绝对不操作DOM。前面这个代码拆给前端维护,后面这个拆给业务开发人员。
最老圡的方式:

a.js
$(".okBtn").click(function() { b1(data);});function a1(result) { $("someArea").html(_.template("tpl", result));}
b.js
function b1(data) { $.ajax(url, data) .success(a1);}
现在大家是不是相安无事了?
如果这么做的话,AB双方要做很多约定,也就是说,这个过程仍然是一个螺旋链。比如说,A先写点击事件的绑定,然后想起来这里要调用一个请求,就去找B写b1方法。B在写b1的时候,又想到他要调用一个界面展示方法a1,然后又来找A写,来回也挺折腾。
况且,有这么一天,A在另外一个地方也想调用b1了,但是由于b1的回调已经写死了,比较蠢的办法就是在a1里面再判断,这是什么东西点击造成的,然后分别调用不同的回调。如果情况复杂,那这个代码写出来真是没法看。
如下:
a.js
var type = 0;$(".okBtn").click(function() { type = 1; b1(data);});$(".okBtn1").click(function() { type = 2; b1(data);});function a1(result) { if (type1) { $("someArea").html(_.template("tpl", result)); } else if (type2) { // ... } type = 0;}
b.js
function b1(data) { $.ajax(url, data) .success(a1);}
稍微好一些的办法是,在b1中,直接返回这个请求的promise,这样可以由调用方决定到底该干什么。
如下:
a.js
$(".okBtn").click(function() { b1(data).success(function(result) { $("someArea").html(_.template("tpl", result)); });});$(".okBtn1").click(function() { b1(data).success(function(result) { // ... });});
b.js
function b1(data) { return $.ajax(url, data);}
如果要对返回数据作统一处理,也可以很容易地在b1中,用promise重新封装了返回出来,只不过这样在a.js里面,直接调用的就不是success,而是then了。
注意到这样的代码还有问题,比如说大量的全局函数,不模块化,容易冲突。此外,没有一个地方可以缓存一些共享数据,比如说这么一个场景:
界面上两个块M和N,其中,M初始载入并加载数据,N在初始的时候不载入,而是在某个按钮点击的时候载入,而M和N中各有一个列表,数据来源于同一个服务端请求。
现在就有个问题,当N载入的时候,它的数据怎么来?比较老土的方式,肯定是载入N的时候,同时也再去请求一下数据,然后渲染到N上。
从一个角度看,如果说不重新请求,N的这个数据应当从哪里来?从另外一个角度看,如果重新请求了,发现数据跟之前的产生了变更,是否要同步给M,怎么同步给它?
我们看看类似Backbone这样的框架,它能提供怎样的机制呢?或者如果我们不用它,怎么自己把这个分层封装得更好一些?
首先,是建立一个数据模型,在它上面添加数据的缓存:
define("model", [], function() { var Model = { data: null, queryData : function(param, fromCache) { var defer = q.defer(); if (fromCache || this.data) { defer.resolve(this.data); } else { var self = this; this.ajax(url, param).success(function(result){ self.data = result; defer.resolve(result); }); } return defer.promise; } }; return Model;});
这么一来,我们在模型上作了数据的缓存,如果调用的时候加fromCache参数,就从缓存读取,否则就请求新的。为了在两种情况下,调用方接口能保持一致,把整个函数封装成promise,以便接着调用。这里的模型定义成单例了,假定是全局唯一的,可以根据需要调整成可实例化的。
这个时候,视图层就要封装DOM和事件的关联关系:
define("view", ["model"], function(Model) { function View(element) { this.element = element; this.element.selector(".okBtn").click(function() { var self = this; var fromCache = true; Model.queryData({}, false).then(function(result) { self.renderData(result); }); }); } View.prototype = { renderData: function(data) { this.element.selector("someArea").html(_.template("tpl", result)); } };});
这个时候,多个视图实例的情况下,数据也能够较好地利用。
这样,前端写这个View,后端写Model,可以作这么个分工。
这个只是很简陋的方式,在复杂场景下还有很多不足,在这里先不展开了。更复杂的场景也就是类似Web应用那种方式,稍后专门写一篇来展开。
## 小结
我们再来回顾前后端分离所要解决的问题,是分离前端和业务开发人员的职责,这个方案怎么定,是应当随着团队状况来确定的。比如阿里前端厉害,人多势众,他的前端就要往后推,去占领中间层。我们苏宁这样的公司,前端比较薄弱,只能在很多场景下,让出中间层,否则战线铺太广只能处处被动。
同一个中途岛,在不同的形势下,占还是不占,是很考验前端架构师的一个问题。
对阿里的这种实践,我们会持续围观,寻找并创造合适的出手时机。
【rank的回答(4票)】:
简单说下自己的看法。

前端不再继续「单纯」在 kissy 上下功夫,而可以考虑向后的延伸架构是一种前端的进步,这种前端架构将重定义阿里的前端工程师工作,很多互联网公司比阿里先行一步。

这个思路与与最早阿里很多前端没有碰后端(例如模板)有很大的关系,用 NodeJS 作中间层能解决现面临的问题,是一种不限于解决当前问题的长远解决方案。

具体是否能解决和解决得好,在于细节,不在新,而在过渡。如,如何过渡目前 NodeJS 与原来的数据交互,如何灰度过渡,工作量等。

平台化与接口化思路(后端数据接口以 Services 存在)让 amazon 收益非浅,现在后端平台化接口化在大公司趋势明显。
平台化需要更多更快的应用层开发选型,NodeJS 是不错的一种。NodeJS 虽然还是有些问题,但从信息面与我们自己的应用经验来看,已有慢慢成为后端 WebApplication 的一种很好的选型方案的趋势。

总的来说,是个趋势。
【Hex的回答(1票)】:
我认为这就是所谓的大前端开发模式。模式确实是好模式,但是真正实践起来,和后端工程师的沟通和协调也会遇到很多问题。
我做过的几个项目都是采用这种大前端的开发模式,前端基于Transformers框架+CodeIgniter组成大前端,这样确实可以很好的隔离前后端,项目可维护性大大提高。
【邓欣欣的回答(1票)】:
上周去杭州玩了下,和之前的阿里同事做了些技术交流,发现这一年,阿里的前端在流程改进上下了很大功夫; 题主所说的中途岛应该是 UDC 团队做的,应该说思路不是很新鲜,国外有 ebay 向 nodejs 的转型案例,国内之前也有百度音乐移动端的案例;
但对阿里前端来说,意义确是很重大,解决了合作流程中的一个很大问题:之前阿里的前端是只写静态 demo,写完给开发套模板,开发不太懂 html,漏写个标签,然后找前端调试,一来一去很折腾,是个必须干但又是个没啥技术含量的事; 中途岛可以很好的解决这类蛋疼事,但是请不要认为前端就因此会后端了,无非是之前浏览器用 ajax 请求接口,现在咱用 node http去请求呗,框架做得牛逼点,统一适配出前端的ajax 接口也不是不可能呀~~,想想嘛,为啥要用 node 呢? 牛逼直接写 java 啊。。哈哈哈~
其他的 F2E 团队也做些很不错的流程改进工具,同样不是很新鲜,但对阿里前端都是比较有意义的工具:
def: 项目构建与发布工具,与阿里的 gitlab, scm 整合,各种 脚手架,build,combo,发布,一条命令搞定,确实很方便;
dip:数据接口平台,定义业务线前后端数据格式的一个内部公共平台,基于 json-schema,好像也可以给你提供 mock 接口;
uitest:前端持续集成平台;之前这东西我是边做边吐槽的,似乎刚上线,类似 jenkis 这些,提交或者发布代码时,先帮你跑一次测试用例;目前通用测试库比较少。
Trace:好像是叫这个名字吧,监控平台,这个比较早就有了,用来监控各个业务线页面的运行状况并搜集各种用户数据,如分辨率,UA
我看来 def 和 dip 对阿里前端的作用会更大些,uitest 估计作用一般,阿里前端是不注重代码质量的,测试用例也仅在几个重要的直接影响交易的业务线会写。
【许文敏的回答(0票)】:
确实不错,从职责上来区分前后端分离才是王道,nodejs将成为前端工程师的基础技能
【猎人豆豆的回答(0票)】:
不要把简单的问题搞复杂,对于淘宝这样规模的公司,有些牵一发而动全身的改动,最好是在权衡风险和收益后再决定,我们是技术的使用者,而不要被技术牵着鼻子走.
【罗正烨的回答(2票)】:
前面前端的大牛们都说了,我换个角度聊聊。
这么讲吧,阿里的前端为什么比其它公司走的远,是因为他们有很多前端,还有很多不用写大量业务逻辑的前端大牛。大牛的作用,就是折腾。阿里的前端工程师水平在自身领域实践上已经跟得上后端。
但这个架构所谓的分离,其实是把很多原来前端不需要做的事揽到了自己的手上,增加前端架构师的KPI,让前端做了更多的事,周报好写。因为nodejs和前端都是js,所以学习成本并不算高,但是对一个技术人员的要求是比原来更高了。
但是,他们团队有很多HC,有很多钱。。所以像我这种一个产品线只有一二个前端的,要是这么玩儿,招人跟不上不说,然后还可以把自己累死。
所以技术选型和架构这种事,还是要根据自己团队的能力和招人啊。

扩展阅读:淘宝 ... you are welcome ... momi交友软件是真人么 ... 淘宝 经常 滑块 ... 新手s应该怎么玩 ... whatsapp messenger2024 ... momi聊天软件靠谱吗 ... 为什么是什么怎么做的逻辑 ... 淘宝 聊天 不见了 ...

本站交流只代表网友个人观点,与本站立场无关
欢迎反馈与建议,请联系电邮
2024© 车视网