10
votes

I have a pre-compiled ember.js app (which fronted-js-framework shouldn't matter here), which basically consists of a folder with a index.html file, and a few js/css assets.

I placed this folder under /priv/static in my phoenix app, and tried to get the routing to serve it... without success so far. I'm on phoenix version 0.17.1 (same as 1.0 afaik). I tried the following steps, in that order:

  • In endpoint.ex, I removed the only: ~w(...) filter.
  • Implemented a bare minimum controller with a single action to serve the file: def index(conn, _params) do redirect conn, to: "/my_app/index.html" end
  • added the controller to my routes.ex: get "/my_app", MyCustomController, :index

None of the above steps worked so far, I only get the Error no route found for GET /my_app/index.html. How could I solve this Issue? I just want to map the URL "/my_app" (or, if nothing else works, "/my_app/index.html") to the path priv/static/my_app/index.html within my phoenix app. Any ideas?

EDIT:

The basic workflow I try to implement is the following:

I have different developers that build some ember.js SPAs in their dedicated folder, located in $phoenix_root/apps/. So I have a developer building $phoenix_root/apps/my_app with ember and ember-cli. This developer uses ember server while developing his app, and has mix phoenix.server running in the background, because the phoenix app itself exposes the required data as an RESTful API.

After each implemented feature, the frontend developer types ember build [...], this task compiles the whole ember.js frontend app into a single folder, with a index.html file and some assets, and moves this folder to $phoenix_root/web/static/assets/my_app. Then phoenix (or, brunch) triggers, and copies this stuff as-is to $phoenix_root/priv/static/my_app, ready to be served like any other asset.

The point is to be able to build a bunch of isolated "frontends" as self-contained packages within a single code base (the phoenix app), while the phoenix app itself has additional (other) stuff to do.

Because the Frontend-Developers auto-generate the SPA everytime, modifying the ever-new index.html file is something I highly want to avoid. Performance-wise it would be the best to just serve these SPAs as the static files they are - they initialize on their own inside the user's browser.

I hope this adds some clarification why I do this.

EDIT 2:

I have a working solution now, see the example repo I created for demonstration purposes: https://github.com/Anonyfox/Phoenix-Example-Multiple-SPA-Frontends

Necessary modifications to the phoenix app:

  • modify endpoint.ex' Plug.Static to include the SPAs and their assets.
  • restart mix phoenix.server after this!

Neccessary modifications to the ember.js apps:

  • add "output-path": "../../web/static/assets/*my_app*/" to .ember-cli, convenience setting to run ember build always with this path
  • add baseURL: '/*my_app*/' and locationType: 'none' to config/environment.js
  • rm -rf .git if you want to have all the code versioned within a single project (the purpose of this question)
2
I have done literally the same in a new app and it worked just fine. Do you have a simple app that shows the issue?José Valim
Also, to be double sure, if you change anything in lib, you need to restart your app.José Valim
Since you're using emberjs (with separate developers), I would suggest you check this addon for deploy. ember-cli.github.io/ember-cli-deploy/docs/v0.4.x Also check these - blog.abuiles.com/blog/2014/07/08/… - youtube.com/watch?v=QZVYP3cPcWQVysakh Sreenivasan
Just a comment on your question – my personal opinion is that storing ember.js (or any other JS framework) project inside of backend codebase is bad practice. Just put them in completely separate folders, use ember's scripts to pre-process files, and them with apache/nginx.EugZol
@JoséValim restarting phoenix.server in conjunction with a config-modification of the ember apps did the trick, thank you. I'll update my question with the solution... unfortunately I can't give you the bounty for a comment :)Maximilian Stroh

2 Answers

5
votes

Your setup should just work. There is only one caveat: every time you change something in lib, you must restart your application.

The only directory that is code reloaded on requests is web. In fact, that's the only difference between lib and web directories. That's why you put long running processes and supervisor in lib, because there is no need to code reload them, and everything else goes in web.

2
votes

I think easiest way to replace web/templates/layout/app.html.eex with your index html and change assets path inside with <%= static_path(@conn, "/js/app.js") %> helpers to grab your ember app js file from static folder.

Router part:

scope "/", Chat do
  pipe_through :browser
  get "/", PageController, :index
end

And inside action render conn.