Closed connordoman closed 1 year ago
Thanks for explaining so detailed!! This sounds good and makes sense to me. However, there are only 3 issues I am concerned about:
In the view of devOps and maintenance, not a big fan. But as this project won't be too big, I don't mind going with this direction.
Awesome, I think the simplicity of this platform is a great fit for the size of our project.
Just to put some of your worries at ease:
There has been some discussion about what framework should be used for our front end environment.
Some concerns that need to be addressed in regards to this include:
Multiple people on our team are eager for a chance to try front end development with React. There are many modern frameworks that use React or similar component-based systems (Angular, Vue, Astro) for building web applications.
Historically, React has been deployed client side as a JavaScript bundle that intelligently composes elements and manages their states. This has the benefits of being mostly backwards compatible and requiring little to no back end setup. Downsides to this approach are reliance on older React code patterns, interpreter setup, and outdated bootstrapping tools. Additionally, sending React to the client and rendering the DOM at page load increases load times and slows user experience.
The popularity of Webpack along with TypeScript and JSX have done much to solve these problems. Webpack transpiles, bundles, and minifies all JavaScript code into chunks, decreasing page load times, old code patterns, and tooling setup. However, Webpack itself is getting older and its setup process also has challenges.
This is where server-side frameworks like PHP, Django, Next.js, and more recently Astro, have stood out.
While PHP and Django are more skeletal they allow writing code that allows data security as well as server control. This gives flexibility to the progammer and dynamism to pages and user data.
Taking into account server-side control and data access combined with the use of the web's most popular tools—React, TypeScript, and Node—Next.js solves all of these problems at once.
Next.js
When looking at our projects requirements along with our personal desires in terms of learning outcomes and using new technologies, Next.js fulfills these needs fully:
tsc
setup1.
and2.
rely on Webpack's configurationnpm
packages, key for staying open source while speeding up developementimport
syntax, even server-side/api/
That being said, anything pre-configured by Next.js is also able to overridden and modified as necessary.
Concerns
To reiterate main concerns:
Containerization
Our project requires us to coordinate multiple services running simultaneously on AWS. This naturally draws us to Kubernetes as it is highly scalable, well integrated with AWS, and an industry-standard.
With this, it is a must that all of our services are containerizable so that they may be properly deployed.
Since Next.js is a Node server, containerizing is well documented but does require some additional work from us. Essentially, we take the extra step of defining a new
expressjs
server that uses Next.js as it's primary app. This makes our deployment more Node-agnostic. Here is an example Dockerfile:This Dockerfile, along with an overview of the rest of the containerization process, can be found here. This article is part of a series that later includes Ansible and Kubernetes integration, though simply having a container is the minimum we need to begin our own integration.
Docker containers aren't exactly the same as Kubernetes standard containers but for our purposes the "cost" of not having a "perfect" k8s deployment is made up for by how much easier front end development will be. Docker containers are also well supported and allow for some atomicity in development.
Server Load
Since Next.js is a server-side rendering framework this naturally leads to concerns about the server having to do too much work. Obviously, this could undo any benefit to load times and would increase cost as compute time increases.
Next.js uses a build-deploy pipeline where pages are precompiled as much as possible before deployment and then static HTML is served to the user. These builds are also cached so rebuilds take less time. Most pages, even those with outgoing API calls, render statically since data fetched by API calls can simply be populated at request time.
Pages that must render at request time are those:
The newest version of Next.js (13) also includes server-side components, where a component that does not rely on external data at runtime can be prerendered and used on many pages.
Another consideration is that our app, a medical/professional service that is largely appointment based with little random access, may see little to no concurrent users within a single deployment, so the server will not be burdened with constant rerenders.
Learning Outcomes
The matter of React as a desired learning outcome is settled. In my opinion, there is no better way for a beginner to start with React than to deploy a Next.js app since JSX syntax with TypeScript is immediately available and from an empty folder to a running development server is just 2 terminal commands (npm).
This also gives us a chance to work with JavaScript/TypeScript, the industry-standard languages for front end web development and a necessary experience in 2023. Since the server is Node, this also means the entire front end app will be written in TypeScript.
Conclusion
The speed with which we can develop the front end along with use of popular web tools and the chance to learn widely-used frameworks with modern JavaScript tooling and little to no extraneous server-side compute cost makes up for any eccentricities in the deployment pipeline.
Additional Notes
I have historically used
yarn
as the package manager for JavaScript projects as I prefer its syntax butnpm
is catching up and looks like it might have some useful CI tools: https://stackoverflow.com/questions/40027819/when-to-use-yarn-over-npm-what-are-the-differences. I am open to whatever the team decides, plusnpm
is more widely supported and should work out of the box within containers.