-
Notifications
You must be signed in to change notification settings - Fork 3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
New major version [complete rewrite] #24
Comments
@chriscalo Would you be up to join me in doing this? We could co-create a new GitHub Org |
Apologies for the slow reply. I started to respond a few time times but wanted to give it some more thought and research. I definitely am still having some struggles in my dev workflow and could be convinced to contribute, though it would need to be a good match for addressing the problems I’m facing. Let me know if any of this sounds interesting. If this doesn’t turn out to be a good match, it’s nevertheless useful for me to get these thoughts down on paper. My wish list: Support modern Vue app development
Development: fast, no-bundle dev serverFile-system based routing for static assets, dynamic pages, and API endpointsThe vision behind Zero Server feels perfect to me, though unfortunately I wasn’t able to get it to build:
Simple SSR
Production: optimized for serverless environmentsWith Nuxt I’m seeing response timeouts in Google App Engine after deployment or after the app is idle for a while. Not certain, but my guess is that when a new instance spins up to handle an incoming request, it runs Would be great to have:
JavaScript API for easy integrationIn addition to a CLI command for starting a server, it’s also nice to have a JavaScript API when more control over the server is needed. Two examples:
Thoughts? Any of this a good match for what you’re hoping to create? |
My overarching motivation is that I want a lean do-one-thing-do-it-well tool, instead of having to use a big rigid monolith à la Next.js or Nuxt. I believe it's possible to implement a lightweight
Core would implement:
Core can be used directly by the user or can be used with an "integrator". The role of the integrator is to stich core with a bundler/builder and a view library. There would be several integrators, for a example a Vue + Snowpack integrator, a Vue + Vite integrator, a React + React Server Components + Webpack integrator, etc. The goal of the flexibility is actually that anyone with a wish list like yours can implement it. Core should not get in the way of your wish list. So, when you ask whether your wish list matches my motivation, my answer is a clear yes since I want anyone, including you, to build whatever they want on top of core.
Neat idea.
I agree, it's important for flexibility. I'm increasingly liking Snowpack. And yes, it would be pretty neat to get rid of the build-step altogether. It's exciting to see Snowpack and Svelte starting using esbuild. It would be exciting to work on a Snowpack integrator together. I'd suggest we take a shot at implementing a first rough prototype of core together where each LOC is reviewed by the other one. What do you think? How about a new name? |
@chriscalo Note that Vite is working on supporting SSR. This means that writing Goldpage/RenderX core + Vue/Vite integrator will be only a couple of kLOCs! This is an exciting opportunity to ship an interface we both deem user-friendly while not having to write much code. It's quite a comfy situation :-). |
Well, that’s quite encouraging
This seems reasonable, though even before that, how would you feel about starting with a few example projects that don’t actually work (yet) but instead attempt to illustrate how projects should work with Goldpage/RenderX? Essentially, this would help us capture the right developer experience before starting, but then those same example projects could later serve as a target to code against and even as automated tests. Thoughts? I’m happy to give this an attempt, but I should be honest about my modest experience: I’ve only worked on fairly simple apps and packages/modules, so I would likely need a good amount of architectural guidance. I want to call out this discussion of “buildless” SSR in the Vite repo:
It seems pretty compelling to be able to just deploy source files and not have to worry about any build configuration. But if you want to you can do a manual build to “prime the cache.” In the end I think buildless is compelling to the community because of a general fatigue of tooling and configuration, but it’s possible things are not quite there yet. At the moment, all that really matters is that things Just Work without fussing with configuration or wiring things together. Maybe it’s too early for buildless, but I’m hopeful web tooling will eventually get there. |
Yep. And, even if we fail to popularize it, we will have built something beautiful we can be proud of :-).
Yes, that's actually my thinking as well, I just forgot to mention it.
With automated tests with good coverage, we'll be able to easily change the internal architecture of Goldpage/RenderX. TypeScript + automated tests make refactoring astonishingly easy. We both care about exposing a minimal interface to the user which means good coverage will be easy to achieve. (We don't have to test all languages PostCSS/SASS/TypeScrip/JSX/SFC/etc. since these are already covered by Vite; we merely need to test our interface.) So basically my answer here is that we can first implement things in a quick way and eventually make internal improvements.
Interesting idea - it would make building completely transparent. Neat.
Yes same here. To me, what's important is that the user has to think only what's strictly necessary when using Goldpage/RenderX. In itself, that the user has to run a One reason why I value the core+integrator desgin: it will allow us to experiment and implement all kinds of neat things in the future while keeping the same DX. We can progressively implement these niceties with minimal breaking change for the user. Let's think about the DX we want, and an exciting future will be ahead of us :). I'll be thinking about it this Weekend. |
Started to think about the interface, but I'm not done. |
Sounds like some interesting developments in Vite SSR (as you mentioned above). https://twitter.com/youyuxi/status/1351225446902464516?s=21 The only thing I’m a little worried about is how long it will take to become stable enough for use in production. Although Vite is at 2.x, things don’t Just Work yet. |
It seems more and more clear that SSR with good DX without framework is only a matter of time. What I forsee is that Vite will be a low-level SSR solution. Goldpage/RenderX would be a higher-level solution (without being a framework). But if Vite covers most DX/features we want, then it could replace what we are doing here. I'll think more about the interface later today. If Vite ends up replacing Goldpage/RenderX then we would have contributed to Vite's SSR interface :). (We should open a ticket about our intentions on the Vite repo at some point.) Thanks for the tweet pointer, it's great to see Evan caring and pushing the envelope. |
The InterfaceBasic usage:
That's all the user would have to do: the basic usage has zero config. But config is possible for advanced "full control" usage.
Furthermore, we can use the render function idea to enable the user full control over app integration. This will enable all kinds of advanced use cases. // Full control over server integration
const { renderx } = require("goldpage");
const express = require("express");
const app = express();
app.render("/", async (req, res) => {
const renderedHtml = await renderx("landing.page.vue");
res.send(`<html><body>${renderedHtml}</div></html>`);
}); // Full control over SSG
const { renderx, saveToHtmlFile } = require("goldpage");
const Todo = require("./path/to/orm-model/Todo");
generateStaticPages();
async function generateStaticPages() {
const items = await Todo.getAll();
await Promise.all(
items.map(async ({ id, text, isCompleted }) => {
const renderedHtml = await renderx('todo/item.page.vue', { initialProps: { text, isCompleted } });
await saveToHtmlFile(`<html><body>renderedHtml</body></html>', { route: `/item/${id}` });
})
)
} This level of control is unseen before. This would be a wonderful do-one-thing-do-it-well tool for companies that need/want control over their app. (I've seen many companies relunctant to use frameworks such as Nuxt/Next.js.) Thanks to Vite, we can keep the whole source code small. Basic usage is and should be zero config. |
@chriscalo Let me know if there is anything you don't like about the interface. I'd be curious to know what you think about it. Vite SSR has landed vitejs/vite#1290 (comment). I'll start playing with a rough implementation. |
I hadn't seen, that's a big deal. 👍 super curious to hear what it's like coding against the Vite SSR implementation. I'll send a more detailed response this weekend, but an initial reaction is:
regarding the proposed interface: the way my brain works, I feel like I need to think through things in this order, so it's a little difficult to talk through the interface before going through the use cases, though they're admittedly similar:
Where's the best place to start capturing these use cases? Should I create a one-off repo to gather my thoughts? |
Also wanted to point out webpack's new lazyCompilation experiment: another step towards going fully buildless in development. |
Super curious as well 👍. I'll have a deeper look at it this Weekend.
👍 I also like it when things are close to "bare metal".
Interesting idea. Although I'm thinking it can be tricky to share common HTML between pages. For example, pages usually have the same footer and header; how would you then share this same header and footer between all pages?
Makes sense. One thing we could as well do is to ask ourselves what use cases would the interface not cover? It may be an efficient way to get intimate with the interface and develop use cases. Similar to writing tests that aim to bring code to fail. I find myself learning a lot when I write tests. Instead of tests, it would be uses case that try to fail the interface.
I guess we can write everything in this ticket for now.
Neat. They only need a zero-config thing, then Webpack is back in the game :). |
@chriscalo I published a beta. I'd be curious to know what you think! :-) |
Fast progress! I've been hoping to try this but haven't found some free time just yet. I have a few ideas that might simplify the developer experience, but will collect my thoughts and share. Also check out recent developments in Nuxt 3: https://nuxtjs.slides.com/atinux/nuxt-3-in-action |
Curious to ear about them!
Feel free to share them raw and unpolished :)
Thanks for these pointers, I was actually looking for these slides. |
A few raw thoughts here, but a big caveat is that I haven't tried things out yet: The For example, here's the
Of course, I put shared components in the I expect some people to not love that naming convention, so I wonder if it would be good to offer an option to specify the glob pattern for pages (but also YAGNI). I'd personally prefer not to use
And you aren't required to write your own In a Nuxt project I ended up embracing the pattern of creating an API and fetching data from within Vue page (and sub-page) components in both Node (via SSR) and the browser. It uses Vue Apollo, and I have no idea how it works, but love that it seems to just work. <script>
import { Goals } from "./goals.graphql";
export default {
apollo: {
goals: {
query: Goals,
prefetch: true,
},
},
};
</script>
<template>
<table>
<thead>
<tr>
<td>Description</td>
<td>Target Date</td>
</tr>
</thead>
<tbody>
<tr v-for="(goal, i) in goals">
<td>{{ goal.description }}</td>
<td>{{ goal.targetdate }}</td>
</tr>
</tbody>
</table>
</template> It does require the following const { HOST, PORT } = process.env;
export default {
modules: [
"@nuxtjs/apollo",
],
apollo: {
clientConfigs: {
default: {
httpEndpoint: `http://${HOST}:${PORT}/graphql`,
browserHttpEndpoint: `/graphql`,
},
},
},
}; I want to try some similar things with Vite SSR and see if I'm able to get a similar setup working without too much fuss. In particular, I wonder if the Thinking aloud, I feel like the fundamental issue is being able to create a "soft" dependency from a I kinda wish a very similar pattern like
import query from "~/util/db.js";
export default async (req, res) => {
res.json(await query(`select * from Foo`));
} Then, in a <script>
import http from "~/util/http"; // (axios instance)
export default {
async data() {
return {
// In the browser, the use of a relative path below just works.
// I wonder what it would take to make the same work on the server.
foo: await http.get("./foo"),
};
},
};
</script>
<template>
…
</template> Here's a somewhat related tweet on making file-based API endpoints, though I don't love the I'm also wondering if there's an easy way to set <template>
<Head>
<title>Hello Vue</title>
<meta name="description" content="Do you like it?" />
</Head>
</template>
<script>
import { Head } from '@egoist/vue-head'
export default {
components: {
Head,
},
}
</script> Another big question: Vite seems really intent on providing only a dev server and not a production server, so I'm curious how you run this in production? I'd really love to not have to write my own server, to be honest. This is the PHP file-system-routing experience: I want to author page and API files, not write serving logic. |
Hi Chris, I like your thoughts, as usual 😊.
I share the sentiment but I also greatly care about minimal configuration and simplicty. Although the user has slightly more effort and has to type these
They'll eventually come to realize that "this is the way".
I did think about supporting Route srings are more powerful and such path trickery ultimately leads to a loss of dev time when the user ends up thinking "I wonder if I can cram that route string as a FS path?", "Will my FS fail with these non-ASCII characters?", "Will my deploy environemnt fail with that FS path?". Even if know the answers to these question, the user will likely not. All these questions vanish by forcing the user to use proper route strings defined in Clarity is more important than having a few extra files.
You actually are required to... and you have to write However, I am thinking of writing a framework that is basically a tiny ejectable wrapper on top of
Neat, that is indeed convenient. I'll have a look at it.
With
Yes exactly:
Check out https://github.com/brillout/wildcard-api (Which I'm btw going to rename it to Telefunc, "Wildcard API" is a misnomer.) Using
Yes, check out https://github.com/brillout/vite-plugin-ssr#html-head
You integrate
I share the sentiment but that's not
Now imagine this with Telefunc. The long term goal of Telefunc is to completely replace Express.js: define your server as functions, that's it. (I'm currently working on file uploads and I've already a design for real-time, which would make Telefunc pretty much feature-complete.) |
There are neat ideas out there waiting to be implemented such as:
ParcelVite is used.The text was updated successfully, but these errors were encountered: