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