DEV Community

prasanna malla
prasanna malla

Posted on • Edited on

In 2023, spin up an e-commerce app in 60s with Vendure + Qwik. Fast enough?

Image description
Vendure is a modern, open-source headless commerce framework built with TypeScript & Nodejs. Vendure makes developer productivity a top priority. Combination of TypeScript and GraphQL provides end-to-end type safety. Content is delivered through its GraphQL API, leaving implementation of your storefront applications in technologies of your choice.

Qwik is a framework reimagined for the edge. You know React? You know Qwik. Developer experience is a core principle of Qwik. Built on top of JSX, functional components and reactivity, learning Qwik is a piece of cake.

Get started with Vendure + Qwik in under a minute! Steps required are:

  1. Make sure you have Docker installed
  2. Get the Dev Containers extension for VSCode
  3. Clone the qwik storefront starter

In the terminal, use this command to clone the starter and open the project folder in VSCode:

git clone https://github.com/vendure-ecommerce/storefront-qwik-starter.git && code storefront-qwik-starter

Image description
If you are using windows, line endings need to be 'LF' and not 'CRLF' for devcontainer-install-vendure.sh in VSCode. Reset any system changes to the files in the project folder with git checkout .

Change the fetch call in src/utils/api.ts to use local backend url



const executeRequest = async (options: Options) => {
 const httpResponse = await fetch(ENV_VARIABLES.VITE_VENDURE_LOCAL_URL, options);
 return await extractTokenAndData(httpResponse);
};


Enter fullscreen mode Exit fullscreen mode

Image description
Open the folder in dev container to get a fully functioning local instance. Container installs postgres, populates the database with sample data and serves Vendure backend at port 3000 and Qwik storefront at port 8080. Default admin login: username- superadmin / password- superadmin

List of all endpoints:
Shop API: http://localhost:3000/shop-api
Admin API: http://localhost:3000/admin-api
Asset server: http://localhost:3000/assets
Dev mailbox: http://localhost:3000/mailbox
Admin UI: http://localhost:3000/admin
Qwik Storefront: http://localhost:8080/

Checkout qwik-storefront and sign up for an account, you can verify your email after signup with dev mailbox.

To run dev container without Vendure, disable postgres install in .devcontainer/Dockerfile and make following changes to .devcontainer/devcontainer.json



// For format details, see https://aka.ms/devcontainer.json. For config options, see the README at:
// https://github.com/microsoft/vscode-dev-containers/tree/v0.241.1/containers/typescript-node
{
 "name": "Node.js & TypeScript",
 "build": {
  "dockerfile": "Dockerfile",
  // Update 'VARIANT' to pick a Node version: 18, 16, 14.
  // Append -bullseye or -buster to pin to an OS version.
  // Use -bullseye variants on local on arm64/Apple Silicon.
  "args": {
   "VARIANT": "18"
  }
 },

 // Configure tool-specific properties.
 "customizations": {
  // Configure properties specific to VS Code.
  "vscode": {
   // Add the IDs of extensions you want installed when the container is created.
   "extensions": ["dbaeumer.vscode-eslint", "ms-vscode-remote.remote-containers"]
  }
 },

 // Use 'forwardPorts' to make a list of ports inside the container available locally.
 "forwardPorts": [8080],

 // Use 'postCreateCommand' to run commands after the container is created.
 "postCreateCommand": "pnpm install",

 // Comment out to connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root.
 "remoteUser": "node",

 "postStartCommand": "pnpm dev"
}


Enter fullscreen mode Exit fullscreen mode

Join the communities at vendure + qwik and to learn more follow:

https://github.com/vendure-ecommerce/vendure
https://twitter.com/vendure_io

https://github.com/BuilderIO/qwik
https://twitter.com/QwikDev

https://github.com/vendure-ecommerce/storefront-qwik-starter
https://twitter.com/giorgio_boa

Top comments (1)

Collapse
 
quillen profile image
Quillen • Edited

Hello @prasmalla , thanks for sharing this guide!

I followed this guide, upgraded the node version to 22 and encountered the following problem:



[dev.server] [server] error 10/7/24, 3:45 AM - [TypeOrmModule] Unable to connect to the database. Retrying (1)...
[dev.server] [server] QueryFailedError: permission denied for schema public
[dev.server] [server]     at PostgresQueryRunner.query (/workspaces/storefront-qwik-starter/one-click-deploy/node_modules/typeorm/src/driver/postgres/PostgresQueryRunner.ts:331:19)
[dev.server] [server]     at processTicksAndRejections (node:internal/process/task_queues:105:5)
[dev.server] [server]     at async PostgresQueryRunner.executeQueries (/workspaces/storefront-qwik-starter/one-click-deploy/node_modules/src/query-runner/BaseQueryRunner.ts:660:13)
[dev.server] [server]     at async PostgresQueryRunner.createTable (/workspaces/storefront-qwik-starter/one-click-deploy/node_modules/typeorm/src/driver/postgres/PostgresQueryRunner.ts:610:9)
[dev.server] [server]     at async RdbmsSchemaBuilder.createNewTables (/workspaces/storefront-qwik-starter/one-click-deploy/node_modules/src/schema-builder/RdbmsSchemaBuilder.ts:635:13)
[dev.server] [server]     at async RdbmsSchemaBuilder.executeSchemaSyncOperationsInProperOrder (/workspaces/storefront-qwik-starter/one-click-deploy/node_modules/src/schema-builder/RdbmsSchemaBuilder.ts:225:9)
[dev.server] [server]     at async RdbmsSchemaBuilder.build (/workspaces/storefront-qwik-starter/one-click-deploy/node_modules/src/schema-builder/RdbmsSchemaBuilder.ts:95:13)
[dev.server] [server]     at async DataSource.synchronize (/workspaces/storefront-qwik-starter/one-click-deploy/node_modules/src/data-source/DataSource.ts:339:9)
[dev.server] [server]     at async DataSource.initialize (/workspaces/storefront-qwik-starter/one-click-deploy/node_modules/src/data-source/DataSource.ts:277:43) 
[dev.server] [worker] warn 10/7/24, 3:45 AM - [Vendure Worker] Awaiting DB schema creation... (attempt 4) 
[dev.server] [worker] warn 10/7/24, 3:45 AM - [Vendure Worker] Awaiting DB schema creation... (attempt 5) 
[dev.server] [worker] warn 10/7/24, 3:45 AM - [Vendure Worker] Awaiting DB schema creation... (attempt 6) 
[dev.server] [worker] warn 10/7/24, 3:45 AM - [Vendure Worker] Awaiting DB schema creation... (attempt 7) 
[dev.server] [worker] warn 10/7/24, 3:45 AM - [Vendure Worker] Awaiting DB schema creation... (attempt 8) 
[dev.server] [worker] warn 10/7/24, 3:45 AM - [Vendure Worker] Awaiting DB schema creation... (attempt 9) 
[dev.server] [worker] warn 10/7/24, 3:45 AM - [Vendure Worker] Awaiting DB schema creation... (attempt 10) 
[dev.server] [worker] warn 10/7/24, 3:45 AM - [Vendure Worker] Awaiting DB schema creation... (attempt 11) 
[dev.server] [worker] warn 10/7/24, 3:45 AM - [Vendure Worker] Awaiting DB schema creation... (attempt 12) 
[dev.server] [worker] warn 10/7/24, 3:45 AM - [Vendure Worker] Awaiting DB schema creation... (attempt 13) 
[dev.server] [worker] warn 10/7/24, 3:45 AM - [Vendure Worker] Awaiting DB schema creation... (attempt 14) 
[dev.server] [worker] warn 10/7/24, 3:45 AM - [Vendure Worker] Awaiting DB schema creation... (attempt 15) 
[dev.server] [worker] warn 10/7/24, 3:45 AM - [Vendure Worker] Awaiting DB schema creation... (attempt 16) 
[dev.server] [worker] warn 10/7/24, 3:45 AM - [Vendure Worker] Awaiting DB schema creation... (attempt 17) 
[dev.server] [worker] warn 10/7/24, 3:45 AM - [Vendure Worker] Awaiting DB schema creation... (attempt 18) 
[dev.server] [worker] error 10/7/24, 3:45 AM - [Vendure Worker] Timed out when awaiting the DB schema to be ready!
[dev.server] [worker] QueryFailedError: relation "public.administrator" does not exist
[dev.server] [worker]     at PostgresQueryRunner.query (/workspaces/storefront-qwik-starter/one-click-deploy/node_modules/typeorm/src/driver/postgres/PostgresQueryRunner.ts:331:19)
[dev.server] [worker]     at processTicksAndRejections (node:internal/process/task_queues:105:5)
[dev.server] [worker]     at async SelectQueryBuilder.loadRawResults (/workspaces/storefront-qwik-starter/one-click-deploy/node_modules/src/query-builder/SelectQueryBuilder.ts:3805:25)
[dev.server] [worker]     at async SelectQueryBuilder.executeEntitiesAndRawResults (/workspaces/storefront-qwik-starter/one-click-deploy/node_modules/src/query-builder/SelectQueryBuilder.ts:3551:26)
[dev.server] [worker]     at async SelectQueryBuilder.getRawAndEntities (/workspaces/storefront-qwik-starter/one-click-deploy/node_modules/src/query-builder/SelectQueryBuilder.ts:1670:29)
[dev.server] [worker]     at async SelectQueryBuilder.getMany (/workspaces/storefront-qwik-starter/one-click-deploy/node_modules/src/query-builder/SelectQueryBuilder.ts:1760:25)
[dev.server] [worker]     at async InitializerService.awaitDbSchemaGeneration (/workspaces/storefront-qwik-starter/one-click-deploy/node_modules/@vendure/core/src/service/initializer.service.ts:76:32)
[dev.server] [worker]     at async InitializerService.onModuleInit (/workspaces/storefront-qwik-starter/one-click-deploy/node_modules/@vendure/core/src/service/initializer.service.ts:43:9)
[dev.server] [worker]     at async Promise.all (index 1)
[dev.server] [worker]     at async callModuleInitHook (/workspaces/storefront-qwik-starter/one-click-deploy/node_modules/@nestjs/core/hooks/on-module-init.hook.js:43:5) 
[dev.server] [worker] QueryFailedError: relation "public.zone" does not exist
[dev.server] [worker]     at PostgresQueryRunner.query (/workspaces/storefront-qwik-starter/one-click-deploy/node_modules/typeorm/src/driver/postgres/PostgresQueryRunner.ts:331:19)
[dev.server] [worker]     at processTicksAndRejections (node:internal/process/task_queues:105:5)
[dev.server] [worker]     at async SelectQueryBuilder.loadRawResults (/workspaces/storefront-qwik-starter/one-click-deploy/node_modules/src/query-builder/SelectQueryBuilder.ts:3805:25)
[dev.server] [worker]     at async SelectQueryBuilder.executeEntitiesAndRawResults (/workspaces/storefront-qwik-starter/one-click-deploy/node_modules/src/query-builder/SelectQueryBuilder.ts:3551:26)
[dev.server] [worker]     at async SelectQueryBuilder.getRawAndEntities (/workspaces/storefront-qwik-starter/one-click-deploy/node_modules/src/query-builder/SelectQueryBuilder.ts:1670:29)
[dev.server] [worker]     at async SelectQueryBuilder.getMany (/workspaces/storefront-qwik-starter/one-click-deploy/node_modules/src/query-builder/SelectQueryBuilder.ts:1760:25)
[dev.server] [worker]     at async createSelfRefreshingCache (/workspaces/storefront-qwik-starter/one-click-deploy/node_modules/@vendure/core/src/common/self-refreshing-cache.ts:71:29)
[dev.server] [worker]     at async ZoneService.createCache (/workspaces/storefront-qwik-starter/one-click-deploy/node_modules/@vendure/core/src/service/services/zone.service.ts:61:16)
[dev.server] [worker]     at async ZoneService.ensureCacheExists (/workspaces/storefront-qwik-starter/one-click-deploy/node_modules/@vendure/core/src/service/services/zone.service.ts:221:22)
[dev.server] [worker]     at async ZoneService.initZones (/workspaces/storefront-qwik-starter/one-click-deploy/node_modules/@vendure/core/src/service/services/zone.service.ts:52:9) {
[dev.server] [worker]   query: 'SELECT "Zone"."createdAt" AS "Zone_createdAt", "Zone"."updatedAt" AS "Zone_updatedAt", "Zone"."name" AS "Zone_name", "Zone"."id" AS "Zone_id", "Zone__Zone_members"."createdAt" AS "Zone__Zone_members_createdAt", "Zone__Zone_members"."updatedAt" AS "Zone__Zone_members_updatedAt", "Zone__Zone_members"."code" AS "Zone__Zone_members_code", "Zone__Zone_members"."type" AS "Zone__Zone_members_type", "Zone__Zone_members"."enabled" AS "Zone__Zone_members_enabled", "Zone__Zone_members"."id" AS "Zone__Zone_members_id", "Zone__Zone_members"."parentId" AS "Zone__Zone_members_parentId", "Zone__Zone_members"."discriminator" AS "Zone__Zone_members_discriminator", "Zone__Zone_members__Zone__Zone_members_translations"."createdAt" AS "Zone__Zone_members__Zone__Zone_members_translations_createdAt", "Zone__Zone_members__Zone__Zone_members_translations"."updatedAt" AS "Zone__Zone_members__Zone__Zone_members_translations_updatedAt", "Zone__Zone_members__Zone__Zone_members_translations"."languageCode" AS "6ec28857ea2abf818a953190ac5c79be0399257b", "Zone__Zone_members__Zone__Zone_members_translations"."name" AS "Zone__Zone_members__Zone__Zone_members_translations_name", "Zone__Zone_members__Zone__Zone_members_translations"."id" AS "Zone__Zone_members__Zone__Zone_members_translations_id", "Zone__Zone_members__Zone__Zone_members_translations"."baseId" AS "Zone__Zone_members__Zone__Zone_members_translations_baseId" FROM "public"."zone" "Zone" LEFT JOIN "public"."zone_members_region" "Zone_Zone__Zone_members" ON "Zone_Zone__Zone_members"."zoneId"="Zone"."id" LEFT JOIN "public"."region" "Zone__Zone_members" ON "Zone__Zone_members"."id"="Zone_Zone__Zone_members"."regionId"  LEFT JOIN "public"."region_translation" "Zone__Zone_members__Zone__Zone_members_translations" ON "Zone__Zone_members__Zone__Zone_members_translations"."baseId"="Zone__Zone_members"."id"',
[dev.server] [worker]   parameters: [],
[dev.server] [worker]   driverError: error: relation "public.zone" does not exist
[dev.server] [worker]       at /workspaces/storefront-qwik-starter/one-click-deploy/node_modules/pg/lib/client.js:526:17
[dev.server] [worker]       at processTicksAndRejections (node:internal/process/task_queues:105:5)
[dev.server] [worker]       at async PostgresQueryRunner.query (/workspaces/storefront-qwik-starter/one-click-deploy/node_modules/typeorm/src/driver/postgres/PostgresQueryRunner.ts:260:25)
[dev.server] [worker]       at async SelectQueryBuilder.loadRawResults (/workspaces/storefront-qwik-starter/one-click-deploy/node_modules/src/query-builder/SelectQueryBuilder.ts:3805:25)
[dev.server] [worker]       at async SelectQueryBuilder.executeEntitiesAndRawResults (/workspaces/storefront-qwik-starter/one-click-deploy/node_modules/src/query-builder/SelectQueryBuilder.ts:3551:26)
[dev.server] [worker]       at async SelectQueryBuilder.getRawAndEntities (/workspaces/storefront-qwik-starter/one-click-deploy/node_modules/src/query-builder/SelectQueryBuilder.ts:1670:29)
[dev.server] [worker]       at async SelectQueryBuilder.getMany (/workspaces/storefront-qwik-starter/one-click-deploy/node_modules/src/query-builder/SelectQueryBuilder.ts:1760:25)
[dev.server] [worker]       at async createSelfRefreshingCache (/workspaces/storefront-qwik-starter/one-click-deploy/node_modules/@vendure/core/src/common/self-refreshing-cache.ts:71:29)
[dev.server] [worker]       at async ZoneService.createCache (/workspaces/storefront-qwik-starter/one-click-deploy/node_modules/@vendure/core/src/service/services/zone.service.ts:61:16)
[dev.server] [worker]       at async ZoneService.ensureCacheExists (/workspaces/storefront-qwik-starter/one-click-deploy/node_modules/@vendure/core/src/service/services/zone.service.ts:221:22) {
[dev.server] [worker]     length: 112,
[dev.server] [worker]     severity: 'ERROR',
[dev.server] [worker]     code: '42P01',
[dev.server] [worker]     detail: undefined,
[dev.server] [worker]     hint: undefined,
[dev.server] [worker]     position: '1416',
[dev.server] [worker]     internalPosition: undefined,
[dev.server] [worker]     internalQuery: undefined,
[dev.server] [worker]     where: undefined,
[dev.server] [worker]     schema: undefined,
[dev.server] [worker]     table: undefined,
[dev.server] [worker]     column: undefined,
[dev.server] [worker]     dataType: undefined,
[dev.server] [worker]     constraint: undefined,
[dev.server] [worker]     file: 'parse_relation.c',
[dev.server] [worker]     line: '1371',
[dev.server] [worker]     routine: 'parserOpenTable'
[dev.server] [worker]   },
[dev.server] [worker]   length: 112,
[dev.server] [worker]   severity: 'ERROR',
[dev.server] [worker]   code: '42P01',
[dev.server] [worker]   detail: undefined,
[dev.server] [worker]   hint: undefined,
[dev.server] [worker]   position: '1416',
[dev.server] [worker]   internalPosition: undefined,
[dev.server] [worker]   internalQuery: undefined,
[dev.server] [worker]   where: undefined,
[dev.server] [worker]   schema: undefined,
[dev.server] [worker]   table: undefined,
[dev.server] [worker]   column: undefined,
[dev.server] [worker]   dataType: undefined,
[dev.server] [worker]   constraint: undefined,
[dev.server] [worker]   file: 'parse_relation.c',
[dev.server] [worker]   line: '1371',
[dev.server] [worker]   routine: 'parserOpenTable'
[dev.server] [worker] }
[dev.server] [server] error 10/7/24, 3:45 AM - [TypeOrmModule] Unable to connect to the database. Retrying (2)...
[dev.server] [server] QueryFailedError: permission denied for schema public
[dev.server] [server]     at PostgresQueryRunner.query (/workspaces/storefront-qwik-starter/one-click-deploy/node_modules/typeorm/src/driver/postgres/PostgresQueryRunner.ts:331:19)
[dev.server] [server]     at processTicksAndRejections (node:internal/process/task_queues:105:5)
[dev.server] [server]     at async PostgresQueryRunner.executeQueries (/workspaces/storefront-qwik-starter/one-click-deploy/node_modules/src/query-runner/BaseQueryRunner.ts:660:13)
[dev.server] [server]     at async PostgresQueryRunner.createTable (/workspaces/storefront-qwik-starter/one-click-deploy/node_modules/typeorm/src/driver/postgres/PostgresQueryRunner.ts:610:9)
[dev.server] [server]     at async RdbmsSchemaBuilder.createNewTables (/workspaces/storefront-qwik-starter/one-click-deploy/node_modules/src/schema-builder/RdbmsSchemaBuilder.ts:635:13)
[dev.server] [server]     at async RdbmsSchemaBuilder.executeSchemaSyncOperationsInProperOrder (/workspaces/storefront-qwik-starter/one-click-deploy/node_modules/src/schema-builder/RdbmsSchemaBuilder.ts:225:9)
[dev.server] [server]     at async RdbmsSchemaBuilder.build (/workspaces/storefront-qwik-starter/one-click-deploy/node_modules/src/schema-builder/RdbmsSchemaBuilder.ts:95:13)
[dev.server] [server]     at async DataSource.synchronize (/workspaces/storefront-qwik-starter/one-click-deploy/node_modules/src/data-source/DataSource.ts:339:9)
[dev.server] [server]     at async DataSource.initialize (/workspaces/storefront-qwik-starter/one-click-deploy/node_modules/src/data-source/DataSource.ts:277:43) 
[dev] Warning: fragment with name OrderDetail already exists.
[dev] graphql-tag enforces all fragment names across your application to be unique; read more about
[dev] this in the docs: http://dev.apollodata.com/core/fragments.html#unique-names
[dev] Loading translations...


Enter fullscreen mode Exit fullscreen mode

Could you advise how to fix this? Thanks in advance!