Skip to content

Commit 2525c72

Browse files
author
Marcin Kwiatkowski
authored
feat: added support for @vue-storefront/cache module (#482)
* chore(theme): added nuxt-image * feat(theme): added nuxt-img to category page * feat: added nuxt-img to category pages, added newe configs, and useImage compoosable * feat(theme): added nuxt-img to products carousel, added image enums * feat(theme): added nuxt-img for search results * feat(theme): added nuxt-img to my account wishlist * feat(theme): changed log to use nuxt-img * feat(theme): changed empty cart icon to use nuxt-img * feat(theme): added nuxt-img to instagram feed, updated image names * feat(theme): changed error image on search results to use nuxt-img * feat(theme): update store switcher to use nuxt-img instead of SfImage * feat(theme): added nuxt-img to wishlist sidebar * feat(theme): added nuxt-img to MobileStoreBanner * feat(theme): added nuxt-img to grouoped product selector * feat(theme): added nuxt-img to payment component * docs: added docs for external images providers * build(cloud): updated vuestorefront cloud docker file and added new args * build: updated deploy gh action to add image env vatiables * docs(configuration): updated docs for image providers * build: added missed buildargs * build: fixed dockerfile * build: fixed typo in docker file * build: updated config * test: add unit tests for the useImage composable * chore(theme): added @vue-storefront-cache module * chore(theme): added config for @vue-storefront/cache to nuxt.config.js * feat(theme): added cache tags to home and category page * chore(theme): added redis-cache module, fixed cache tags for category page * feat(theme): added cache tags to product page, added body parser server middleware * build: added config for redis, modified deployment config for tests * build: removed unnecessary redis_password env variable * build: fixed redis env variables names * feat(theme): added cache tags for cms pages * chore(theme): removed console.logs, added comments to nuxt.config.js * build: removed redis-cache module from package.json and addet it to dockerfile * build: updated dockerfile * build(updzted docker file): updated dovkerfile * build: added REDIS__ENABLED env variable * docs: added docs for redis caching * build: reverted test changes in deploy action * fix(theme): removed typo from Category template n * build: fixed GH deploy action
1 parent de3e8ff commit 2525c72

File tree

14 files changed

+20633
-26967
lines changed

14 files changed

+20633
-26967
lines changed

.github/workflows/deploy-vue-storefront-cloud.yml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ jobs:
2525
password: ${{ secrets.CLOUD_PASSWORD }}
2626
dockerfile: .vuestorefrontcloud/docker/Dockerfile
2727
buildoptions: --compress
28-
buildargs: NPM_EMAIL,NPM_PASS,NPM_USER,NPM_REGISTRY,STORE_URL,MAGENTO_GRAPHQL,MAGENTO_EXTERNAL_CHECKOUT,MAGENTO_EXTERNAL_CHECKOUT_URL,MAGENTO_EXTERNAL_CHECKOUT_SYNC_PATH,IMAGE_PROVIDER,IMAGE_PROVIDER_BASE_URL,SENTRY_DSN
28+
buildargs: NPM_EMAIL,NPM_PASS,NPM_USER,NPM_REGISTRY,STORE_URL,MAGENTO_GRAPHQL,MAGENTO_EXTERNAL_CHECKOUT,MAGENTO_EXTERNAL_CHECKOUT_URL,MAGENTO_EXTERNAL_CHECKOUT_SYNC_PATH,IMAGE_PROVIDER,IMAGE_PROVIDER_BASE_URL,REDIS__HOST,REDIS__PORT,REDIS__CACHE_INVALIDATE_KEY,REDIS__CACHE_INVALIDATE_URL,REDIS__KEY_PREFIX,REDIS__ENABLED,SENTRY_DSN
2929
env:
3030
NPM_EMAIL: ${{ secrets.NPM_EMAIL }}
3131
NPM_PASS: ${{ secrets.CLOUD_PASSWORD }}
@@ -38,6 +38,12 @@ jobs:
3838
MAGENTO_EXTERNAL_CHECKOUT_SYNC_PATH: ${{ secrets.MAGENTO_EXTERNAL_CHECKOUT_SYNC_PATH }}
3939
IMAGE_PROVIDER: ${{ secrets.IMAGE_PROVIDER }}
4040
IMAGE_PROVIDER_BASE_URL: ${{ secrets.IMAGE_PROVIDER_BASE_URL }}
41+
REDIS__HOST: ${{ secrets.REDIS__HOST }}
42+
REDIS__PORT: ${{ secrets.REDIS__PORT }}
43+
REDIS__KEY_PREFIX: ${{ secrets.REDIS__KEY_PREFIX }}
44+
REDIS__CACHE_INVALIDATE_KEY: ${{ secrets.REDIS__CACHE_INVALIDATE_KEY }}
45+
REDIS__CACHE_INVALIDATE_URL: ${{ secrets.REDIS__CACHE_INVALIDATE_URL }}
46+
REDIS__ENABLED: ${{ secrets.REDIS__ENABLED }}
4147
SENTRY_DSN: ${{ secrets.SENTRY_DSN }}
4248
deploy:
4349
runs-on: ubuntu-latest

.vuestorefrontcloud/docker/Dockerfile

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,13 @@ ARG STORE_URL
1313
ARG MAGENTO_BASE_URL
1414
ARG IMAGE_PROVIDER
1515
ARG IMAGE_PROVIDER_BASE_URL
16+
ARG REDIS__HOST
17+
ARG REDIS__PORT
18+
ARG REDIS__CACHE_INVALIDATE_KEY
19+
ARG REDIS__CACHE_INVALIDATE_URL
20+
ARG REDIS__CACHE_INVALIDATE_URL
21+
ARG REDIS__KEY_PREFIX
22+
ARG REDIS__ENABLED
1623
ARG SENTRY_DSN
1724

1825
ENV MAGENTO_GRAPHQL=${MAGENTO_GRAPHQL}
@@ -27,6 +34,13 @@ ENV NUXT_APP_PORT=3000
2734
ENV MAGENTO_BASE_URL=https://magento2-instance.vuestorefront.io/
2835
ENV IMAGE_PROVIDER=${IMAGE_PROVIDER}
2936
ENV IMAGE_PROVIDER_BASE_URL=${IMAGE_PROVIDER_BASE_URL}
37+
ENV REDIS__HOST=${REDIS__HOST}
38+
ENV REDIS__PORT=${REDIS__PORT}
39+
ENV REDIS__CACHE_INVALIDATE_KEY=${REDIS__CACHE_INVALIDATE_KEY}
40+
ENV REDIS__CACHE_INVALIDATE_URL=${REDIS__CACHE_INVALIDATE_URL}
41+
ENV REDIS__CACHE_INVALIDATE_URL=${REDIS__CACHE_INVALIDATE_URL}
42+
ENV REDIS__KEY_PREFIX=${REDIS__KEY_PREFIX}
43+
ENV REDIS__ENABLED=${REDIS__ENABLED}
3044
ENV SENTRY_DSN=${SENTRY_DSN}
3145

3246

@@ -37,7 +51,11 @@ WORKDIR /var/www
3751

3852
COPY . .
3953

40-
RUN yarn install && yarn build && yarn cache clean --all
54+
RUN yarn install
55+
56+
RUN npx [email protected] workspace @vue-storefront/magento-theme add @vsf-enterprise/redis-cache
57+
58+
RUN yarn build && yarn cache clean --all
4159

4260
COPY .vuestorefrontcloud/docker/vue-storefront.sh /usr/local/bin/
4361

docs/.vuepress/config.js

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,8 @@ module.exports = {
4747
{ text: 'Core Documentation', link: 'https://docs.vuestorefront.io/v2/' },
4848
{ text: 'Demo', link: 'https://demo-magento2.europe-west1.gcp.storefrontcloud.io/' },
4949
{ text: 'GitHub', link: 'https://github.com/vuestorefront/magento2'},
50-
{ text: 'Roadmap', link: 'https://github.com/vuestorefront/magento2/projects/5'}
50+
{ text: 'Roadmap', link: 'https://docs.vuestorefront.io/magento/guide/roadmap.html'},
51+
{ text: 'Environments', link: 'https://docs.vuestorefront.io/magento/guide/environments.html'}
5152
],
5253
sidebar: [
5354
{
@@ -66,13 +67,21 @@ module.exports = {
6667
collapsable: false,
6768
children: [
6869
['/guide/creating-a-store', 'Creating a Store'],
69-
['/guide/graphql-get', 'Use GET for GraphQL Queries'],
7070
['/guide/configuration', 'Configuration'],
7171
['/guide/override-queries', 'Override queries'],
72+
['/guide/testing', 'Testing'],
7273
['/guide/recaptcha', 'ReCaptcha'],
7374
['/guide/testing', 'Testing']
7475
]
7576
},
77+
{
78+
title: 'Performance',
79+
collapsable: false,
80+
children: [
81+
['/guide/graphql-get', 'Varnish & GET for GraphQL Queries'],
82+
['/guide/ssr', 'Server Side Rendering Cache'],
83+
]
84+
},
7685
{
7786
title: 'Composables',
7887
children: [

docs/guide/ssr.md

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
# Server-Side Rendering Cache
2+
3+
## Introduction
4+
5+
VueStorefront 2 - Magento 2 integrations use @vue-storefront/cache module that adds posibility to cache some server-side
6+
rendered pages.
7+
8+
### What is cached
9+
The cached pages are:
10+
11+
* Home page with the `Vhome` tag.
12+
* All CMS pages with the `V${page.identifier}` tag
13+
* Category page with the `Vcategory` tag and tags for products: `P${product.uid}` as well as categories `C${category.slug}`
14+
* Product page with the `Vproduct-${route.value.params.id}` tag and tags for the main product `P${product.uid}` as well as categories `C${cat.id}`
15+
16+
## Invalidating tags
17+
18+
To invalidate a tag and remove pages associated with that tag, use the [Invalidation endpoint](https://docs.vuestorefront.io/v2/performance/ssr-cache.html#invalidating-tags).
19+
20+
Go to the route configured in the `.env` file under the `REDIS__CACHE_INVALIDATE_KEY` key with two query parameters:
21+
* `key` — string matching the `REDIS__CACHE_INVALIDATE_KEY` key in the `.env` file.
22+
* `tags` — a comma-separated list of tags for invalidation.
23+
24+
Assuming that you are running the application locally, the `REDIS__CACHE_INVALIDATE_URL` key is equal to `/cache-invalidate,` and the `REDIS__CACHE_INVALIDATE_KEY` key is equal to `secret_key`, and you want to invalidate the `Vhome` tag, the full URL will look like this:
25+
26+
## How to cache other pages
27+
28+
We added caching only to the most visited pages. However, you can cache other pages as well, including custom ones. You can find detailed instructions on how to use cache on the [SSR Cache](https://docs.vuestorefront.io/v2/performance/ssr-cache.html) and [Redis cache](https://docs.vuestorefront.io/v2/integrations/redis-cache.html) pages.
29+
30+
:::tip
31+
You don't need to add any additional packages to cache more pages — just add or modify tags in components.
32+
:::
33+
34+
## Cache drivers
35+
36+
@vue-storefront/cache module is open source and provided Out Of The Box by Magento 2 integration.
37+
To set up caching in your store, you must install and configure a cache driver.
38+
You can use our enterprise `@vsf-enterprise/redis-cache` module, or build your cache driver.
39+
40+
### Redis cache (enterprise)
41+
Once you have access to the [Vue Storefront npm registry](https://docs.vuestorefront.io/v2/general/enterprise.htm),
42+
you can install the Redis cache driver by running this command in a console:
43+
44+
``yarn add @vsf-enterprise/redis-cache``
45+
46+
47+
#### redis cache configuration
48+
49+
Once you have the Redis driver installed, you need to add the Redis configuration to your project's `.env` file.
50+
51+
```
52+
.env
53+
REDIS__HOST=127.0.0.1
54+
REDIS__PORT=6379
55+
REDIS_PASSWORD=
56+
REDIS__KEY_PREFIX=
57+
REDIS__CACHE_INVALIDATE_URL=/cache-invalidate
58+
REDIS__ENABLED=false
59+
```
60+
61+
Then you have to update `nuxt.config.js file` and add this to the `modules` object:
62+
63+
```javascript
64+
['@vue-storefront/cache/nuxt', {
65+
enabled: process.env.REDIS__ENABLED,
66+
invalidation: {
67+
endpoint: process.env.REDIS__CACHE_INVALIDATE_URL,
68+
key: process.env.REDIS__CACHE_INVALIDATE_KEY,
69+
handlers: [
70+
'@vue-storefront/cache/defaultHandler',
71+
],
72+
},
73+
driver: [
74+
'@vsf-enterprise/redis-cache',
75+
{
76+
// docs: https://github.com/luin/ioredis/blob/master/API.md#new-redisport-host-options
77+
redis: {
78+
keyPrefix: process.env.REDIS__KEY_PREFIX,
79+
host: process.env.REDIS__HOST,
80+
port: process.env.REDIS__PORT,
81+
},
82+
},
83+
],
84+
}],
85+
```
86+
87+
## Useful links
88+
89+
- https://docs.vuestorefront.io/v2/performance/ssr-cache.html
90+
- https://docs.vuestorefront.io/v2/integrations/redis-cache.html
91+
- https://docs.vuestorefront.io/v2/integrate/cache-driver.html

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,5 +88,5 @@
8888
"node": ">=16.x.x",
8989
"yarn": "1.x.x||>=3.x.x"
9090
},
91-
"packageManager": "yarn@3.1.1"
91+
"packageManager": "yarn@1.22.15"
9292
}

packages/theme/.env.example

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,12 @@ MAGENTO_EXTERNAL_CHECKOUT_SYNC_PATH=/vue/cart/sync
99
MAGENTO_BASE_URL={YOUR_SITE_FRONT_URL}
1010
IMAGE_PROVIDER={YOUR_IMAGE_PROVIDER}
1111
IMAGE_PROVIDER_BASE_URL={YOUR_IMAGE_PROVIDER_BASE_URL}
12+
MAGENTO_BASE_URL={YOUR_SITE_FRONT_URL}
13+
IMAGE_PROVIDER={YOUR_IMAGE_PROVIDER}
14+
IMAGE_PROVIDER_BASE_URL={YOUR_IMAGE_PROVIDER_BASE_URL}
15+
REDIS__HOST=127.0.0.1
16+
REDIS__PORT=6379
17+
REDIS_PASSWORD=
18+
REDIS__KEY_PREFIX=
19+
REDIS__CACHE_INVALIDATE_URL=/cache-invalidate
20+
REDIS__ENABLED=false

packages/theme/nuxt.config.js

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,29 @@ export default {
115115
'@nuxt/image',
116116
'@nuxtjs/sentry',
117117
// '@nuxtjs/recaptcha',
118+
['@vue-storefront/cache/nuxt', {
119+
enabled: process.env.REDIS__ENABLED,
120+
invalidation: {
121+
endpoint: process.env.REDIS__CACHE_INVALIDATE_URL,
122+
key: process.env.REDIS__CACHE_INVALIDATE_KEY,
123+
handlers: [
124+
'@vue-storefront/cache/defaultHandler',
125+
],
126+
},
127+
driver: [
128+
// project only start:
129+
'@vsf-enterprise/redis-cache',
130+
{
131+
// docs: https://github.com/luin/ioredis/blob/master/API.md#new-redisport-host-options
132+
redis: {
133+
keyPrefix: process.env.REDIS__KEY_PREFIX,
134+
host: process.env.REDIS__HOST,
135+
port: process.env.REDIS__PORT,
136+
},
137+
},
138+
// project only end
139+
],
140+
}],
118141
],
119142
recaptcha: {
120143
hideBadge: config.get('recaptchaHideBadge'), // Hide badge element (v3 & v2 via size=invisible)
@@ -252,6 +275,9 @@ export default {
252275
'~/plugins/i18n',
253276
'~/plugins/fcPlugin',
254277
],
278+
serverMiddleware: [
279+
'~/serverMiddleware/body-parser.js',
280+
],
255281
router: {
256282
extendRoutes(routes) {
257283
getRoutes(`${__dirname}/_theme`)

packages/theme/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
"@nuxtjs/style-resources": "^1.2.1",
3636
"@sentry/tracing": "^6.17.2",
3737
"@storefront-ui/vue": "^0.11.5",
38+
"@vue-storefront/cache": "^2.5.4",
3839
"@vue-storefront/core": "~2.5.4",
3940
"@vue-storefront/magento": "1.0.0-rc.5.3",
4041
"@vue-storefront/middleware": "~2.5.4",

packages/theme/pages/Category.vue

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -431,6 +431,7 @@ import {
431431
useWishlist,
432432
} from '@vue-storefront/magento';
433433
import { onSSR, useVSFContext } from '@vue-storefront/core';
434+
import { useCache, CacheTagPrefix } from '@vue-storefront/cache';
434435
import { useUrlResolver } from '~/composables/useUrlResolver.ts';
435436
import { useUiHelpers, useUiState, useImage } from '~/composables';
436437
import cacheControl from '~/helpers/cacheControl';
@@ -466,6 +467,7 @@ export default defineComponent({
466467
}),
467468
transition: 'fade',
468469
setup() {
470+
const { addTags } = useCache();
469471
const uiHelpers = useUiHelpers();
470472
const uiState = useUiState();
471473
const {
@@ -641,6 +643,19 @@ export default defineComponent({
641643
await searchCategoryProduct();
642644
isProductsLoading.value = false;
643645
}
646+
647+
const tags = [{ prefix: CacheTagPrefix.View, value: 'category' }];
648+
// eslint-disable-next-line no-underscore-dangle
649+
const productTags = products.value.map((product) => {
650+
return { prefix: CacheTagPrefix.Product, value: product.uid };
651+
});
652+
653+
const categoriesTags = categoryTree.value.items.map((category) => {
654+
return { prefix: CacheTagPrefix.Category, value: category.slug };
655+
});
656+
657+
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
658+
addTags(tags.concat(productTags, categoriesTags));
644659
});
645660
646661
const { getMagentoImage, imageSizes } = useImage();

packages/theme/pages/Home.vue

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ import {
7777
} from '@nuxtjs/composition-api';
7878
import { onSSR } from '@vue-storefront/core';
7979
import LazyHydrate from 'vue-lazy-hydration';
80+
import { useCache, CacheTagPrefix } from '@vue-storefront/cache';
8081
import MobileStoreBanner from '~/components/MobileStoreBanner.vue';
8182
import InstagramFeed from '~/components/InstagramFeed.vue';
8283
import ProductsCarousel from '~/components/ProductsCarousel.vue';
@@ -95,6 +96,8 @@ export default defineComponent({
9596
},
9697
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
9798
setup() {
99+
const { addTags } = useCache();
100+
98101
const {
99102
products: newProductsResult,
100103
search: newProductsSearch,
@@ -215,6 +218,10 @@ export default defineComponent({
215218
position: 'ASC',
216219
},
217220
});
221+
222+
addTags([
223+
{ prefix: CacheTagPrefix.View, value: 'home' }
224+
]);
218225
});
219226
220227
return {

0 commit comments

Comments
 (0)