Skip to content

Commit

Permalink
Merge pull request #1075 from basics/feature/use-booster-hydrate
Browse files Browse the repository at this point in the history
fix(composable): added `useBoosterHydrate` composable
  • Loading branch information
ThornWalli authored Aug 12, 2024
2 parents 008e544 + e52f481 commit ffcb8de
Show file tree
Hide file tree
Showing 14 changed files with 107 additions and 49 deletions.
4 changes: 4 additions & 0 deletions docs/.vitepress/navigation.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,10 @@ export default {
text: 'Composables',
collapsed: true,
items: [
{
text: 'useBoosterHydrate',
link: '/composables/useBoosterHydrate'
},
{ text: 'useBoosterFont', link: '/composables/useBoosterFont' },
{
text: 'useBoosterCritical',
Expand Down
21 changes: 21 additions & 0 deletions docs/src/composables/useBoosterHydrate.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
---
title: useBoosterHydrate
---

# {{$frontmatter.title}}

Compasable provides a function for wrapping components in order to control hydration.

[Learn more about component import](/guide/usage#import-components).

## Return

Returns import wrapper function.

## Example

```js
const hydrate = useBoosterHydrate();

const component = hydrate(() => import('~/components/MyComponent.vue'));
```
8 changes: 5 additions & 3 deletions docs/src/guide/usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,20 +42,22 @@ Until now, components were imported either statically (`import component from '@

In the background, the module [`vue3-lazy-hydration`](https://github.com/freddy38510/vue3-lazy-hydration) inspired by `vue-lazy-hydration` from [Markus Oberlehner](https://github.com/maoberlehner/vue-lazy-hydration) is used in a standardised way.

[Learn more about `useBoosterHydrate`](/composables/useBoosterHydrate).

````js
import boosterHydrate from '#booster/hydrate';
const hydrate = useBoosterHydrate();

export default {
components: {
Stage: boosterHydrate(() => import('@/components/organisms/Stage')),
Stage: hydrate(() => import('@/components/organisms/Stage')),
}
};
````

Whether a component is in the viewport or not is determined in the background by the intersection observer. If the initialisation is to take place earlier, e.g. when scrolling, this can be adjusted accordingly via the `rootMargin` option in the [nuxt.config](/guide/options#lazyoffset).

::: warning
Although the <code>#booster/hydrate</code> function can be used in any component, we recommend its explicit use only in pages and layout. Its use within components can be useful only in explicit special cases. Here we recommend the general use of static imports.
Although the `useBoosterHydrate` composable can be used in any component, we recommend its explicit use only in pages and layout. Its use within components can be useful only in explicit special cases. Here we recommend the general use of static imports.
:::

::: info
Expand Down
7 changes: 4 additions & 3 deletions playground/layouts/default.vue
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,14 @@

<script setup>
import 'wicg-inert';
import boosterHydrate from '#booster/hydrate';
import { useBoosterHydrate } from '#imports';
const hydrate = useBoosterHydrate();
const InfoLayer = defineAsyncComponent(() => import('@/components/InfoLayer'));
const GithubCorner = boosterHydrate(
const GithubCorner = hydrate(
() => import('@/components/elements/GithubCorner')
);
const PageHeader = boosterHydrate(() => import('@/components/PageHeader'));
const PageHeader = hydrate(() => import('@/components/PageHeader'));
const route = useRoute();
Expand Down
1 change: 1 addition & 0 deletions playground/nuxt.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export default defineNuxtConfig(async () => {
const { repository } = await readPackage();

return {
compatibilityDate: '2024-08-01',
dev: isDev,

builder: getBuilder(),
Expand Down
21 changes: 8 additions & 13 deletions playground/pages/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -13,22 +13,17 @@
</template>

<script setup>
import boosterHydrate from '#booster/hydrate';
import { useBoosterHydrate } from '#imports';
const hydrate = useBoosterHydrate();
const ModuleStage = boosterHydrate(() => import('@/components/modules/Stage'));
const ModuleTextA = boosterHydrate(
() => import('@/components/modules/TextFontA')
);
const ModuleImageText = boosterHydrate(
() => import('@/components/modules/ImageText')
);
const ModuleTextB = boosterHydrate(
() => import('@/components/modules/TextFontB')
);
const ModuleVideoYoutube = boosterHydrate(
const ModuleStage = hydrate(() => import('@/components/modules/Stage'));
const ModuleTextA = hydrate(() => import('@/components/modules/TextFontA'));
const ModuleImageText = hydrate(() => import('@/components/modules/ImageText'));
const ModuleTextB = hydrate(() => import('@/components/modules/TextFontB'));
const ModuleVideoYoutube = hydrate(
() => import('@/components/modules/VideoYoutube')
);
const ModuleVideoVimeo = boosterHydrate(
const ModuleVideoVimeo = hydrate(
() => import('@/components/modules/VideoVimeo')
);
Expand Down
6 changes: 4 additions & 2 deletions playground/pages/tests/booster-layer/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,16 @@
</template>

<script setup>
import boosterHydrate from '#booster/hydrate';
import BoosterLayer from '#booster/components/BoosterLayer';
import { useBoosterHydrate } from '#imports';
const hydrate = useBoosterHydrate();
const ready = ref(false);
onMounted(() => (ready.value = true));
const ComponentImageText = boosterHydrate(
const ComponentImageText = hydrate(
() => import('@/components/modules/ImageText')
);
Expand Down
8 changes: 5 additions & 3 deletions playground/pages/tests/booster-loader/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,12 @@
</template>

<script setup>
import boosterHydrate from '#booster/hydrate';
import { useBoosterHydrate } from '#imports';
const Critical = boosterHydrate(() => import('./components/Critical'));
const Lazy = boosterHydrate(() => import('./components/Lazy'));
const hydrate = useBoosterHydrate();
const Critical = hydrate(() => import('./components/Critical'));
const Lazy = hydrate(() => import('./components/Lazy'));
definePageMeta({
layout: 'blank'
Expand Down
7 changes: 5 additions & 2 deletions playground/pages/tests/vimeo/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,11 @@
</template>

<script setup>
import boosterHydrate from '#booster/hydrate';
const Default = boosterHydrate(() => import('./components/Default'));
import { useBoosterHydrate } from '#imports';
const hydrate = useBoosterHydrate();
const Default = hydrate(() => import('./components/Default'));
const items = [
{
vimeoUrl: 'https://vimeo.com/288344114',
Expand Down
7 changes: 5 additions & 2 deletions playground/pages/tests/youtube/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,11 @@
</template>

<script setup>
import boosterHydrate from '#booster/hydrate';
const Default = boosterHydrate(() => import('./components/Default'));
import { useBoosterHydrate } from '#imports';
const hydrate = useBoosterHydrate();
const Default = hydrate(() => import('./components/Default'));
const items = [
{
youtubeUrl: 'https://www.youtube.com/watch?v=cLKvbhfVBUU',
Expand Down
23 changes: 23 additions & 0 deletions src/runtime/composables/useBoosterHydrate.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { hydrateWhenVisible } from 'vue3-lazy-hydration';
import { defineAsyncComponent, useRuntimeConfig } from '#imports';

export default function () {
return hydrate;
}

const isDev = process.env.NODE_ENV === 'development';

export const hydrate = component => {
const runtimeConfig = useRuntimeConfig();

return hydrateWhenVisible(wrapComponent(component), {
rootMargin: runtimeConfig.public.booster.lazyOffsetComponent || '0%'
});
};

const wrapComponent = component => {
if (!(isDev || import.meta.server) && typeof component === 'function') {
return defineAsyncComponent(component);
}
return component;
};
29 changes: 10 additions & 19 deletions src/runtime/hydrate.js
Original file line number Diff line number Diff line change
@@ -1,19 +1,10 @@
import { hydrateWhenVisible } from 'vue3-lazy-hydration';
import { defineAsyncComponent, useRuntimeConfig } from '#imports';

const isDev = process.env.NODE_ENV === 'development';

export default component => {
const runtimeConfig = useRuntimeConfig();

return hydrateWhenVisible(wrapComponent(component), {
rootMargin: runtimeConfig.public.booster.lazyOffsetComponent || '0%'
});
};

const wrapComponent = component => {
if (!(isDev || import.meta.server) && typeof component === 'function') {
return defineAsyncComponent(component);
}
return component;
};
import { hydrate } from './composables/useBoosterHydrate';
import { obsolete } from './utils/deprecation';

/**
* @deprecated Import `#booster/hydrate` has been deprecated, please use the new composable `useBoosterHydrate` instead!
*/
export default obsolete(
hydrate,
'WARNING! Obsolete import called. Import `#booster/hydrate` has been deprecated, please use the new composable `useBoosterHydrate` instead!'
);
9 changes: 9 additions & 0 deletions src/runtime/utils/deprecation.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export default function obsolete(newFunction, message) {
const wrapper = (...args) => {
console.warn(message);
return newFunction.apply(this, args);
};
wrapper.prototype = newFunction.prototype;

return wrapper;
}
5 changes: 3 additions & 2 deletions src/tmpl/plugin.tmpl.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
export default options => {
let code = `import { defineNuxtPlugin } from '#imports';
let code = `import { defineNuxtPlugin, useBoosterHydrate } from '#imports';
import vFont from '#booster/directives/vFont';
import { isSupportedBrowser } from '#booster/utils/browser';
import FontList from '#booster/classes/FontList';
import hydrate from '#booster/hydrate';
import { useNuxtApp, useBoosterHead, useRequestHeaders, useRequestURL, useRequestFetch } from '#imports';
import './fonts.css';
Expand All @@ -12,6 +11,8 @@ export default defineNuxtPlugin({
enforce: 'post',
async setup(nuxtApp) {
const hydrate = useBoosterHydrate();
const fontConfig = await import('./fontConfig').then(
module => module.default || module
);
Expand Down

0 comments on commit ffcb8de

Please sign in to comment.