123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125 |
- \section{JavaScript Compiler}
- \subsection{Compilation and Macros}
- Erlang JavaScript/OTP Parse Transform has two modes defined
- by {\bf \-jsmacro} and {\bf \-js} Erlang module attributes.
- The first mode precompiles Erlang module functions
- into JavaScript strings. The second one exports Erlang functions
- into a separate JavaScript file ready to run in the browser or Node.js.
- \paragraph{}
- Sample usage of {\bf \-jsmacro} and {\bf \-js}:
- \begin{lstlisting}
- -module(sample).
- -compile({parse_transform, shen}).
- -jsmacro([tabshow/0,doc_ready/1,event/3]).
- -js(doc_ready/1).
- \end{lstlisting}
- \subsection{Erlang Macro Functions}
- Macro functions are useful for using N2O as a server-side framework.
- Functions get rewritten during Erlang compilation into a JavaScript format
- string ready for embedding. Here is an example from N2O pages:
- \begin{lstlisting}
- tabshow() ->
- X = jq("a[data-toggle=tab]"),
- X:on("show",
- fun(E) -> T = jq(E:at("target")),
- tabshow(T:attr("href")) end).
- doc_ready(E) ->
- D = jq(document),
- D:ready(fun() ->
- T = jq("a[href=\"#" ++ E ++ "\"]"),
- T:tab("show") end).
- event(A,B,C) ->
- ws:send('Bert':encodebuf(
- [{source,'Bert':binary(A)}, {x,C},
- {pickle,'Bert':binary(B)}, {linked,C}])).
- main() ->
- Script1 = tabshow(),
- Script2 = event(1, 2, 3),
- Script3 = doc_ready(wf:js_list("tab")),
- io:format("tabshow/0:~n~s~nevent/3:~n~s~ndoc_ready/1:~n~s~n",
- [Script1,Script2,Script3]).
- \end{lstlisting}
- Perform compilation and run tests:
- \vspace{1\baselineskip}
- \begin{lstlisting}
- $ erlc sample.erl
- $ erl
- > sample:main().
- \end{lstlisting}
- \vspace{1\baselineskip}
- You'll get the following output:
- \vspace{1\baselineskip}
- \begin{lstlisting}
- tabshow/0:
- var x = $('a[data-toggle=tab]');
- x.on('show',function(e) {
- var t = $(e['target']);
- return tabshow(t.attr('href'));
- });
- event/3:
- ws.send(Bert.encodebuf({source:Bert.binary(1),
- x:3,
- pickle:Bert.binary(2),
- linked:3}));
- doc_ready/1:
- var d = $(document);
- d.ready(function() {
- var t = $('a[href="#' + 'tab' + '"]');
- return t.tab('show');
- });
- \end{lstlisting}
- \vspace{1\baselineskip}
- As you see, no source-map needed.
- \subsection{JavaScript File Compilation}
- Export Erlang function to JavaScript file with {\bf -js([sample/0,fun\_{args}/2])}.
- You could include functions for both {\bf macro} and {\bf js} definitions.
- \newpage
- \subsection{Mapping Erlang/OTP to JavaScript/OTP}
- Following OTP libraries are partially supported in Erlang JavaScript Parse Transform:
- {\bf lists}, {\bf proplists}, {\bf queue}, {\bf string}.
- \paragraph{\bf Example 1}\
- \vspace{1\baselineskip}
- \begin{lstlisting}
- S = lists:map(fun(X) -> X * X end,[1,2,3,4]),
- \end{lstlisting}
- transforms to:
- \begin{lstlisting}
- s = [1,2,3,4].map(function(x) {
- return x * x;
- });
- \end{lstlisting}
- \paragraph{\bf Example 2}\
- \vspace{1\baselineskip}
- \begin{lstlisting}
- M = lists:foldl(fun(X, Acc) -> Acc + X end,0,[1,2,3,4]),
- \end{lstlisting}
- transforms to:
- \begin{lstlisting}
- m = [1,2,3,4].reduce(function(x,acc) {
- return acc + x;
- },0);
- \end{lstlisting}
|