Phoenix working as a front end file server

Hello all,
I want to know how can I build a phoenix file server which will be work as a :-

  • file server for my vuejs app, the code will be already production build. Something like express-node thing.
  • all phoenix have to do is server the build assets and files on a particular url hits.
  • if u can help a step deeper I am highly interested to know how can I use lazy loading here.

As a beginner I need some guidance, I assure you that I will try my level best and hopefully will be able to contribute something good to community.
Thanks :slight_smile:

To be honest, I would not use Phoenix just to serve static files. As a full featured framework, Phoenix has a lot of stuff for different things and using it for just static files is a waste of resources and adds needless complexity.

Instead I would use a web server like Nginx, or if you really want to go with Elixir, just Plug (which contains Plug.Static for serving static files: https://hexdocs.pm/plug/Plug.Static.html).

1 Like

Thanks for replaying @Nicd :slight_smile:,
True that phoenix has greater power and I am using those powers for my backend in the most efficient way I can.

What I was thinking is just that since make a file server over node will be less efficient than making with phoenix. That’s why I just raised the doubt.

If you already have a Phoenix doing other stuff, then you obviously can use it to serve your VueJS files. Just place your built files under priv/static and they will be served by Phoenix. You can check the Plug.Static configuration in your endpoint.ex, it will look something like this: https://gitlab.com/code-stats/code-stats/blob/master/lib/code_stats_web/endpoint.ex#L8-18

Actually I have planned this same.
But as having a totally different dedicated server for front end will give me better load balancing and traffic management ( my opinion), I am trying to make a different phoenix assets provider.

Having two or more Erlang VMs on the same machine will result in more OS level context switching and thus worse performance. You would be better served with just one Phoenix instance in this case. Unless you are talking about a totally different machine, but then my point in the first post stands, it would be a waste to put Phoenix there just to serve static assets.

1 Like

So what you can do, and - in fact - I do it, is that you start two, not one Phoenix instances.

I assume you have a single page app here.

You can have an umbrella project, what I would do (and in fact I did in the past is to have):

ui - pure JavaScript project directory, with something like webpack configured to save compiled files to ../web/priv/static

web - Phoenix front-end, started on port say 4000. There is just one catch-all controller, mounted with: get("/*path", PageController, :index) in router. The controller only outputs the index.html file fount in web/priv/static for all requests. In development mode it is also configured to live reload stuff. So everything you drop into web/priv/static gets served already using Phoenix’s plug for serving static files. We needed the catch-all route since it’s a client-side routing and when user reloads the page on given URL we still want to serve initial index.html and then JS routing takes over when the JS apps loads.

api - Phoenix API, started on port say 4002, multiple controllers, channels etc. all go here.

and then obviously some other apps I might have like core or db or whatever else I decide to split the app into.

I like the above configuration because it’s a clear separation of concerns, and JavaScript programmer would be only concerned with ui folder and it’s contents, while someone who’s writing API only with api and there’s no routing conflict with catch-all route in web.

3 Likes

Totally agree @hubertlepicki
Thanks for the elaborated explanation, I also liked the setup to make things cleaner for initial phase.
Sir, if possible please explain a bit more on how can I serve the files based on url enter (lazy loading), i.e only that much of bundle will be served. Say the generic bundle and a page specific bundle, not whole. Just to make an speed enhancement. :smile:

Here, I have basic idea of setting routes function based on urls and serving files on that only, but not too sure.

I would love to know that myself in fact. :slight_smile: I never had to do that and so far it was okay to bundle everything up together. But I can definitely see the value in doing that, just that I have zero experience in the area.

1 Like