vikejs / vike

🔨 Flexible, lean, community-driven, dependable, fast Vite-based frontend framework.
https://vike.dev
MIT License
4.3k stars 348 forks source link

V1 Design #578

Closed brillout closed 10 months ago

brillout commented 1 year ago

The vite-plugin-ssr@1.0.0 design in a nutshell:

// /pages/product/+config.ts

import type { Config } from 'vite-plugin-ssr'

export default {
  Page: './Page.vue',
  route: '/product/@id',
  onBeforeRender: './onBeforeRender.ts',
  onPrerender: './onPrerender.ts',
  prerender: true,
  ssr: false // render as SPA
} satisfies Config // `satisfies` is a new TypeScript 4.9 operator

I.e. +config.js replaces .page.js, .page.server.js, .page.client.js, and .page.route.js.

It also replaces _default.page.js as well as VPS configurations set in vite.config.js:

// /pages/+config.ts

import type { Config } from 'vite-plugin-ssr'

// Applies as default to all pages
export default {
  onRenderHtml: './config/onRenderHtml.tsx',
  onRenderClient: './config/onRenderClient.tsx',
  prerender: {
    partial: true // Currently lives in vite.config.js
  },
  ssr: true
} satisfies Config

VPS's architecture stays the same and therefore migration is relatively simple.

Succint syntax

Under consideration is the possibility to create new pages in a succint manner:

/pages/index/+Page.js
/pages/about/+Page.js
/pages/jobs/+Page.js

Here, a new +config.js file isn't needed each time a new page is created.

I'm currently leaning towards not supporting such succint syntax (in favor of "Single Config File", see next section). But I may reconsider if users want this.

Single Config File (aka Single Route File)

// /pages/+config.ts

import type { Config } from 'vite-plugin-ssr'

const marketingPagesConfig = {
  Layout: './layouts/LayoutMarketingPages.vue',
  ssr: true,
}
const adminPagesConfig = {
  title: 'Admin Panel',
  Layout: './layouts/LayoutAdminPages.vue',
  ssr: false
}

export default {
  // If `singleConfigFile: true` then only one `+` file is allowed (this file). If there is
  // anothoer `+` file, then VPS displays a warning.
  singleConfigFile: true,
  pages: [
    { ...marketingPagesConfig, Page: './LandingPage.vue', route: '/'        , title: 'Awesome Startup'                          },
    { ...marketingPagesConfig, Page:    './JobsPage.vue', route: '/jobs'    , title: "We're hiring!"                            },
    { ...marketingPagesConfig, Page:  './VisionPage.vue', route: '/vision'  , title: 'Our mission <3'                           },
    {     ...adminPagesConfig, Page:   './AdminPage.vue', route: '/admin'   , onBeforeRender:   './AdminPage-onBeforeRender.ts' },
    {     ...adminPagesConfig, Page: './AdminDbPage.vue', route: '/admin/db', onBeforeRender: './AdminDbPage-onBeforeRender.ts' }
  ]
} satisfies Config

The singleConfigFile enforces the entire app to be defined in that single +config.js file. This means that this single +config.js file represents the entire interface between VPS and your app.

Nested Views

(Aka "Nested Layouts", but "Nested Views" is a better name for this design.)

// /pages/product/+config.js

export default {
  Page: './Page.js',
  onBeforeRender: './onBeforeRender.js',
  route: '/product/@id',
  nested: [
    {
      route: '/product/@id/details',
      View: './DetailsView.js'
    },
    {
      route: '/product/@id/reviews',
      View: './ReviewsView.js',
      onBeforeRender: './onBeforeRenderReviewsView.js'
    }
  ]
}

This example doesn't use singleConfigFile (otherwise nested would be defined in /pages/+config.js instead).

Custom Exports

The V1 design requires Custom Exports to be registered.

// /pages/+config.ts

import type { Config } from 'vite-plugin-ssr'

export default {
  configDefinitions: [
    {
      name: 'title',
      env: 'SERVER_ONLY' // | 'CLIENT_ONLY' | 'CLIENT_AND_SERVER'
    }
  ]
} satisfies Config
// /pages/index/+title.ts

// The file is loaded only in Node.js. (At server run-time or at build-time while pre-rendering.)
export const title = 'Welcome to the V1 design'

More

The V1 design unlocks many more capabilities, in particular around building frameworks on top of VPS. See end of this comment.

This is a very exciting design. (In many subtle ways, you'll see when you'll use a VPS framework.)

Feedback

(Negative) feedback welcome.

Acknowledgement

🙏 @AaronBeaudoin for the fruitful conversation.

phiberber commented 1 year ago

Just to mention. I've lost all my interest in SvelteKit due to these +s. I think they make the project structure feel cluttered, the same as other symbols as $ or _.

I do prefer the .page.x design, but I would rather use something like the new Next13 project structure with page.vue, layout.vue, loading.vue, etc.

I think that replacing .onBeforeRender.ts with .render.ts and exporting a function onBeforeRender would be less confusing, even though these unused exports are not something I like, it's better in my opinion than big file names that also make it feel cluttered.

brillout commented 1 year ago

I can't speak for SvelteKit, but for VPS it seems pretty clear to me that the following is much clearer with than without +.

/pages/UcoHome/+Page.vue
/pages/UcoHome/+route.ts
/pages/UcoHome/+onBeforeRender.ts
/pages/UcoHome/someOtherNonVPSFile.ts

At the end of the day, it's only aesthetics. I'd rather go for ugly but clear, than "pretty" but confusing. (Personally, I actually now find + much prettier.)

I'm happy to be shown wrong with a concrete example why + is a problem.

As for your last point, you'll actually be able to only use +config.ts files:

// /pages/product/@id/+config.ts

import type { Config } from 'vite-plugin-ssr'

// No `+` needed here
import Page from './Page'
// (FYI, in case you're curious about the technicalities, VPS code-splits these imports,
// e.g. `onBeforeRender` is only loaded and executed on the server-side, while `Page`
// is loaded and executed on both the client- and server-side.)
import onBeforeRender from './onBeforeRender'

export default {
  Page,
  onBeforeRender
} satisfies Config

The capability of directly importing hooks in +config.js isn't implemented yet but it's on the roadmap.

samuelstroschein commented 1 year ago

// No + needed here import Page from './Page' // (FYI, in case you're curious about the technicalities, VPS code-splits these imports, // e.g. onBeforeRender is only loaded and executed on the server-side, while Page // is loaded and executed on both the client- and server-side.) import onBeforeRender from './onBeforeRender'

Dangerous. What if I import beforeRender from './beforeRender.ts?

brillout commented 1 year ago

What if I import beforeRender from './beforeRender.ts?

So, yea, you'll be able to name your files and imports as you wish. So no more convention here. On the flip side, you'll have a complete overview simply by opening all +config.js files $ git ls-files | grep +config | xargs vim.

Dangerous

VPS throws an error if you try to import Page and onBeforeRender from the same file (because VPS needs to be able to code-split per environment). In general, hooks can live in the same file only if they live in the same environment. It's well defined in what environments hooks are loaded, and VPS will throw a useful error accordingly.

phiberber commented 1 year ago

I disagree with the point that it's clear. For me like I've said before, it's cluttered and personally visually unappealing. For me it's ugly and confusing. If I were planning to use VPS as a framework by itself, it would be a deal breaker for me, I'm planning though on using it as a way to create my own framework, which then makes this design acceptable as I don't plan on using it at all in my projects.

brillout commented 1 year ago

That's your perspective which, as you describe it, seems quite subjective. As said, I'm happy to be contradicted but please with a rationale.

I'm happy to be shown wrong with a concrete example why + is a problem.

As I said many times here already, I also found + ugly at first. I can see that even you will eventually find it pretty.

brillout commented 1 year ago

The V1 design is now official released in 0.4.119.

Migration: https://vite-plugin-ssr.com/migration/v1-design.

It's beta but I don't foresee breaking changes and some users have are already been using it.

Reach out if you have questions or run into any issue.

seniorquico commented 1 year ago

@brillout I scaffolded a new app using the latest (0.4.123) and began to work through a lot of the initial setup. I discovered this thread and "migrated" to the v1 design. All good, with one exception: Our app is quite large, and I setup the file structure based on the "domain-driven file structure" example. I ran into trouble trying to port the _default.page.route.ts file. No matter what I tried, I just kept getting 404's. See the comment I added below in the bit from this example:

# Marketing pages
/marketing/pages/index/index.page.js # Landing page (URL: `/`)
/marketing/pages/about/index.page.js # About page (URL: `/about`)
/marketing/pages/jobs/index.page.js # Jobs page (URL: `/jobs`)
/marketing/_default.page.route.js # Route to `/*` instead of `/marketing/*` (see below)
# >> How do I correctly port ^^^ this route configuration to the v1 design? <<

# All code related to products
/products/pages/index/index.page.js
/products/pages/product/index.page.js
/products/pages/product/index.page.route.js
/products/db/fetchProduct.js
/products/db/fetchProductList.js

I tried to make a +config.ts file in the /marketing directory, among many other naive, wild guesses, but it couldn't seem to get it to work as I expected. Did I miss something obvious? Any guidance would be hugely appreciated. Also happy to contribute back a small comment to the v1 design migration doc if that's helpful.

brillout commented 1 year ago

@seniorquico That's actually the only feature that isn't implemented yet in the V1 design beta. I've been doing a bit of refactoring of the V1 design implementation the last couple of days to be able to implement this feature (and address a couple of issues). It's mostly finished although a lot of polishing is left to do. ETA this week. I'll keep you updated in this thread. In the meantime, if it's ok for you, continue using the 0.4 design.

brillout commented 1 year ago

@seniorquico Done & released in 0.4.126. Domain-driven file structure (using filesystemRoutingRoot) migration example added at the end of https://vite-plugin-ssr.com/migration/v1-design#examples.

brillout commented 1 year ago

I recommend upgrading to 0.4.132. Lot's of polishing around the V1 design has been done.

louwers commented 1 year ago

My 2 cents to the above discussion: unique filenames are very handy for finding the right file quickly. So I tend to avoid making lots of files with the same name.

brillout commented 1 year ago

unique filenames are very handy for finding the right file quickly

What IDE are you using?

Personally I use https://github.com/junegunn/fzf (with Neovim) and it searches against the whole path (relative to the project root). Which means that, whether filenames are disambiguated doesn't make a difference. I'm assuming all IDEs would also match the search query against the full path and not only against the filename.

If you mean finding the right file among all open files and you use VSCode, then I'd suggest to configure VSCode to show the whole path instead of only the filename.

louwers commented 1 year ago

VSCode aggressively matches filenames before directories. So if you have a directory profile/+Page.vue and a file program.js somewhere it will put profile.js on top when you search for pro. If the file is falled program-file.js it will even match it first when you search for prof.

brillout commented 1 year ago

I guess a workaround is to search for pro+P then. I'm not a VSCode user so I can't say for sure, but it seems like a good workaround.

marviobezerra commented 1 year ago

The v1 specs are really nice, good job!

My only question, so far, is about the + sign. What is the purpose of this sign? What problem is it solving that a page.{jsx|tsx} wouldn’t solve?

NextJs is getting some negative feedback (including mine) on the amount of signs in files and folders - omg so many. In my opinion, simple is better, so no sign and file case insensitive or lower case.

brillout commented 1 year ago

@marviobezerra @DanAndreasson I do understand it's slightly off putting at first. But I believe you'll eventually end up liking it as it's a succinct way to clarify that the file is a vite-plugin-ssr entry.

What problem is it solving that a page.{jsx|tsx} wouldn’t solve?

It doesn't solve a problem per se and an alternative such as /pages/some-page/index.onBeforeRender.js would work equally well. I explain the reason why I prefer + here.

NextJs is getting some negative feedback (including mine) on the amount of signs in files and folders - omg so many. In my opinion, simple is better, so no sign and file case insensitive or lower case.

I agree with the sentiment and I also find Next.js's Filesytem Routing convention messy, and I'm confident vite-plugin-ssr won't turn into such a mess (a central reason being that vite-plugin-ssr allows you to define advanced routes programmatically, which means that vite-plugin-ssr can keep its Fillesystem Routing convention simple).


To be clear: I'm not against revisting the + decision, but I'll ask you to make your case with rational arguments and not merely emotional ones. As said before multiple times, I do empathize that the + sign is off putting at first, and I also didn't like it at first. But I did end up liking it a lot, and I'm actually looking forward to deprecate the current convention in favor of the new + covention.

marviobezerra commented 1 year ago

I took a few days to answer because I was thinking about it (and also having some beers). There are many ways to approach a discussion like this one, and I agree with you that been rational is the best option. That been said, let get into it!

First, I'd chose convention over configuration 10 out of 10 times, specially for routing. Having a well defined file structure makes so much easier to navigate the code - specially for routes. In my opinion, the + sign, in this case, is just "noise" and I'd avoid as much as I can. More over, all my files are lower case, I do that so I can keep a smooth file system. When you have Pascal-case, Lower-case, Snake-Case, and Pick-Your-Poision-Case in the same application is like driving on a bumpy road.

Second, this kind of decision is tough because wherever you decide we need to cary on. I can imagine a developer creating a file page.tsx and not getting page rendered. After debugging and Googling for a few minutes (or more) they realize the it's missing the + and it should be +page.tsx. However, they still not getting the route to work. After more debugging and Googling they realize that it needs to be +Page.tsx (capital P). It may happens once or twice and the developer will learn its lesson (at least I hope so) but the first impression is already set.

Also, when you jump between projects using different frameworks you need to shift your brain to. For example, we have applications using NextJs, Expo, and React-Scripts (ugh). The + is one more wire to connect when changing projects and, imo, it's not needed.

In summary, the + sign adds one small not necessary step that won't hurt and also won't help. As you said "It doesn't solve a problem per se" so it's a matter of liking or not. In the end it's your framework and it's your decision - be wise.

brillout commented 1 year ago

the + sign adds one small not necessary step that won't hurt and also won't help

The + sign does have a function: it's about distinguishing normal JavaScript files from vite-plugin-ssr entries.

If we remove the + sign then:

# A vite-plugin-ssr entry
/pages/index/Page.js
# Another vite-plugin-ssr entry
/pages/index/onBeforeRender.js
# Confusing: is that a vite-plugin-ssr entry?
/pages/index/somethingElse.js

We need to have some kind of way to distinguish. So the question boils down to whether we should go for /pages/product/+onBeforeRender.js or something else, for example /pages/product/index.onBeforeRender.js.

Also, when you jump between projects using different frameworks you need to shift your brain to. For example, we have applications using NextJs, Expo, and React-Scripts (ugh). The + is one more wire to connect when changing projects and, imo, it's not needed.

I don't see /pages/product/index.onBeforeRender.js to be better than /pages/product/+onBeforeRender.js in that regard.

I can imagine a developer creating a file page.tsx and not getting page rendered. After debugging and Googling for a few minutes (or more) they realize [...] it should be +Page.tsx

You're right and I care about this. Actually the error message is quite nice already:

c1

But I went ahead and made it better:

c2

they realize the it's missing the +

Because /pages/product/+onBeforeRender.js is much more "in your face" than /pages/product/index.onBeforeRender.js, I'd actually argue that the user is much less likely to forget the + sign than forgetting the index. prefix.

When you have Pascal-case, Lower-case, Snake-Case, and Pick-Your-Poision-Case in the same application is like driving on a bumpy road.

I actually appreciate that SvelteKit is going for snake_case over camelCase (I prefer snake_case a lot more) but, unfortunately, I think they're fighting a lost cause: the JavaScript ecosystem as a whole will most likely stick to camelCase.

I don't think there is an alternative here other than taking the bullet.

More over, all my files are lower case, I do that so I can keep a smooth file system.

I'd actually recommend you to forgo that practice of yours because the JavaScript is pretty much ubiquitously camelCase.

the first impression

I agree the first impression isn't perfect here. But, even with considering the first impression, I still prefer this:

/pages/product/+Page.vue
/pages/product/+route.ts
/pages/product/+onBeforeRender.ts

Over this:

/pages/product/index.Page.vue
/pages/product/index.route.ts
/pages/product/index.onBeforeRender.ts

I find the increased compactness appealing.

It find it so appealing that I think it's worth the inital impression of weirdness. (And after using it a while, users won't find it weird anymore.)

I'm open to alternatives to /pages/product/+onBeforeRender.js and /pages/product/index.onBeforeRender.js. I can't think of any but maybe someone can come up with one.

I took a few days to answer because I was thinking about it (and also having some beers). There are many ways to approach a discussion like this one, and I agree with you that been rational is the best option. That been said, let get into it!

Thanks. I appreciate it.

marviobezerra commented 1 year ago

I see that you already made your mind. It'd amazing to have a simple solution, but, again, your framework and it's your decision.

/pages/product/{P|p}age.vue
/pages/product/{R|r}oute.ts
/pages/product/on{B|b}efore{R|r}ender.ts

Thanks for taking the time to answer.

brillout commented 1 year ago
/pages/product/{P|p}age.vue
/pages/product/{R|r}oute.ts
/pages/product/on{B|b}efore{R|r}ender.ts

FYI Next.js had a lot of negative feedback because of the distinguishing issue of such design.

phiberber commented 1 year ago

Am I right to say that there's more negative feedback than positive on this topic?

I know you think people are going to get used to it (I didn't yet), but I'd like to know the ratio of people enough to convince you emotionally.

It's a "Noise" vs "Useful Noise" battle which already looks in my opinion pretty personal and emotional.

A battle which I have no motivation to participate anymore.

marviobezerra commented 1 year ago

I’m also done.

brillout commented 1 year ago

convince you emotionally

That's precisely my point: I want to be convinced on a rational basis, not on a merely emotional one.

As an open source maintainer it's paramount to be able to proceed despite negativity (while thoroughly listening and considering it which I hope/think I'm doing). Otherwise the project stifles and there is no progress anymore.

Am I right to say that there's more negative feedback than positive on this topic?

I wouldn't be sure about it: it could very well be a small minority that is a lot more vocal than a vast agreeing majority. But that besides the point.

As always: I'm more than open to rational critical feedback. In particular around IDEs, as it seems like there'll be some paper cuts with the V1 design.

I'm also open to suggestions. For example, something that hasn't been brought up is the possibility to define everything in a single file (not only configs but also .telefunc.js files). Some folks care a lot about this and I wonder: could a Vite plugin be created that implements this in a generic way? It could be used not only for Vike but also for other tools that also don't do code extraction.

Another suggestion that hasn't been brought up is the fact that https://github.com/brillout/vite-plugin-ssr/issues/341 together with a vike.config.js (same functionallity as /pages/+config.h.js) would actually mean that you'll end up with zero + sign in your filesystem.

redbar0n commented 1 year ago

Just throwing this suggestion out there:

/pages/product/product.ts
/pages/product/product.vike.ts

Where the product.ts file by convention would contain the index and solve the aforementioned problem of multiple index.ts files.

Where the Vike (upcoming new name for VPS) file product.vike.ts would contain all of:

You probably need to look at the code of all of those at the same time to get an overview anyway.

What I like about it is that it is less small files and tabs to keep track of (less clutter all around). More intuitive and self-documenting (no need to document capitalized filename or + sign), does not force IDE config on users, and imho quite aesthetical (Rails inspired convention over configuration).

Wouldn’t this be clean?

Thumbs up if so, and heart it if you love it. :)

samuelstroschein commented 1 year ago

The .vike. filename clearly communicates that "this is a vike related file" much better than implicit "+config files mean it's related to vike" 👍

marviobezerra commented 1 year ago

That's precisely my point: I want to be convinced on a rational basis, not on a merely emotional one.

What is your motivation other the emotional? I agree that it needs reserved file names, so +Page, page, or page.vike won’t matter. Only your preference (aka emotional).

I wouldn't be sure about it: it could very well be a small minority that is a lot more vocal than a vast agreeing majority.

Maybe a survey can provide actual data to support a decision. Formulate a valid question here and ask for thumbs up, thumbs down, etc. Would you accept the result?

flodlc commented 1 year ago

After many days testing the v1 design, I actually like the "+" syntax a lot 👍

Previous design leads to lot of export in the page file and it became hard to see which one is present.

brillout commented 1 year ago

@redbar0n The V1 design requires each config to be defined by its own file (or in the +config.js file when the value is primitive/serializable). It's at the core of the V1 design and enables foundational features such as a config ssr: boolean. An ssr flag needs to change in which environment +Page.js/Page.vike.js is loaded.

That said, a .vike.js suffix would indeed be an alternative. And I like it.

That said, + is more succint and has the advantage of improved FS order as pointed by @flodlc. So, personally, I'm still in favor of the + sign.

I appreciate your feedback which is much more constructive than just saying "I categorically don't like it and I don't want to explain why".

Only your preference (aka emotional).

It isn't. It's rational. For example, the + sign is the most succint of all suggestions.

Maybe a survey [...] Would you accept the result?

I would consider the result but I wouldn't make it the sole reason for deciding. Also, I wouldn't do the survey now as it'd be premature and shortsighted: let's first see how many get used to the + sign after a couple of months. Remember, my argument is that most will get used to the weirdness. (Maybe it will become a widespread convention even outside of SvelteKit and Vike...). It's my job to see far in the future.

That said, I can make a survey out of curiosity.

phiberber commented 1 year ago

I've mentioned before that the reason I don't like the + sign is how cluttered it look, mentioned also an alternative that would be using a colon which in my opinion looks really simple and it's one of the things I did when I started my own framework.

It isn't. It's rational. For example, the + sign is the most succinct of all suggestions.

I've suggested two options, the colon instead of the plus sign and the way Next does it (Although I don't like that much how colocation works in Next).

That said, a .vike.js suffix would indeed be an alternative. And I like it.

I actually prefer the plus sign over a suffix, I'm looking for the less cluttered way to identify pages and a suffix is just too much to me.

I would consider the result but I wouldn't make it the sole reason for deciding. Also, I wouldn't do the survey now as it'd be premature and shortsighted

I agree with you on that one and change my opinion on this topic, I still hate the plus sign but maybe you're right in your motivation to wait, but it's quite strange to implement something that you're thinking in possibly removing in the future.

If I've interpreted right, all the things @flodlc mentioned would be possible with a colon instead of a plus, I don't think there's a rationale to that, it's just less cluttered to my eyes and I agree it's extremely personal, emotional and subjective, you should do that too @brillout.

redbar0n commented 1 year ago

@phiberber

On Windows systems, files and directory names cannot be created with a colon (:). But if a file or directory name is created with a colon on a Linux or Mac operating system, then moved to a Windows system, percent encoding is used to include the colon in the name in the index.

https://www.ibm.com/docs/en/spectrum-archive-sde/2.4.1.0?topic=tips-file-name-characters#:~:text=On%20Windows%20systems%2C%20files%20and,the%20name%20in%20the%20index.

phiberber commented 1 year ago

Makes sense, I'm not a Windows user, Maybe - then, something cleaner than +.

brillout commented 1 year ago

@phiberber Seems like you're slowly appreciating the whole + thing after all :-).

Beyond redbar0n's point the issue with : is that it already denotes parameterized route segments in many other ecosystems.

Maybe - then, something cleaner than +

I like the fact that + can be interepreted as "adding something" which kinda makes sense. The - sign is weird from that perspective.

phiberber commented 1 year ago

I still hate it and it has been one of the three reasons I avoided VPS. But I'm seeing there's not that many options of symbols other than +, suffixes are bad, prefixes are good but they should not feel cluttered, which is my main problem with the + sign.

Seeing a large project tree with + signs is the same to me as looking to every ad at the Times Square, too much information to process.

Colocation feels badly designed to me still, it could maybe get better with proper IDE support.

+Page.ts $Page.ts @Page.ts

Page.ts <Page.ts _Page.ts -Page.ts .Page.ts ~Page.ts

To me - means more like an item of a list than subtraction or something negative, it's really clean and easier to read.

brillout commented 1 year ago

That's actually something I'd be up for making a poll about and going with the result. But still premature.

Out of all options, I clearly prefer +. So I'd suggest we go for + and revisit the sign after a while. I'm hopeful you'll get used to it.

samuelstroschein commented 1 year ago

What about vike.page.tsx, vike.config.ts to achieve grouping of vike related files and more explicitness than "+ means it's related to vike"?

brillout commented 1 year ago

The + sign quickly ends up being as explicit as a vike. prefix. A vike. prefix is more explicit only for newcomers, and I don't think it justifies giving away the succinctness of the + sign.

I'd suggest we pause and resume the discussion after a couple of months after the old design is deprecated.

That said, I'm more than looking forward to hear about concrete issues, such as paper cuts around IDE. (I actually have an idea about it but I purposely don't write about it because, so far, I don't think it's enough of a priority for us to spend time on. Important to prioritize things correctly, otherwise Vike will never hit prime time.)

To sum up:

Looking forward to ship the V1 (design).

redbar0n commented 1 year ago

@phiberber

I do also like - more than + purely aesthetically. But I think + may be better here.

To me - means more like an item of a list than subtraction or something negative, it's really clean and easier to read.

I agree, I never thought about it as subtraction and addition, in terms of file names. - is well established in file names, and should be intuitive to most.

But, related, an issue I have with YAML is that it’s confusing to quickly glance at something and tell whether it is a list or not. Because of - being present or not (esp. when nested).

That’s could actually be an issue here too, since it would look like some folder items in the IDE indicate they are part of a list, so the (inexperienced) user may be inclined to make all files in the folder be prefixed with - to be uniform. Or vice versa. Both may conflict with this library’s operation.

In all, I’m starting to come around to the + sign. Let’s just try it and see.

Hebilicious commented 1 year ago

Everything looks exciting !

I have one minor suggestion :

export default {
  configDefinitions: [
      {  name: 'island', handler(value) {}},
      {  name: 'foo', handler(value) {}},
  ]
} satisfies Config

I would love to see a change to :

export default defineVikeConfig({
  extendConfig: {
    island: { handler: (value) => {} }, //object syntax
    foo : (value) => { } // function syntax
  }
 })

The reasons why :

brillout commented 1 year ago

@Hebilicious It's actually already renamed, see https://vike.dev/meta. I find "meta" better than "extendConfig", given the fact that meta is also about modifying existing configurations.

As for the config helper, it didn't occur to me that it would help JS users. Neat & good to know. PR welcome if that's something you'd be up to.

I also like the idea of an object syntax. Maybe something like that:

// /pages/some-page/+config.h.js

import dataHook from './data.js'

export default defineConfig({
  // object syntax
  dataMeta: {
    value: dataHook,
    // By default `env` is 'server-only'
    env: 'server-and-client'
  },
  // direct syntax
  data: dataHook
})
// /pages/some-page/data.js

export default (pageContext) => {
  /* ... */
}

It's a succinct way to define both the config value and its options :+1:.

Hebilicious commented 1 year ago

@Hebilicious It's actually already renamed, see https://vike.dev/meta. I find "meta" better than "extendConfig", given the fact that meta is also about modifying existing configurations.

As for the config helper, it didn't occur to me that it would help JS users. Neat & good to know. PR welcome if that's something you'd be up to.

I also like the idea of an object syntax. Maybe something like that:

// /pages/some-page/+config.h.js

import dataHook from './data.js'

export default defineConfig({
  // object syntax
  dataMeta: {
    value: dataHook,
    // By default `env` is 'server-only'
    env: 'server-and-client'
  },
  // direct syntax
  data: dataHook
})
// /pages/some-page/data.js

export default (pageContext) => {
  /* ... */
}

It's a succinct way to define both the config value and its options :+1:.

I'll open a PR then !

About meta, it's more likely that people associate it with metadata, metaverse or Facebook meta ...

In what context is meta about modifying configuration ?

In my opinion, the name should encapsulate something like define, extend, modify or add.

brillout commented 1 year ago

I agree and I ain't 100% happy with the name "meta" but it's the best I could find so far. The use cases listed in https://vike.dev/meta are a good representation for what meta is used for. Contribution welcome to suggest a better name.

(Looking forward to your defineConfig() PR 👀)

redbar0n commented 1 year ago

I find "meta" better than "extendConfig", given the fact that meta is also about modifying existing configurations.

how about metaConfig ?

vchirikov commented 1 year ago

@brillout it will be nice to have docs about v1 on vike.dev, because for now they're unlisted :\

brillout commented 1 year ago

@redbar0n I think, given the context, metaConfig would be redundent.

// /pages/+config.js

export default {
  // Since we are in +config.js it's fairly clear that meta relates to "meta configuration".
  meta: {
    // ...
  }
}


@vchirikov I agree and it will happen as soon as the V1 design is out of beta. (And since we increasingly recommend users to use Bati and vike-{react,vue,solid}, which both use the V1 design, we should release the V1 design sooner rather than later.)

There is one little breaking change coming for the V1 design and then it should be ready for release. So it's coming soon.

redbar0n commented 1 year ago

@brillout yeah I thought about that, but then again, since a config can refer to anything then meta can refer to anything not necessarily a type of config. So with just meta then it might seem that you are configuring some particular thing called meta (re: all kinds of associations with metadata, metaverse or Facebook meta ...) and not generally applying a configuration of the configuration itself.. Anyways, for my part I found risking a little over-specification in this case wouldn't hurt. Better too clear than unclear.

brillout commented 1 year ago

Technically, meta is a config, just like any other config. How a config is being used is completely up to the implementation that uses it (that's one of the beauty of the V1 design as it's very flexible/customizable). And, actually, meta isn't the only config that influences other configs, e.g. ssr: boolean changes the env of Page. (FYI this flexibility is paramount for vike-{react,vue,solid} and other upcoming integrations such as vike-relay.)

Hebilicious commented 1 year ago

I agree and I ain't 100% happy with the name "meta" but it's the best I could find so far. The use cases listed in vike.dev/meta are a good representation for what meta is used for. Contribution welcome to suggest a better name.

(Looking forward to your defineConfig() PR 👀)

For alternative names :

extend(...) can be replaced by add, additional, define, modify ...

Definitely agree with @redbar0n , meta by itself doesn't indicates whats happening whatsoever (definition was better in that regard). Semantically, extend can be used for both additions and modifications.

redbar0n commented 1 year ago

Re: https://vike.dev/meta

My vote goes to customConfig since it's:

brillout commented 1 year ago

I actually did consider the name define, but I ended up going for meta as it does a better job at communicating that it's a config that influences configs, which is pretty much what "meta level" means. And define can mean everything really (it actually already means something for bundlers like Vite and webpack so, let alone for that reason, we cannot pick that name).

As for the other suggestion, they are misnomers as they convey either extending or modifying but not both. Same for custom (which I actually also did consider back then): it conveys creating new configs but it doesn't convey modifying existing configs. I understand that customConfig is slightly clearer but it's also clunky.

I think meta is good enough, so let me suggest we settle for it.