defmodule ReactPhx.SSR.NodeJS do @moduledoc """ Implements SSR by using `NodeJS` package. Under the hood, it invokes "render" function exposed by `server.js` file. You can see how `server.js` is created by looking at `assets.deploy` command and `package.json` build-server script. """ @behaviour ReactPhx.SSR def render(name, props, slots) do filename = Application.get_env(:react_phx, :ssr_filepath, "./react-components/server.js") if Code.ensure_loaded?(NodeJS) do try do # Dynamically apply the NodeJS.call!/3 to avoid compiler warning apply(NodeJS, :call!, [ {filename, "render"}, [name, props, slots], [binary: true, esm: true] ]) catch :exit, {:noproc, _} -> message = """ NodeJS is not configured. Please add the following to your application.ex: {NodeJS.Supervisor, [path: ReactPhx.SSR.NodeJS.server_path(), pool_size: 4]}, """ raise %ReactPhx.SSR.NotConfigured{message: message} end else message = """ NodeJS is not installed. Please add the following to mix.ex deps: `{:nodejs, "~> 3.1"}` """ raise %ReactPhx.SSR.NotConfigured{message: message} end end def server_path() do {:ok, path} = :application.get_application() Application.app_dir(path, "/priv") end end