В тази статия ще покажа как е възможно да се споделя един и същ код от клиентската страна в javascript и сървърната страна в pyhton.
Това е възможно благодарение на Haxe, език, който може да компилира на 8 езика (js, php, flash, python, java, c#,neko,c++).
В този пример същият шаблон се изобразява в python и javascript с Erazor, библиотека с шаблони, и страниците се обслужват с колба.
можете да намерите кода на този пример в това хранилище github https://github.com/francescoagati/isomorphic-haxe-python.
Нека видим отделните части на проекта.
build.hxml
В този файл има декларациите за целите на javascript и python, отделени от arg next.
За всяка цел има пътя до целевата папка, главния клас и библиотеките, които трябва да бъдат включени.
-js build/static/js/client.js -main Client -lib erazor -dce full -D analyzer --next -python build/server.py -main Server -lib erazor -dce full -D analyzer
arg dce се използва за активиране на функцията „Елиминиране на мъртвия код“ , която позволява да се елиминира кодът, който не се използва, а arg „-D анализатор“ се използва за активиране на статичен анализатор за оптимизации на кода.
article.html
Е шаблонът. Благодарение на Erazor и haxe макросите, шаблонът се преобразува в haxe код и се компилира към целевия език.
<h1>@title</h1> <br> <p>@body</p>
Template.hx
Класът за изобразяване на шаблона.
Анотацията includeTemplate се използва за дефиниране на пътя на шаблона.
@:includeTemplate("templates/article.html") class Template extends erazor.macro.HtmlTemplate { public var title:String; public var body:String; }
Server.hx
Flask се използва за обслужване на страниците.
Haxe externs се използват за картографиране на методите на Flask към клас Haxe.
Маршрутът от страната на сървъра обслужва страницата, компилирана в python, докато маршрутът от страната на клиента връща маркер на скрипт за изпълнение на javascript кода.
import haxe.Constraints.Function; import python.KwArgs; using python.Lib; @:pythonImport("flask", "request") extern class Request implements Dynamic { public static var args:python.Dict<String,Dynamic>; } @:pythonImport("flask", "Flask") extern class Flask { function new(module:String); function run(?opts:KwArgs<{?debug:Bool}>):Void; function route<T:Function>(path:String, ?opts:KwArgs<{?defaults:Dynamic}>):T->T; } class Server { public static function main() { var app = new Flask(untyped __name__); app.route("/server")(serverSide); app.route("/client")(clientSide); app.run(); } static function clientSide() { return ' <html> <body> <div id="content"></div> <script src="static/js/client.js"></script> </body> </html> '; } static function serverSide() { var template = new Template(); template.title = "Hello from server side"; template.body = "This content is rendered in python"; return template.execute(); } }
Client.hx
Този клас изобразява шаблона за изтриване и инжектира изхода в div за съдържание.
class Client { public static function main() { var template = new Template(); template.title="Hello for client side"; template.body="This content is rendered in javascript"; js.Browser.document.getElementById('content').innerHTML = template.execute(); } }