Thinks to self: OK, this “full-stack” project is going to be fairly complex. I need:
- a database. I don’t need it yet, I’ll defer that.
- a thing that runs on the server, listens for HTTP requests from a browser, builds responses, and sends them to the browser.
- a thing that runs on the browser, built out of bits assembled by the server thing, that the user can interact with.
What I actually got was:
- a thing that runs on the server.
- a thing that defines the environment for the server.
- a thing that defines the environment on development machines so that you can run server-development tasks.
- a thing that turns code that can’t run in a browser into code that can run in a browser.
- a thing that turns code that can run in a browser into code that does run in real browsers.
- a headless browser that lets me test browser code.
- BTW, it doesn’t work with that server environment.
- a thing that shows how Linux binaries are loaded, to work out how to fix the environment.
- also BTW, it doesn’t run headless without setting some environment variable
- a thing that is used for cross-platform native desktop apps, that I can configure to work headless.
- a thing that builds the bits assembled by the server thing so that the test thing can see the code being tested.
And somehow, people argue that this is about reducing development costs.
It’s true that the complexity of a single project goes upwards; likewise, MicroServices are pointless for a small environment. But if you’re building a large environment, with lots of interacting parts that can be farmed out to multiple people, you template/architect/whatever-your-language-provides the project structure, and they just go
click-write important code-deploy
into the environment.We’re in the middle of building this environment, with a choice of source languages (Go, C# or Java) for the server bits, integrations to the other bits that talk, cogs here, whirly bits there, databases and keys and structures and… lots of moving parts. It’s not something for Joe-sat-doing-one-task-or-one-website (Which is where I think this world has gone mad – sure, transpiling TypeScript to JavaScript has benefits in you get to be able to use an arguably better language, but it makes the process much harder), but it’s great for big teams and multi-project performance. One project takes twice the time, but a hundred take half the time.
“100 projects is as easy as 50” is Netflix envy. My company is not yet Netflix, and I cannot, nor do I want to, spend “large environment” money on training a whole team to get that first project out and test product/market fit.
I started making web apps with WebObjects. It was a tool for building native applications, which exposed a web server and could bind data (optionally from a database) into HTML documents. Rails is like that, except that it also makes me think about rvm or Docker (if I don’t, then it’s likely that two people can’t both make their gems or bundlers work, or that it won’t work in prod). And it chooses to encourage me to think about coffee script instead of Javascript, when my users’ browsers will only work with Javascript. None of that complexity is necessary. What I would like is testing infrastructure, because one thing that’s changed since WebObjects is that we learned to write more tests. Unfortunately, Rails doesn’t come with tools for testing Javascript, so I have to find my own and make sure they work with the aforementioned complexity.
I pick Rails just because it’s the most WebObjects-like of the web app tools that people still use. Node makes testing better, but not deployment (if anything, deployment is worse, because what you’re allowed to write in a
.js
file changes more frequently than what you can write in a.rb
file).