Skip to content

Commit

Permalink
fix: improve DX & docs upon using vike-{react,vue,solid} configs with…
Browse files Browse the repository at this point in the history
…out installing (fix #1578)
  • Loading branch information
brillout committed Mar 28, 2024
1 parent 9e213ea commit c08a6bb
Show file tree
Hide file tree
Showing 14 changed files with 125 additions and 26 deletions.
35 changes: 35 additions & 0 deletions docs/components/ImplementedBy.tsx
@@ -0,0 +1,35 @@
export { ImplementedBy }

import { Link } from '@brillout/docpress'
import { UiFrameworkVikeExtension, UiFrameworkVikeExtensionNames } from '../components'
import React from 'react'

function ImplementedBy({
children,
by,
noCustomGuide
}: { children: React.ReactNode; by?: React.ReactNode; noCustomGuide?: true }) {
return (
<>
<br />
Implemented by: {by ?? <UiFrameworkVikeExtensionNames />}.
<blockquote>
<p>
You need to use{' '}
{by ?? (
<>
a <UiFrameworkVikeExtension />
</>
)}{' '}
in order to use the {children}.
{!noCustomGuide && (
<>
{' '}If you don't use {by ?? <UiFrameworkVikeExtensionNames />} then see{' '}
<Link href="#without-vike-extension" />.
</>
)}
</p>
</blockquote>
</>
)
}
1 change: 1 addition & 0 deletions docs/components/index.ts
Expand Up @@ -9,3 +9,4 @@ export { RecommendationRouterLibraries } from './RecommendationRouterLibraries'
export { HookTypeScriptHints } from './HookTypeScriptHints'
export { ViteLazyTranspilingContradiction } from './ViteLazyTranspilingContradiction'
export { Example, Github } from './Example'
export { ImplementedBy } from './ImplementedBy'
2 changes: 1 addition & 1 deletion docs/pages/ClientOnly/+Page.mdx
Expand Up @@ -2,7 +2,7 @@ import { Link } from '@brillout/docpress'
import { ClientOnlyCommon } from './ClientOnlyCommon.tsx'
import { UiFrameworkVikeExtension } from '../../components'

Provided by: <UiFrameworkVikeExtension /> (or <Link href="#without-vike-extension">yourself</Link>).
Implemented by: <UiFrameworkVikeExtension /> (or <Link href="#without-vike-extension">yourself</Link>).

The `<ClientOnly>` wrapper enables you to render and load a component only on the client-side.

Expand Down
4 changes: 2 additions & 2 deletions docs/pages/Layout/+Page.mdx
@@ -1,7 +1,7 @@
import { Link, RepoLink } from '@brillout/docpress'
import { UiFrameworkVikeExtension } from '../../components'
import { UiFrameworkVikeExtension, ImplementedBy } from '../../components'

Provided by: <UiFrameworkVikeExtension /> (or <Link href="#without-vike-extension">yourself</Link>).
<ImplementedBy>`Layout` setting</ImplementedBy>

> **What are layouts?**
> Pages can have different layouts:
Expand Down
4 changes: 2 additions & 2 deletions docs/pages/Wrapper/+Page.mdx
@@ -1,7 +1,7 @@
import { Link } from '@brillout/docpress'
import { UiFrameworkVikeExtension } from '../../components'
import { UiFrameworkVikeExtension, ImplementedBy } from '../../components'

Provided by: <UiFrameworkVikeExtension /> (or <Link href="#without-vike-extension">yourself</Link>).
<ImplementedBy>`Wrapper` setting</ImplementedBy>

The `Wrapper` setting wraps your <Link href="/Page">Page component</Link> with another component.

Expand Down
2 changes: 1 addition & 1 deletion docs/pages/data-fetching/+Page.mdx
Expand Up @@ -54,7 +54,7 @@ import { useData } from 'vike-solid/useData'
const { name, price } = data
```

> `useData()` is provided by the <UiFrameworkVikeExtension />. If you don't use <UiFrameworkVikeExtensionNames /> then see <Link href="/useData#without-vike-extension" doNotInferSectionTitle />.
> `useData()` is implemented by the <UiFrameworkVikeExtension />. If you don't use <UiFrameworkVikeExtensionNames /> then see <Link href="/useData#without-vike-extension" doNotInferSectionTitle />.
The `data()` hook is only meant for fetching the initial data of a page (in technical words: the SSR data). For other use cases see the sections below <Link href="#api-routes">API routes</Link> and <Link href="#rpc">RPC</Link>.

Expand Down
45 changes: 42 additions & 3 deletions docs/pages/extends/+Page.mdx
@@ -1,14 +1,53 @@
import { Link, Warning } from '@brillout/docpress'

You use `extends` to install <Link href="/extensions" noBreadcrumb />.
To install <Link href="/extensions">Vike extensions</Link> you use `extends`:

```js
// /pages/+config.js

import vikeReact from 'vike-react'
import vikeReact from 'vike-react/config'

export default {
// Inherit the configuration set by vike-react
// Install vike-react.
// In technical terms: inherit the configuration set by `vike-react/config`.
extends: vikeReact
}
```

## Inheritance

Note that <Link href="/config#inheritance">config inheritance</Link> also applies to `extends`.

For example, you can use two completely different rendering strategy: some pages can use Vue without SSR while other pages can use React with SSR.

```js
// /pages/admin/+config.js

import vikeVue from 'vike-vue/config'

// Applies only to Admin Panel pages:
// /pages/admin/income/+Page.js
// /pages/admin/kpi/+Page.js
// ...

// Make all Admin Panel pages use Vue without SSR:
export default {
ssr: false,
extends: [vikeVue]
}
```

```js
// /pages/product/@id/+config.js

import vikeReact from 'vike-react/config'

// Applies only to the product page:
// /pages/product/@id/+Page.js

// Make the product page use React with SSR:
export default {
ssr: true,
extends: [vikeReact]
}
```
2 changes: 1 addition & 1 deletion docs/pages/head/+Page.mdx
Expand Up @@ -7,7 +7,7 @@ To add `<head>` tags, such as `<title>` and `<meta name="description">`, you can
- The page settings <Link href="#title-favicon">`title` & `favicon`</Link>.
- :construction: The <Link href="#usehead">`useHead()`</Link> component hook.

> These options are provided by the <UiFrameworkVikeExtension />. See <Link href="#without-vike-extension" /> if you don't use such extension.
> These options are implemented by the <UiFrameworkVikeExtension />. See <Link href="#without-vike-extension" /> if you don't use such extension.

## `Head`
Expand Down
5 changes: 3 additions & 2 deletions docs/pages/onCreateApp/+Page.mdx
@@ -1,7 +1,8 @@
import { Link } from '@brillout/docpress'
import { ImplementedBy } from '../../components'

Environment: server, client.
Provided by: <Link href="/extensions"><code>vike-vue</code> extension</Link>
Environment: server, client.
<ImplementedBy by={<code>vike-vue</code>} noCustomGuide={true}>`onCreateApp()` hook</ImplementedBy>

The `onCreateApp()` hook is called right after the
[Vue app](https://vuejs.org/guide/essentials/application.html) is created, giving you the opportunity to extend it,
Expand Down
6 changes: 3 additions & 3 deletions docs/pages/ssr/+Page.mdx
@@ -1,8 +1,8 @@
import { Link } from '@brillout/docpress'
import { UiFrameworkVikeExtension } from '../../components'
import { UiFrameworkVikeExtension, ImplementedBy } from '../../components'

Default value: `true`.
Provided by: <UiFrameworkVikeExtension /> (or <Link href="#without-vike-extension">yourself</Link>).
Default value: `true`.
<ImplementedBy>`ssr` setting</ImplementedBy>

Setting to enable/disable Server-Side Rendering (SSR). You can disable SSR for all your pages or only for some pages.

Expand Down
6 changes: 3 additions & 3 deletions docs/pages/stream/+Page.mdx
@@ -1,10 +1,10 @@
import { Link } from '@brillout/docpress'

import { UiFrameworkVikeExtension } from '../../components'
import { UiFrameworkVikeExtension, ImplementedBy } from '../../components'

Default value: `false`. (Or `true` if using a <Link href="/extensions">Vike extension</Link> that requires streaming.)
Requires: <Link href="/ssr">`ssr: true`</Link>.
Provided by: <UiFrameworkVikeExtension /> (or <Link href="#without-vike-extension">yourself</Link>).
Requires: <Link href="/ssr">`ssr: true`</Link>.
<ImplementedBy>`stream` setting</ImplementedBy>

Setting to disable/enable <Link href="/streaming">HTML Streaming</Link>.

Expand Down
2 changes: 1 addition & 1 deletion docs/pages/useData/+Page.mdx
Expand Up @@ -2,7 +2,7 @@ import { Link } from '@brillout/docpress'
import { UiFrameworkVikeExtension } from '../../components'

Environment: server, client.
Provided by: <UiFrameworkVikeExtension /> (or <Link href="#without-vike-extension">yourself</Link>).
Implemented by: <UiFrameworkVikeExtension /> (or <Link href="#without-vike-extension">yourself</Link>).

The `useData()` component hook allows you to access the data that is returned by a <Link href="/data">`data()` hook</Link>.

Expand Down
2 changes: 1 addition & 1 deletion docs/pages/usePageContext/+Page.mdx
Expand Up @@ -3,7 +3,7 @@ import { Link, RepoLink } from '@brillout/docpress'
import { UiFrameworkVikeExtension } from '../../components'

Environment: server, client.
Provided by: <UiFrameworkVikeExtension /> (or <Link href="#without-vike-extension">yourself</Link>).
Implemented by: <UiFrameworkVikeExtension /> (or <Link href="#without-vike-extension">yourself</Link>).

The `usePageContext()` hook enables any UI component to access the <Link href="/pageContext">`pageContext`</Link> object.

Expand Down
35 changes: 29 additions & 6 deletions vike/node/plugin/plugins/importUserCode/v1-design/getVikeConfig.ts
Expand Up @@ -1046,7 +1046,34 @@ function assertNoUnexpectedPlusSign(filePath: string, fileName: string) {
*/

function handleUnknownConfig(configName: string, configNames: string[], filePathToShowToUser: string) {
let errMsg = `${filePathToShowToUser} defines an unknown config ${pc.cyan(configName)}`
{
const ui = ['vike-react', 'vike-vue', 'vike-solid'] as const
const knownVikeExntensionConfigs = {
description: ui,
favicon: ui,
Head: ui,
Layout: ui,
onCreateApp: ['vike-vue'],
title: ui,
ssr: ui,
stream: ui,
Wrapper: ui
} as const
if (configName in knownVikeExntensionConfigs) {
const requiredVikeExtension = knownVikeExntensionConfigs[configName as keyof typeof knownVikeExntensionConfigs]
assertUsage(
false,
[
`${filePathToShowToUser} uses the config ${pc.cyan(configName)} (https://vike.dev/${configName})`,
`which requires the Vike extension ${requiredVikeExtension.map((e) => pc.bold(e)).join('/')}.`,
`Make sure to install the Vike extension,`,
`and make sure it applies to ${filePathToShowToUser} as explained at https://vike.dev/extends#inheritance.`
].join(' ')
)
}
}

let errMsg = `${filePathToShowToUser} sets an unknown config ${pc.cyan(configName)}`
let configNameSimilar: string | null = null
if (configName === 'page') {
configNameSimilar = 'Page'
Expand All @@ -1055,16 +1082,12 @@ function handleUnknownConfig(configName: string, configNames: string[], filePath
}
if (configNameSimilar) {
assert(configNameSimilar !== configName)
errMsg += `, did you mean to define ${pc.cyan(configNameSimilar)} instead?`
errMsg += `, did you mean to set ${pc.cyan(configNameSimilar)} instead?`
if (configName === 'page') {
errMsg += ` (The name of the config ${pc.cyan('Page')} starts with a capital letter ${pc.cyan(
'P'
)} because it usually defines a UI component: a ubiquitous JavaScript convention is to start the name of UI components with a capital letter.)`
}
} else {
errMsg += `, you need to define the config ${pc.cyan(configName)} by using ${pc.cyan(
'config.meta'
)} https://vike.dev/meta`
}
assertUsage(false, errMsg)
}
Expand Down

0 comments on commit c08a6bb

Please sign in to comment.