I always thought that frontend should not be over bloated in size, usually by "frontend" I imagined a set of HTML, CSS and JS files, which are kind of small, especially when minified and compressed. So you can use whatever framework or library you love, your dev node_modules could be enormous in size, but after the compilation you get something lightweight to be served e.g by Nginx. Yeah, I just described an SPA-like setup, not an SSR when there’s a server process running.
I had an experience building a website with NuxtJS, and it has only runtime logic, so no backend was required. I just did yarn generate
and served all the resulted static with Nginx.
Now I’m building an application which requires a backend (it’s a separate Python process), with dynamic pages like /users/john
and /users/jane
. Nuxt documentation says I can’t use generate
option anymore, cause such routing is dynamic. (technically I can write a set of fetch functions to load users from API during build time and generate corresponding pages, but it doesn’t work well for runtime data). The only option is to use server target of NuxtJs.
There’s even a page describing how to serve Nuxt application with Nginx. It assumes you should use yarn start
command, which starts a Node process. It works fine, dynamic content is routed, caching is performed by Nginx, but.. it doesn’t fit in a model that "frontend is lightweight". I use docker, and it means that now I need to bring huge node_modules
with me. nuxt
package itself is about 200 MB, which is kinda big for a small frontend app. I can run yarn install --production
to save some space, but it still doesn’t solve an issue that resulted image is huge.
Previously, when I wrote some apps in React, they resulted in a single index.html
which I served by Nginx. It means, such dynamic routing was handled by frontend, using react-router
or similar stuff.
To better understand my concerns, here’s some rough comparison:
- My old React apps: ~5 MB of disk space, 0 RAM, 0 CPU, routing is done by
index.html
file - My previous site with Nuxt static option: ~5 MB of disk space, 0 RAM, 0 CPU, routing is done by file system (
/page1/index.html
,/page2/index.html
) - My current site with Nuxt server option: ~ 400 MB or even more disk space for a docker image, RAM, CPU, routing is done by Nuxt runtime
I don’t really want to overcomplicate things. Allocating a lot of resources for a simple web app is too much, especially when you can solve the task with a help of a few static files.
The questions are:
- Am I missing some option in NuxtJS to solve my issue?
- Am I just misusing NuxtJS, and it’s better to get plain VueJS, some vue-router, and develop the app as I described in "previously with react" section?
3
Answers
I think you are making a mistake here about
SPA
mode.Assume that you have a page named
users
in yourNuxt pages
, your folder structure is like this:When you requesting
/users/john
you can take the john fromparams
and making anaxios
call to your server.After that, you can use the
nuxt generate
command to create yourdist
folder and after that serve thedist
folder withNginx
. Everything will work fine.Check this simple routing approach in the browser
In the Users component integrate with your python backend.
You can use SPA mode in NuxtJS (
mode: 'spa',
orssr: false,
in latest versions), then runyarn generate
ornuxt generate
, it will generate a full bundle indist
folder that can be served with any HTTP server.This works fine with all dynamic routes, I tested it with simple
php -S localhost:8000
that’s just serves a folder via HTTP.This works due to a trick with 200.html https://dev.to/adnanbabakan/deploy-a-single-page-application-with-200-html-2p0f
For my project it generated all needed data and folder size is just 13mb (with all images, fonts, etc…).
You can read more about how static routing is done in Nuxt docs: https://router.vuejs.org/guide/essentials/history-mode.html#example-server-configurations