From 9c085036f76751da1859729bb30f84b41ba28e52 Mon Sep 17 00:00:00 2001
From: mtyszczak <mateusz.tyszczak@gmail.com>
Date: Wed, 22 Jan 2025 13:32:22 +0100
Subject: [PATCH] Add vue-vite and vue-webpack examples testing WASM in other
 frameworks

---
 examples/ts/nextjs-app/README.md             | 63 ++++++++------------
 examples/ts/vue-vite/.gitignore              | 31 ++++++++++
 examples/ts/vue-vite/.npmrc                  |  2 +
 examples/ts/vue-vite/.vscode/extensions.json |  3 +
 examples/ts/vue-vite/README.md               | 33 ++++++++++
 examples/ts/vue-vite/__tests__/index.spec.ts | 24 ++++++++
 examples/ts/vue-vite/index.html              | 13 ++++
 examples/ts/vue-vite/jsconfig.json           |  8 +++
 examples/ts/vue-vite/package.json            | 22 +++++++
 examples/ts/vue-vite/playwright.config.ts    | 15 +++++
 examples/ts/vue-vite/src/App.vue             | 24 ++++++++
 examples/ts/vue-vite/src/main.js             |  4 ++
 examples/ts/vue-vite/vite.config.js          | 19 ++++++
 examples/ts/vue-webpack/.gitignore           | 23 +++++++
 examples/ts/vue-webpack/.npmrc               |  2 +
 examples/ts/vue-webpack/README.md            | 24 ++++++++
 examples/ts/vue-webpack/babel.config.js      |  5 ++
 examples/ts/vue-webpack/jsconfig.json        | 19 ++++++
 examples/ts/vue-webpack/package.json         | 44 ++++++++++++++
 examples/ts/vue-webpack/public/index.html    | 10 ++++
 examples/ts/vue-webpack/src/App.vue          | 16 +++++
 examples/ts/vue-webpack/src/main.js          |  4 ++
 examples/ts/vue-webpack/vue.config.js        | 12 ++++
 examples/ts/vue/README.md                    | 50 ----------------
 ts/package.json                              |  4 +-
 25 files changed, 385 insertions(+), 89 deletions(-)
 create mode 100644 examples/ts/vue-vite/.gitignore
 create mode 100644 examples/ts/vue-vite/.npmrc
 create mode 100644 examples/ts/vue-vite/.vscode/extensions.json
 create mode 100644 examples/ts/vue-vite/README.md
 create mode 100644 examples/ts/vue-vite/__tests__/index.spec.ts
 create mode 100644 examples/ts/vue-vite/index.html
 create mode 100644 examples/ts/vue-vite/jsconfig.json
 create mode 100644 examples/ts/vue-vite/package.json
 create mode 100644 examples/ts/vue-vite/playwright.config.ts
 create mode 100644 examples/ts/vue-vite/src/App.vue
 create mode 100644 examples/ts/vue-vite/src/main.js
 create mode 100644 examples/ts/vue-vite/vite.config.js
 create mode 100644 examples/ts/vue-webpack/.gitignore
 create mode 100644 examples/ts/vue-webpack/.npmrc
 create mode 100644 examples/ts/vue-webpack/README.md
 create mode 100644 examples/ts/vue-webpack/babel.config.js
 create mode 100644 examples/ts/vue-webpack/jsconfig.json
 create mode 100644 examples/ts/vue-webpack/package.json
 create mode 100644 examples/ts/vue-webpack/public/index.html
 create mode 100644 examples/ts/vue-webpack/src/App.vue
 create mode 100644 examples/ts/vue-webpack/src/main.js
 create mode 100644 examples/ts/vue-webpack/vue.config.js
 delete mode 100644 examples/ts/vue/README.md

diff --git a/examples/ts/nextjs-app/README.md b/examples/ts/nextjs-app/README.md
index a75ac5248..a38f463e6 100644
--- a/examples/ts/nextjs-app/README.md
+++ b/examples/ts/nextjs-app/README.md
@@ -1,40 +1,27 @@
-This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app).
-
-## Getting Started
-
-First, run the development server:
-
-```bash
-npm run dev
-# or
-yarn dev
-# or
-pnpm dev
-# or
-bun dev
+# nextjs-app
+
+Created by command: `npx create-next-app@latest nextjs-app`
+
+[pages/index.tsx](pages/index.tsx) file was modified
+
+Changes made in order for React + Next.js app to work:
+
+```diff
+const nextConfig = {
+  reactStrictMode: true,
++  webpack: (config, { isServer }) => {
++    if (!isServer) // Prevents client bundles from including node specific packages required for WASM loading in wax
++      config.resolve.fallback = {
++        fs: false,
++        path: false,
++        module: false
++      };
++
++    return config;
++  }
+};
+
+export default nextConfig;
 ```
 
-Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
-
-You can start editing the page by modifying `pages/index.tsx`. The page auto-updates as you edit the file.
-
-[API routes](https://nextjs.org/docs/api-routes/introduction) can be accessed on [http://localhost:3000/api/hello](http://localhost:3000/api/hello). This endpoint can be edited in `pages/api/hello.ts`.
-
-The `pages/api` directory is mapped to `/api/*`. Files in this directory are treated as [API routes](https://nextjs.org/docs/api-routes/introduction) instead of React pages.
-
-This project uses [`next/font`](https://nextjs.org/docs/basic-features/font-optimization) to automatically optimize and load Inter, a custom Google Font.
-
-## Learn More
-
-To learn more about Next.js, take a look at the following resources:
-
-- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
-- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
-
-You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome!
-
-## Deploy on Vercel
-
-The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
-
-Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details.
+As you can see, we had to extend webpack configuration, ensuring `fs`, `path` and `module` dependencies are omitted from bundling as code importing them will be unreachable on the client-web-side
diff --git a/examples/ts/vue-vite/.gitignore b/examples/ts/vue-vite/.gitignore
new file mode 100644
index 000000000..8a0af7239
--- /dev/null
+++ b/examples/ts/vue-vite/.gitignore
@@ -0,0 +1,31 @@
+# Logs
+logs
+*.log
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+pnpm-debug.log*
+lerna-debug.log*
+
+node_modules
+.DS_Store
+dist
+dist-ssr
+coverage
+*.local
+
+/cypress/videos/
+/cypress/screenshots/
+test-results
+
+# Editor directories and files
+.vscode/*
+!.vscode/extensions.json
+.idea
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?
+
+*.tsbuildinfo
diff --git a/examples/ts/vue-vite/.npmrc b/examples/ts/vue-vite/.npmrc
new file mode 100644
index 000000000..c09005dca
--- /dev/null
+++ b/examples/ts/vue-vite/.npmrc
@@ -0,0 +1,2 @@
+# https://gitlab.syncad.com/hive group specification, offering aggregated package view: https://gitlab.syncad.com/groups/hive/-/packages
+@hiveio:registry=https://gitlab.syncad.com/api/v4/groups/136/-/packages/npm/
diff --git a/examples/ts/vue-vite/.vscode/extensions.json b/examples/ts/vue-vite/.vscode/extensions.json
new file mode 100644
index 000000000..a7cea0b06
--- /dev/null
+++ b/examples/ts/vue-vite/.vscode/extensions.json
@@ -0,0 +1,3 @@
+{
+  "recommendations": ["Vue.volar"]
+}
diff --git a/examples/ts/vue-vite/README.md b/examples/ts/vue-vite/README.md
new file mode 100644
index 000000000..56347d5b2
--- /dev/null
+++ b/examples/ts/vue-vite/README.md
@@ -0,0 +1,33 @@
+# vue-webpack
+
+Created by command: `pnpm create vue@latest .`
+
+[src/App.vue](src/App.vue) file was modified
+
+Changes made in order for Vue + Vite to work:
+
+```diff
+import { defineConfig } from 'vite'
+import vue from '@vitejs/plugin-vue'
+
+// https://vite.dev/config/
+export default defineConfig({
+  plugins: [
+    vue()
+  ],
++  optimizeDeps: { // Affects only dev build
++    exclude: ['@hiveio/wax'],
++    include: [
++      '@hiveio/wax > class-validator',
++      '@hiveio/wax > class-transformer',
++      '@hiveio/wax > long',
++      '@hiveio/wax > events',
++      '@hiveio/wax > reflect-metadata'
++    ]
++  }
+})
+```
+
+As you can see, we excluded `@hiveio/wax` from the optimized dependencies list, keeping its sub-dependencies optimized. This results in WASM being downloaded from the proper directory during development build.
+
+During production WASM file is automatically copied to the build directory.
diff --git a/examples/ts/vue-vite/__tests__/index.spec.ts b/examples/ts/vue-vite/__tests__/index.spec.ts
new file mode 100644
index 000000000..2d4a42865
--- /dev/null
+++ b/examples/ts/vue-vite/__tests__/index.spec.ts
@@ -0,0 +1,24 @@
+import { expect, test } from '@playwright/test';
+
+test.describe('Proper WASM Wax loading on playwright ', () => {
+  test.beforeEach(async ({ page }) => {
+    /// use >> marker for each texts printed in the browser context
+    page.on('console', msg => {
+      console.log('>>', msg.type(), msg.text());
+    });
+
+    await page.goto("http://localhost:5317", { waitUntil: "load" });
+  });
+
+  test('WASM should be properly loaded during development', async ({ page }) => {
+    // Wait for wax to be loaded
+    await page.waitForFunction(() => typeof (window as any).waxLoaded !== "undefined");
+
+    const result = await page.evaluate(async() => {
+      return (window as any).waxLoaded; // This value is set by this app in App.vue after successfull wax initialization
+    });
+
+    // Wax should be loaded
+    expect(result).toBe(true);
+  });
+});
diff --git a/examples/ts/vue-vite/index.html b/examples/ts/vue-vite/index.html
new file mode 100644
index 000000000..b19040a0e
--- /dev/null
+++ b/examples/ts/vue-vite/index.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html lang="">
+  <head>
+    <meta charset="UTF-8">
+    <link rel="icon" href="/favicon.ico">
+    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+    <title>Vite App</title>
+  </head>
+  <body>
+    <div id="app"></div>
+    <script type="module" src="/src/main.js"></script>
+  </body>
+</html>
diff --git a/examples/ts/vue-vite/jsconfig.json b/examples/ts/vue-vite/jsconfig.json
new file mode 100644
index 000000000..5a1f2d222
--- /dev/null
+++ b/examples/ts/vue-vite/jsconfig.json
@@ -0,0 +1,8 @@
+{
+  "compilerOptions": {
+    "paths": {
+      "@/*": ["./src/*"]
+    }
+  },
+  "exclude": ["node_modules", "dist"]
+}
diff --git a/examples/ts/vue-vite/package.json b/examples/ts/vue-vite/package.json
new file mode 100644
index 000000000..1188e701f
--- /dev/null
+++ b/examples/ts/vue-vite/package.json
@@ -0,0 +1,22 @@
+{
+  "name": "vue-vite",
+  "version": "0.0.0",
+  "private": true,
+  "type": "module",
+  "scripts": {
+    "dev": "vite",
+    "build": "vite build",
+    "preview": "vite preview",
+    "test": "unset CI && playwright test --workers 1 --max-failures 1 --project=wax_vue_vite_testsuite"
+  },
+  "dependencies": {
+    "vue": "^3.5.13",
+    "@hiveio/wax": "file:../../../ts"
+  },
+  "devDependencies": {
+    "@playwright/test": "^1.49.1",
+    "@vitejs/plugin-vue": "^5.2.1",
+    "playwright": "^1.49.1",
+    "vite": "^6.0.5"
+  }
+}
diff --git a/examples/ts/vue-vite/playwright.config.ts b/examples/ts/vue-vite/playwright.config.ts
new file mode 100644
index 000000000..c969d777c
--- /dev/null
+++ b/examples/ts/vue-vite/playwright.config.ts
@@ -0,0 +1,15 @@
+// This is a workaround for https://github.com/microsoft/playwright/issues/18282#issuecomment-1612266345
+import { defineConfig } from '@playwright/test';
+
+export default defineConfig({
+  projects: [
+    {
+      name: "wax_vue_vite_testsuite",
+      testDir: "./__tests__"
+    }
+  ],
+  // Run your local dev server before starting the tests
+  webServer: {
+    command: 'pnpm dev --port 5317'
+  }
+});
diff --git a/examples/ts/vue-vite/src/App.vue b/examples/ts/vue-vite/src/App.vue
new file mode 100644
index 000000000..c7361fb5a
--- /dev/null
+++ b/examples/ts/vue-vite/src/App.vue
@@ -0,0 +1,24 @@
+<template>
+  <main>You are using wax version: "{{ version }}"</main>
+</template>
+
+<script setup>
+import { createWaxFoundation } from '@hiveio/wax';
+import { ref, onBeforeMount } from 'vue';
+
+const version = ref();
+
+onBeforeMount(async () => {
+  try {
+    const wax = await createWaxFoundation();
+
+    version.value = wax.getVersion();
+
+    window.waxLoaded = true;
+  } catch (error) {
+    console.error(error);
+
+    window.waxLoaded = false;
+  }
+});
+</script>
\ No newline at end of file
diff --git a/examples/ts/vue-vite/src/main.js b/examples/ts/vue-vite/src/main.js
new file mode 100644
index 000000000..01433bca2
--- /dev/null
+++ b/examples/ts/vue-vite/src/main.js
@@ -0,0 +1,4 @@
+import { createApp } from 'vue'
+import App from './App.vue'
+
+createApp(App).mount('#app')
diff --git a/examples/ts/vue-vite/vite.config.js b/examples/ts/vue-vite/vite.config.js
new file mode 100644
index 000000000..c6749ab79
--- /dev/null
+++ b/examples/ts/vue-vite/vite.config.js
@@ -0,0 +1,19 @@
+import { defineConfig } from 'vite'
+import vue from '@vitejs/plugin-vue'
+
+// https://vite.dev/config/
+export default defineConfig({
+  plugins: [
+    vue()
+  ],
+  optimizeDeps: { // Affects only dev build
+    exclude: ['@hiveio/wax'],
+    include: [
+      '@hiveio/wax > class-validator',
+      '@hiveio/wax > class-transformer',
+      '@hiveio/wax > long',
+      '@hiveio/wax > events',
+      '@hiveio/wax > reflect-metadata'
+    ]
+  }
+})
diff --git a/examples/ts/vue-webpack/.gitignore b/examples/ts/vue-webpack/.gitignore
new file mode 100644
index 000000000..403adbc1e
--- /dev/null
+++ b/examples/ts/vue-webpack/.gitignore
@@ -0,0 +1,23 @@
+.DS_Store
+node_modules
+/dist
+
+
+# local env files
+.env.local
+.env.*.local
+
+# Log files
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+pnpm-debug.log*
+
+# Editor directories and files
+.idea
+.vscode
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?
diff --git a/examples/ts/vue-webpack/.npmrc b/examples/ts/vue-webpack/.npmrc
new file mode 100644
index 000000000..22122d9c0
--- /dev/null
+++ b/examples/ts/vue-webpack/.npmrc
@@ -0,0 +1,2 @@
+shamefully-hoist=true
+@hiveio:registry=https://gitlab.syncad.com/api/v4/groups/136/-/packages/npm/
diff --git a/examples/ts/vue-webpack/README.md b/examples/ts/vue-webpack/README.md
new file mode 100644
index 000000000..9334830d4
--- /dev/null
+++ b/examples/ts/vue-webpack/README.md
@@ -0,0 +1,24 @@
+# vue-webpack
+
+Created by command: `vue create vue-webpack` ([`@vue/cli` package](https://www.npmjs.com/package/@vue/cli))
+
+[src/App.vue](src/App.vue) file was modified
+
+Changes made in order for Vue + Webpack to work:
+
+```diff
+const { defineConfig } = require('@vue/cli-service')
+module.exports = defineConfig({
+  transpileDependencies: true,
++  configureWebpack: config => {
++    config.resolve.fallback = {
++      fs: false,
++      path: false,
++      module: false,
++      crypto: false
++    };
++  }
+})
+```
+
+As you can see, we had to extend webpack configuration, ensuring `fs`, `path`, `module` and `crypto` dependencies are omitted from bundling as code importing them will be unreachable on the client-web-side
diff --git a/examples/ts/vue-webpack/babel.config.js b/examples/ts/vue-webpack/babel.config.js
new file mode 100644
index 000000000..e9558405f
--- /dev/null
+++ b/examples/ts/vue-webpack/babel.config.js
@@ -0,0 +1,5 @@
+module.exports = {
+  presets: [
+    '@vue/cli-plugin-babel/preset'
+  ]
+}
diff --git a/examples/ts/vue-webpack/jsconfig.json b/examples/ts/vue-webpack/jsconfig.json
new file mode 100644
index 000000000..4aafc5f6e
--- /dev/null
+++ b/examples/ts/vue-webpack/jsconfig.json
@@ -0,0 +1,19 @@
+{
+  "compilerOptions": {
+    "target": "es5",
+    "module": "esnext",
+    "baseUrl": "./",
+    "moduleResolution": "node",
+    "paths": {
+      "@/*": [
+        "src/*"
+      ]
+    },
+    "lib": [
+      "esnext",
+      "dom",
+      "dom.iterable",
+      "scripthost"
+    ]
+  }
+}
diff --git a/examples/ts/vue-webpack/package.json b/examples/ts/vue-webpack/package.json
new file mode 100644
index 000000000..476b1b07a
--- /dev/null
+++ b/examples/ts/vue-webpack/package.json
@@ -0,0 +1,44 @@
+{
+  "name": "vue-webpack",
+  "version": "0.1.0",
+  "private": true,
+  "scripts": {
+    "serve": "vue-cli-service serve",
+    "build": "vue-cli-service build",
+    "lint": "vue-cli-service lint"
+  },
+  "dependencies": {
+    "core-js": "^3.8.3",
+    "vue": "^3.2.13",
+    "@hiveio/wax": "file:../../../ts"
+  },
+  "devDependencies": {
+    "@babel/core": "^7.12.16",
+    "@babel/eslint-parser": "^7.12.16",
+    "@vue/cli-plugin-babel": "~5.0.0",
+    "@vue/cli-plugin-eslint": "~5.0.0",
+    "@vue/cli-service": "~5.0.0",
+    "eslint": "^7.32.0",
+    "eslint-plugin-vue": "^8.0.3"
+  },
+  "eslintConfig": {
+    "root": true,
+    "env": {
+      "node": true
+    },
+    "extends": [
+      "plugin:vue/vue3-essential",
+      "eslint:recommended"
+    ],
+    "parserOptions": {
+      "parser": "@babel/eslint-parser"
+    },
+    "rules": {}
+  },
+  "browserslist": [
+    "> 1%",
+    "last 2 versions",
+    "not dead",
+    "not ie 11"
+  ]
+}
diff --git a/examples/ts/vue-webpack/public/index.html b/examples/ts/vue-webpack/public/index.html
new file mode 100644
index 000000000..b4ea60dcc
--- /dev/null
+++ b/examples/ts/vue-webpack/public/index.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta charset="utf-8">
+    <meta name="viewport" content="width=device-width,initial-scale=1.0">
+  </head>
+  <body>
+    <div id="app"></div>
+  </body>
+</html>
diff --git a/examples/ts/vue-webpack/src/App.vue b/examples/ts/vue-webpack/src/App.vue
new file mode 100644
index 000000000..387dfde02
--- /dev/null
+++ b/examples/ts/vue-webpack/src/App.vue
@@ -0,0 +1,16 @@
+<template>
+  <main>You are using wax version: "{{ version }}"</main>
+</template>
+
+<script setup>
+import { createWaxFoundation } from '@hiveio/wax';
+import { ref, onBeforeMount } from 'vue';
+
+const version = ref();
+
+onBeforeMount(async () => {
+  const wax = await createWaxFoundation();
+
+  version.value = wax.getVersion();
+});
+</script>
diff --git a/examples/ts/vue-webpack/src/main.js b/examples/ts/vue-webpack/src/main.js
new file mode 100644
index 000000000..01433bca2
--- /dev/null
+++ b/examples/ts/vue-webpack/src/main.js
@@ -0,0 +1,4 @@
+import { createApp } from 'vue'
+import App from './App.vue'
+
+createApp(App).mount('#app')
diff --git a/examples/ts/vue-webpack/vue.config.js b/examples/ts/vue-webpack/vue.config.js
new file mode 100644
index 000000000..9ead6f22f
--- /dev/null
+++ b/examples/ts/vue-webpack/vue.config.js
@@ -0,0 +1,12 @@
+const { defineConfig } = require('@vue/cli-service')
+module.exports = defineConfig({
+  transpileDependencies: true,
+  configureWebpack: (config) => {
+    config.resolve.fallback = {
+      fs: false,
+      path: false,
+      module: false,
+      crypto: false
+    };
+  }
+})
diff --git a/examples/ts/vue/README.md b/examples/ts/vue/README.md
deleted file mode 100644
index 6658eb61a..000000000
--- a/examples/ts/vue/README.md
+++ /dev/null
@@ -1,50 +0,0 @@
-# wax-vue
-
-This template should help get you started developing with Vue 3 in Vite with our wax library.
-
-## Project Setup
-
-```sh
-# Change your directory to vue dir
-cd examples/ts/vue
-
-# Create a vue project in current directory
-pnpm create vue@latest .
-
-# Run through all options
-
-# Install all dependencies
-pnpm install
-
-# Add wax library (the dist-tag should be stable)
-pnpm add @hiveio/wax@stable
-```
-
-### You can use the following code as a template for a simple App.vue code implementing wax
-
-```vue
-<template>
-  <main>You are using wax version: "{{ version }}"</main>
-</template>
-
-<script lang="ts" setup>
-import { createWaxFoundation } from '@hiveio/wax';
-import { ref, onBeforeMount } from 'vue';
-
-const version = ref<string>();
-
-onBeforeMount(async () => {
-  const wax = await createWaxFoundation();
-
-  version.value = wax.getVersion();
-});
-</script>
-```
-
-### Compile and Hot-Reload for Development
-
-Navigate in your browser to the displayed web server location to listen to the project changes
-
-```sh
-pnpm dev
-```
diff --git a/ts/package.json b/ts/package.json
index 4d98ca0dd..ddd770018 100644
--- a/ts/package.json
+++ b/ts/package.json
@@ -19,7 +19,9 @@
     "examples": "run-s examples:*",
     "examples:html": "cd ../examples/ts/html && pnpm install && pnpm run test && cd ../../../ts",
     "examples:nextjs-app": "cd ../examples/ts/nextjs-app && pnpm install && pnpm run build && cd ../../../ts",
-    "examples:node-app": "cd ../examples/ts/node-app && pnpm install && pnpm run test && cd ../../../ts"
+    "examples:node-app": "cd ../examples/ts/node-app && pnpm install && pnpm run test && cd ../../../ts",
+    "examples:vue-webpack": "cd ../examples/ts/vue-webpack && pnpm install && pnpm run build && cd ../../../ts",
+    "examples:vue-vite": "cd ../examples/ts/vue-vite && pnpm install && pnpm run test && pnpm run build && cd ../../../ts"
   },
   "exports": {
     ".": {
-- 
GitLab