+ You’ve successfully created a project with
+ Vite +
+ Vue 3. What's next?
+
+
+
+
+
diff --git a/playground/typescript-jsx-router-pinia-nightwatch/src/components/TheWelcome.vue b/playground/typescript-jsx-router-pinia-nightwatch/src/components/TheWelcome.vue
new file mode 100644
index 000000000..49d8f7354
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-nightwatch/src/components/TheWelcome.vue
@@ -0,0 +1,88 @@
+
+
+
+
+
+
+
+ Documentation
+
+ Vue’s
+ official documentation
+ provides you with all information you need to get started.
+
+
+
+
+
+
+ Tooling
+
+ This project is served and bundled with
+ Vite. The
+ recommended IDE setup is
+ VSCode +
+ Volar. If
+ you need to test your components and web pages, check out
+ Cypress and
+ Cypress Component Testing.
+
+
+
+ More instructions are available in README.md.
+
+
+
+
+
+
+ Ecosystem
+
+ Get official tools and libraries for your project:
+ Pinia,
+ Vue Router,
+ Vue Test Utils, and
+ Vue Dev Tools. If
+ you need more resources, we suggest paying
+ Awesome Vue
+ a visit.
+
+
+
+
+
+
+ Community
+
+ Got stuck? Ask your question on
+ Vue Land, our official
+ Discord server, or
+ StackOverflow. You should also subscribe to
+ our mailing list and follow
+ the official
+ @vuejs
+ twitter account for latest news in the Vue world.
+
+
+
+
+
+
+ Support Vue
+
+ As an independent project, Vue relies on community backing for its sustainability. You can help
+ us by
+ becoming a sponsor.
+
+
diff --git a/playground/typescript-jsx-router-pinia-nightwatch/src/components/WelcomeItem.vue b/playground/typescript-jsx-router-pinia-nightwatch/src/components/WelcomeItem.vue
new file mode 100644
index 000000000..6d7086aea
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-nightwatch/src/components/WelcomeItem.vue
@@ -0,0 +1,87 @@
+
+
+ You’ve successfully created a project with
+ Vite +
+ Vue 3. What's next?
+
+
+
+
+
diff --git a/playground/typescript-jsx-router-pinia-playwright/src/components/TheWelcome.vue b/playground/typescript-jsx-router-pinia-playwright/src/components/TheWelcome.vue
new file mode 100644
index 000000000..49d8f7354
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-playwright/src/components/TheWelcome.vue
@@ -0,0 +1,88 @@
+
+
+
+
+
+
+
+ Documentation
+
+ Vue’s
+ official documentation
+ provides you with all information you need to get started.
+
+
+
+
+
+
+ Tooling
+
+ This project is served and bundled with
+ Vite. The
+ recommended IDE setup is
+ VSCode +
+ Volar. If
+ you need to test your components and web pages, check out
+ Cypress and
+ Cypress Component Testing.
+
+
+
+ More instructions are available in README.md.
+
+
+
+
+
+
+ Ecosystem
+
+ Get official tools and libraries for your project:
+ Pinia,
+ Vue Router,
+ Vue Test Utils, and
+ Vue Dev Tools. If
+ you need more resources, we suggest paying
+ Awesome Vue
+ a visit.
+
+
+
+
+
+
+ Community
+
+ Got stuck? Ask your question on
+ Vue Land, our official
+ Discord server, or
+ StackOverflow. You should also subscribe to
+ our mailing list and follow
+ the official
+ @vuejs
+ twitter account for latest news in the Vue world.
+
+
+
+
+
+
+ Support Vue
+
+ As an independent project, Vue relies on community backing for its sustainability. You can help
+ us by
+ becoming a sponsor.
+
+
diff --git a/playground/typescript-jsx-router-pinia-playwright/src/components/WelcomeItem.vue b/playground/typescript-jsx-router-pinia-playwright/src/components/WelcomeItem.vue
new file mode 100644
index 000000000..6d7086aea
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-playwright/src/components/WelcomeItem.vue
@@ -0,0 +1,87 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/playground/typescript-jsx-router-pinia-playwright/src/components/icons/IconCommunity.vue b/playground/typescript-jsx-router-pinia-playwright/src/components/icons/IconCommunity.vue
new file mode 100644
index 000000000..2dc8b0552
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-playwright/src/components/icons/IconCommunity.vue
@@ -0,0 +1,7 @@
+
+
+
diff --git a/playground/typescript-jsx-router-pinia-playwright/src/components/icons/IconDocumentation.vue b/playground/typescript-jsx-router-pinia-playwright/src/components/icons/IconDocumentation.vue
new file mode 100644
index 000000000..6d4791cfb
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-playwright/src/components/icons/IconDocumentation.vue
@@ -0,0 +1,7 @@
+
+
+
diff --git a/playground/typescript-jsx-router-pinia-playwright/src/components/icons/IconEcosystem.vue b/playground/typescript-jsx-router-pinia-playwright/src/components/icons/IconEcosystem.vue
new file mode 100644
index 000000000..c3a4f078c
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-playwright/src/components/icons/IconEcosystem.vue
@@ -0,0 +1,7 @@
+
+
+
diff --git a/playground/typescript-jsx-router-pinia-playwright/src/components/icons/IconSupport.vue b/playground/typescript-jsx-router-pinia-playwright/src/components/icons/IconSupport.vue
new file mode 100644
index 000000000..7452834d3
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-playwright/src/components/icons/IconSupport.vue
@@ -0,0 +1,7 @@
+
+
+
diff --git a/playground/typescript-jsx-router-pinia-playwright/src/components/icons/IconTooling.vue b/playground/typescript-jsx-router-pinia-playwright/src/components/icons/IconTooling.vue
new file mode 100644
index 000000000..660598d7c
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-playwright/src/components/icons/IconTooling.vue
@@ -0,0 +1,19 @@
+
+
+
+
diff --git a/playground/typescript-jsx-router-pinia-playwright/src/main.ts b/playground/typescript-jsx-router-pinia-playwright/src/main.ts
new file mode 100644
index 000000000..5dcad83c3
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-playwright/src/main.ts
@@ -0,0 +1,14 @@
+import './assets/main.css'
+
+import { createApp } from 'vue'
+import { createPinia } from 'pinia'
+
+import App from './App.vue'
+import router from './router'
+
+const app = createApp(App)
+
+app.use(createPinia())
+app.use(router)
+
+app.mount('#app')
diff --git a/playground/typescript-jsx-router-pinia-playwright/src/router/index.ts b/playground/typescript-jsx-router-pinia-playwright/src/router/index.ts
new file mode 100644
index 000000000..a49ae507f
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-playwright/src/router/index.ts
@@ -0,0 +1,23 @@
+import { createRouter, createWebHistory } from 'vue-router'
+import HomeView from '../views/HomeView.vue'
+
+const router = createRouter({
+ history: createWebHistory(import.meta.env.BASE_URL),
+ routes: [
+ {
+ path: '/',
+ name: 'home',
+ component: HomeView
+ },
+ {
+ path: '/about',
+ name: 'about',
+ // route level code-splitting
+ // this generates a separate chunk (About.[hash].js) for this route
+ // which is lazy-loaded when the route is visited.
+ component: () => import('../views/AboutView.vue')
+ }
+ ]
+})
+
+export default router
diff --git a/playground/typescript-jsx-router-pinia-playwright/src/stores/counter.ts b/playground/typescript-jsx-router-pinia-playwright/src/stores/counter.ts
new file mode 100644
index 000000000..b6757ba57
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-playwright/src/stores/counter.ts
@@ -0,0 +1,12 @@
+import { ref, computed } from 'vue'
+import { defineStore } from 'pinia'
+
+export const useCounterStore = defineStore('counter', () => {
+ const count = ref(0)
+ const doubleCount = computed(() => count.value * 2)
+ function increment() {
+ count.value++
+ }
+
+ return { count, doubleCount, increment }
+})
diff --git a/playground/typescript-jsx-router-pinia-playwright/src/views/AboutView.vue b/playground/typescript-jsx-router-pinia-playwright/src/views/AboutView.vue
new file mode 100644
index 000000000..756ad2a17
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-playwright/src/views/AboutView.vue
@@ -0,0 +1,15 @@
+
+
+
This is an about page
+
+
+
+
diff --git a/playground/typescript-jsx-router-pinia-playwright/src/views/HomeView.vue b/playground/typescript-jsx-router-pinia-playwright/src/views/HomeView.vue
new file mode 100644
index 000000000..d5c0217e4
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-playwright/src/views/HomeView.vue
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
diff --git a/playground/typescript-jsx-router-pinia-playwright/tsconfig.app.json b/playground/typescript-jsx-router-pinia-playwright/tsconfig.app.json
new file mode 100644
index 000000000..e14c754d3
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-playwright/tsconfig.app.json
@@ -0,0 +1,14 @@
+{
+ "extends": "@vue/tsconfig/tsconfig.dom.json",
+ "include": ["env.d.ts", "src/**/*", "src/**/*.vue"],
+ "exclude": ["src/**/__tests__/*"],
+ "compilerOptions": {
+ "composite": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
+
+ "baseUrl": ".",
+ "paths": {
+ "@/*": ["./src/*"]
+ }
+ }
+}
diff --git a/playground/typescript-jsx-router-pinia-playwright/tsconfig.json b/playground/typescript-jsx-router-pinia-playwright/tsconfig.json
new file mode 100644
index 000000000..66b5e5703
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-playwright/tsconfig.json
@@ -0,0 +1,11 @@
+{
+ "files": [],
+ "references": [
+ {
+ "path": "./tsconfig.node.json"
+ },
+ {
+ "path": "./tsconfig.app.json"
+ }
+ ]
+}
diff --git a/playground/typescript-jsx-router-pinia-playwright/tsconfig.node.json b/playground/typescript-jsx-router-pinia-playwright/tsconfig.node.json
new file mode 100644
index 000000000..f09406303
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-playwright/tsconfig.node.json
@@ -0,0 +1,19 @@
+{
+ "extends": "@tsconfig/node20/tsconfig.json",
+ "include": [
+ "vite.config.*",
+ "vitest.config.*",
+ "cypress.config.*",
+ "nightwatch.conf.*",
+ "playwright.config.*"
+ ],
+ "compilerOptions": {
+ "composite": true,
+ "noEmit": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
+
+ "module": "ESNext",
+ "moduleResolution": "Bundler",
+ "types": ["node"]
+ }
+}
diff --git a/playground/typescript-jsx-router-pinia-playwright/vite.config.ts b/playground/typescript-jsx-router-pinia-playwright/vite.config.ts
new file mode 100644
index 000000000..36c618756
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-playwright/vite.config.ts
@@ -0,0 +1,18 @@
+import { fileURLToPath, URL } from 'node:url'
+
+import { defineConfig } from 'vite'
+import vue from '@vitejs/plugin-vue'
+import vueJsx from '@vitejs/plugin-vue-jsx'
+
+// https://vitejs.dev/config/
+export default defineConfig({
+ plugins: [
+ vue(),
+ vueJsx(),
+ ],
+ resolve: {
+ alias: {
+ '@': fileURLToPath(new URL('./src', import.meta.url))
+ }
+ }
+})
diff --git a/playground/typescript-jsx-router-pinia-vitest-cypress/.gitignore b/playground/typescript-jsx-router-pinia-vitest-cypress/.gitignore
new file mode 100644
index 000000000..8ee54e8d3
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-vitest-cypress/.gitignore
@@ -0,0 +1,30 @@
+# 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/
+
+# Editor directories and files
+.vscode/*
+!.vscode/extensions.json
+.idea
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?
+
+*.tsbuildinfo
diff --git a/playground/typescript-jsx-router-pinia-vitest-cypress/README.md b/playground/typescript-jsx-router-pinia-vitest-cypress/README.md
new file mode 100644
index 000000000..9a2410570
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-vitest-cypress/README.md
@@ -0,0 +1,62 @@
+# typescript-jsx-router-pinia-vitest-cypress
+
+This template should help get you started developing with Vue 3 in Vite.
+
+## Recommended IDE Setup
+
+[VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur) + [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin).
+
+## Type Support for `.vue` Imports in TS
+
+TypeScript cannot handle type information for `.vue` imports by default, so we replace the `tsc` CLI with `vue-tsc` for type checking. In editors, we need [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin) to make the TypeScript language service aware of `.vue` types.
+
+If the standalone TypeScript plugin doesn't feel fast enough to you, Volar has also implemented a [Take Over Mode](https://github.com/johnsoncodehk/volar/discussions/471#discussioncomment-1361669) that is more performant. You can enable it by the following steps:
+
+1. Disable the built-in TypeScript Extension
+ 1) Run `Extensions: Show Built-in Extensions` from VSCode's command palette
+ 2) Find `TypeScript and JavaScript Language Features`, right click and select `Disable (Workspace)`
+2. Reload the VSCode window by running `Developer: Reload Window` from the command palette.
+
+## Customize configuration
+
+See [Vite Configuration Reference](https://vitejs.dev/config/).
+
+## Project Setup
+
+```sh
+pnpm install
+```
+
+### Compile and Hot-Reload for Development
+
+```sh
+pnpm dev
+```
+
+### Type-Check, Compile and Minify for Production
+
+```sh
+pnpm build
+```
+
+### Run Unit Tests with [Vitest](https://vitest.dev/)
+
+```sh
+pnpm test:unit
+```
+
+### Run End-to-End Tests with [Cypress](https://www.cypress.io/)
+
+```sh
+pnpm test:e2e:dev
+```
+
+This runs the end-to-end tests against the Vite development server.
+It is much faster than the production build.
+
+But it's still recommended to test the production build with `test:e2e` before deploying (e.g. in CI environments):
+
+```sh
+pnpm build
+pnpm test:e2e
+```
diff --git a/playground/typescript-jsx-router-pinia-vitest-cypress/cypress.config.ts b/playground/typescript-jsx-router-pinia-vitest-cypress/cypress.config.ts
new file mode 100644
index 000000000..0f66080fd
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-vitest-cypress/cypress.config.ts
@@ -0,0 +1,8 @@
+import { defineConfig } from 'cypress'
+
+export default defineConfig({
+ e2e: {
+ specPattern: 'cypress/e2e/**/*.{cy,spec}.{js,jsx,ts,tsx}',
+ baseUrl: 'http://localhost:4173'
+ }
+})
diff --git a/playground/typescript-jsx-router-pinia-vitest-cypress/cypress/e2e/example.cy.ts b/playground/typescript-jsx-router-pinia-vitest-cypress/cypress/e2e/example.cy.ts
new file mode 100644
index 000000000..7554c35d8
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-vitest-cypress/cypress/e2e/example.cy.ts
@@ -0,0 +1,8 @@
+// https://on.cypress.io/api
+
+describe('My First Test', () => {
+ it('visits the app root url', () => {
+ cy.visit('/')
+ cy.contains('h1', 'You did it!')
+ })
+})
diff --git a/playground/typescript-jsx-router-pinia-vitest-cypress/cypress/e2e/tsconfig.json b/playground/typescript-jsx-router-pinia-vitest-cypress/cypress/e2e/tsconfig.json
new file mode 100644
index 000000000..37748feb7
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-vitest-cypress/cypress/e2e/tsconfig.json
@@ -0,0 +1,10 @@
+{
+ "extends": "@vue/tsconfig/tsconfig.dom.json",
+ "include": ["./**/*", "../support/**/*"],
+ "compilerOptions": {
+ "isolatedModules": false,
+ "target": "es5",
+ "lib": ["es5", "dom"],
+ "types": ["cypress"]
+ }
+}
diff --git a/playground/typescript-jsx-router-pinia-vitest-cypress/cypress/fixtures/example.json b/playground/typescript-jsx-router-pinia-vitest-cypress/cypress/fixtures/example.json
new file mode 100644
index 000000000..02e425437
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-vitest-cypress/cypress/fixtures/example.json
@@ -0,0 +1,5 @@
+{
+ "name": "Using fixtures to represent data",
+ "email": "hello@cypress.io",
+ "body": "Fixtures are a great way to mock data for responses to routes"
+}
diff --git a/playground/typescript-jsx-router-pinia-vitest-cypress/cypress/support/commands.ts b/playground/typescript-jsx-router-pinia-vitest-cypress/cypress/support/commands.ts
new file mode 100644
index 000000000..9b7bb8e25
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-vitest-cypress/cypress/support/commands.ts
@@ -0,0 +1,39 @@
+///
+// ***********************************************
+// This example commands.ts shows you how to
+// create various custom commands and overwrite
+// existing commands.
+//
+// For more comprehensive examples of custom
+// commands please read more here:
+// https://on.cypress.io/custom-commands
+// ***********************************************
+//
+//
+// -- This is a parent command --
+// Cypress.Commands.add('login', (email, password) => { ... })
+//
+//
+// -- This is a child command --
+// Cypress.Commands.add('drag', { prevSubject: 'element'}, (subject, options) => { ... })
+//
+//
+// -- This is a dual command --
+// Cypress.Commands.add('dismiss', { prevSubject: 'optional'}, (subject, options) => { ... })
+//
+//
+// -- This will overwrite an existing command --
+// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... })
+//
+// declare global {
+// namespace Cypress {
+// interface Chainable {
+// login(email: string, password: string): Chainable
+// drag(subject: string, options?: Partial): Chainable
+// dismiss(subject: string, options?: Partial): Chainable
+// visit(originalFn: CommandOriginalFn, url: string, options: Partial): Chainable
+// }
+// }
+// }
+
+export {}
diff --git a/playground/typescript-jsx-router-pinia-vitest-cypress/cypress/support/e2e.ts b/playground/typescript-jsx-router-pinia-vitest-cypress/cypress/support/e2e.ts
new file mode 100644
index 000000000..d68db96df
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-vitest-cypress/cypress/support/e2e.ts
@@ -0,0 +1,20 @@
+// ***********************************************************
+// This example support/index.js is processed and
+// loaded automatically before your test files.
+//
+// This is a great place to put global configuration and
+// behavior that modifies Cypress.
+//
+// You can change the location of this file or turn off
+// automatically serving support files with the
+// 'supportFile' configuration option.
+//
+// You can read more here:
+// https://on.cypress.io/configuration
+// ***********************************************************
+
+// Import commands.js using ES2015 syntax:
+import './commands'
+
+// Alternatively you can use CommonJS syntax:
+// require('./commands')
diff --git a/playground/typescript-jsx-router-pinia-vitest-cypress/env.d.ts b/playground/typescript-jsx-router-pinia-vitest-cypress/env.d.ts
new file mode 100644
index 000000000..11f02fe2a
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-vitest-cypress/env.d.ts
@@ -0,0 +1 @@
+///
diff --git a/playground/typescript-jsx-router-pinia-vitest-cypress/index.html b/playground/typescript-jsx-router-pinia-vitest-cypress/index.html
new file mode 100644
index 000000000..a88854489
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-vitest-cypress/index.html
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+ Vite App
+
+
+
+
+
+
diff --git a/playground/typescript-jsx-router-pinia-vitest-cypress/package.json b/playground/typescript-jsx-router-pinia-vitest-cypress/package.json
new file mode 100644
index 000000000..58d5b141e
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-vitest-cypress/package.json
@@ -0,0 +1,38 @@
+{
+ "name": "typescript-jsx-router-pinia-vitest-cypress",
+ "version": "0.0.0",
+ "private": true,
+ "type": "module",
+ "scripts": {
+ "dev": "vite",
+ "build": "run-p type-check \"build-only {@}\" --",
+ "preview": "vite preview",
+ "test:unit": "vitest",
+ "test:e2e": "start-server-and-test preview http://localhost:4173 'cypress run --e2e'",
+ "test:e2e:dev": "start-server-and-test 'vite dev --port 4173' http://localhost:4173 'cypress open --e2e'",
+ "build-only": "vite build",
+ "type-check": "vue-tsc --build --force"
+ },
+ "dependencies": {
+ "pinia": "^2.1.7",
+ "vue": "^3.4.15",
+ "vue-router": "^4.2.5"
+ },
+ "devDependencies": {
+ "@tsconfig/node20": "^20.1.2",
+ "@types/jsdom": "^21.1.6",
+ "@types/node": "^20.11.16",
+ "@vitejs/plugin-vue": "^5.0.3",
+ "@vitejs/plugin-vue-jsx": "^3.1.0",
+ "@vue/test-utils": "^2.4.4",
+ "@vue/tsconfig": "^0.5.1",
+ "cypress": "^13.6.4",
+ "jsdom": "^24.0.0",
+ "npm-run-all2": "^6.1.2",
+ "start-server-and-test": "^2.0.3",
+ "typescript": "~5.3.0",
+ "vite": "^5.0.11",
+ "vitest": "^1.2.2",
+ "vue-tsc": "^1.8.27"
+ }
+}
diff --git a/playground/typescript-jsx-router-pinia-vitest-cypress/public/favicon.ico b/playground/typescript-jsx-router-pinia-vitest-cypress/public/favicon.ico
new file mode 100644
index 000000000..df36fcfb7
Binary files /dev/null and b/playground/typescript-jsx-router-pinia-vitest-cypress/public/favicon.ico differ
diff --git a/playground/typescript-jsx-router-pinia-vitest-cypress/src/App.vue b/playground/typescript-jsx-router-pinia-vitest-cypress/src/App.vue
new file mode 100644
index 000000000..7905b0516
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-vitest-cypress/src/App.vue
@@ -0,0 +1,85 @@
+
+
+
+
+
+
+
+ You’ve successfully created a project with
+ Vite +
+ Vue 3. What's next?
+
+
+
+
+
diff --git a/playground/typescript-jsx-router-pinia-vitest-cypress/src/components/TheWelcome.vue b/playground/typescript-jsx-router-pinia-vitest-cypress/src/components/TheWelcome.vue
new file mode 100644
index 000000000..49d8f7354
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-vitest-cypress/src/components/TheWelcome.vue
@@ -0,0 +1,88 @@
+
+
+
+
+
+
+
+ Documentation
+
+ Vue’s
+ official documentation
+ provides you with all information you need to get started.
+
+
+
+
+
+
+ Tooling
+
+ This project is served and bundled with
+ Vite. The
+ recommended IDE setup is
+ VSCode +
+ Volar. If
+ you need to test your components and web pages, check out
+ Cypress and
+ Cypress Component Testing.
+
+
+
+ More instructions are available in README.md.
+
+
+
+
+
+
+ Ecosystem
+
+ Get official tools and libraries for your project:
+ Pinia,
+ Vue Router,
+ Vue Test Utils, and
+ Vue Dev Tools. If
+ you need more resources, we suggest paying
+ Awesome Vue
+ a visit.
+
+
+
+
+
+
+ Community
+
+ Got stuck? Ask your question on
+ Vue Land, our official
+ Discord server, or
+ StackOverflow. You should also subscribe to
+ our mailing list and follow
+ the official
+ @vuejs
+ twitter account for latest news in the Vue world.
+
+
+
+
+
+
+ Support Vue
+
+ As an independent project, Vue relies on community backing for its sustainability. You can help
+ us by
+ becoming a sponsor.
+
+
diff --git a/playground/typescript-jsx-router-pinia-vitest-cypress/src/components/WelcomeItem.vue b/playground/typescript-jsx-router-pinia-vitest-cypress/src/components/WelcomeItem.vue
new file mode 100644
index 000000000..6d7086aea
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-vitest-cypress/src/components/WelcomeItem.vue
@@ -0,0 +1,87 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/playground/typescript-jsx-router-pinia-vitest-cypress/src/components/__tests__/HelloWorld.spec.ts b/playground/typescript-jsx-router-pinia-vitest-cypress/src/components/__tests__/HelloWorld.spec.ts
new file mode 100644
index 000000000..253320200
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-vitest-cypress/src/components/__tests__/HelloWorld.spec.ts
@@ -0,0 +1,11 @@
+import { describe, it, expect } from 'vitest'
+
+import { mount } from '@vue/test-utils'
+import HelloWorld from '../HelloWorld.vue'
+
+describe('HelloWorld', () => {
+ it('renders properly', () => {
+ const wrapper = mount(HelloWorld, { props: { msg: 'Hello Vitest' } })
+ expect(wrapper.text()).toContain('Hello Vitest')
+ })
+})
diff --git a/playground/typescript-jsx-router-pinia-vitest-cypress/src/components/icons/IconCommunity.vue b/playground/typescript-jsx-router-pinia-vitest-cypress/src/components/icons/IconCommunity.vue
new file mode 100644
index 000000000..2dc8b0552
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-vitest-cypress/src/components/icons/IconCommunity.vue
@@ -0,0 +1,7 @@
+
+
+
diff --git a/playground/typescript-jsx-router-pinia-vitest-cypress/src/components/icons/IconDocumentation.vue b/playground/typescript-jsx-router-pinia-vitest-cypress/src/components/icons/IconDocumentation.vue
new file mode 100644
index 000000000..6d4791cfb
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-vitest-cypress/src/components/icons/IconDocumentation.vue
@@ -0,0 +1,7 @@
+
+
+
diff --git a/playground/typescript-jsx-router-pinia-vitest-cypress/src/components/icons/IconEcosystem.vue b/playground/typescript-jsx-router-pinia-vitest-cypress/src/components/icons/IconEcosystem.vue
new file mode 100644
index 000000000..c3a4f078c
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-vitest-cypress/src/components/icons/IconEcosystem.vue
@@ -0,0 +1,7 @@
+
+
+
diff --git a/playground/typescript-jsx-router-pinia-vitest-cypress/src/components/icons/IconSupport.vue b/playground/typescript-jsx-router-pinia-vitest-cypress/src/components/icons/IconSupport.vue
new file mode 100644
index 000000000..7452834d3
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-vitest-cypress/src/components/icons/IconSupport.vue
@@ -0,0 +1,7 @@
+
+
+
diff --git a/playground/typescript-jsx-router-pinia-vitest-cypress/src/components/icons/IconTooling.vue b/playground/typescript-jsx-router-pinia-vitest-cypress/src/components/icons/IconTooling.vue
new file mode 100644
index 000000000..660598d7c
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-vitest-cypress/src/components/icons/IconTooling.vue
@@ -0,0 +1,19 @@
+
+
+
+
diff --git a/playground/typescript-jsx-router-pinia-vitest-cypress/src/main.ts b/playground/typescript-jsx-router-pinia-vitest-cypress/src/main.ts
new file mode 100644
index 000000000..5dcad83c3
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-vitest-cypress/src/main.ts
@@ -0,0 +1,14 @@
+import './assets/main.css'
+
+import { createApp } from 'vue'
+import { createPinia } from 'pinia'
+
+import App from './App.vue'
+import router from './router'
+
+const app = createApp(App)
+
+app.use(createPinia())
+app.use(router)
+
+app.mount('#app')
diff --git a/playground/typescript-jsx-router-pinia-vitest-cypress/src/router/index.ts b/playground/typescript-jsx-router-pinia-vitest-cypress/src/router/index.ts
new file mode 100644
index 000000000..a49ae507f
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-vitest-cypress/src/router/index.ts
@@ -0,0 +1,23 @@
+import { createRouter, createWebHistory } from 'vue-router'
+import HomeView from '../views/HomeView.vue'
+
+const router = createRouter({
+ history: createWebHistory(import.meta.env.BASE_URL),
+ routes: [
+ {
+ path: '/',
+ name: 'home',
+ component: HomeView
+ },
+ {
+ path: '/about',
+ name: 'about',
+ // route level code-splitting
+ // this generates a separate chunk (About.[hash].js) for this route
+ // which is lazy-loaded when the route is visited.
+ component: () => import('../views/AboutView.vue')
+ }
+ ]
+})
+
+export default router
diff --git a/playground/typescript-jsx-router-pinia-vitest-cypress/src/stores/counter.ts b/playground/typescript-jsx-router-pinia-vitest-cypress/src/stores/counter.ts
new file mode 100644
index 000000000..b6757ba57
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-vitest-cypress/src/stores/counter.ts
@@ -0,0 +1,12 @@
+import { ref, computed } from 'vue'
+import { defineStore } from 'pinia'
+
+export const useCounterStore = defineStore('counter', () => {
+ const count = ref(0)
+ const doubleCount = computed(() => count.value * 2)
+ function increment() {
+ count.value++
+ }
+
+ return { count, doubleCount, increment }
+})
diff --git a/playground/typescript-jsx-router-pinia-vitest-cypress/src/views/AboutView.vue b/playground/typescript-jsx-router-pinia-vitest-cypress/src/views/AboutView.vue
new file mode 100644
index 000000000..756ad2a17
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-vitest-cypress/src/views/AboutView.vue
@@ -0,0 +1,15 @@
+
+
+
This is an about page
+
+
+
+
diff --git a/playground/typescript-jsx-router-pinia-vitest-cypress/src/views/HomeView.vue b/playground/typescript-jsx-router-pinia-vitest-cypress/src/views/HomeView.vue
new file mode 100644
index 000000000..d5c0217e4
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-vitest-cypress/src/views/HomeView.vue
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
diff --git a/playground/typescript-jsx-router-pinia-vitest-cypress/tsconfig.app.json b/playground/typescript-jsx-router-pinia-vitest-cypress/tsconfig.app.json
new file mode 100644
index 000000000..e14c754d3
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-vitest-cypress/tsconfig.app.json
@@ -0,0 +1,14 @@
+{
+ "extends": "@vue/tsconfig/tsconfig.dom.json",
+ "include": ["env.d.ts", "src/**/*", "src/**/*.vue"],
+ "exclude": ["src/**/__tests__/*"],
+ "compilerOptions": {
+ "composite": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
+
+ "baseUrl": ".",
+ "paths": {
+ "@/*": ["./src/*"]
+ }
+ }
+}
diff --git a/playground/typescript-jsx-router-pinia-vitest-cypress/tsconfig.json b/playground/typescript-jsx-router-pinia-vitest-cypress/tsconfig.json
new file mode 100644
index 000000000..5304731b8
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-vitest-cypress/tsconfig.json
@@ -0,0 +1,17 @@
+{
+ "files": [],
+ "references": [
+ {
+ "path": "./tsconfig.node.json"
+ },
+ {
+ "path": "./tsconfig.app.json"
+ },
+ {
+ "path": "./tsconfig.vitest.json"
+ }
+ ],
+ "compilerOptions": {
+ "module": "NodeNext"
+ }
+}
diff --git a/playground/typescript-jsx-router-pinia-vitest-cypress/tsconfig.node.json b/playground/typescript-jsx-router-pinia-vitest-cypress/tsconfig.node.json
new file mode 100644
index 000000000..f09406303
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-vitest-cypress/tsconfig.node.json
@@ -0,0 +1,19 @@
+{
+ "extends": "@tsconfig/node20/tsconfig.json",
+ "include": [
+ "vite.config.*",
+ "vitest.config.*",
+ "cypress.config.*",
+ "nightwatch.conf.*",
+ "playwright.config.*"
+ ],
+ "compilerOptions": {
+ "composite": true,
+ "noEmit": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
+
+ "module": "ESNext",
+ "moduleResolution": "Bundler",
+ "types": ["node"]
+ }
+}
diff --git a/playground/typescript-jsx-router-pinia-vitest-cypress/tsconfig.vitest.json b/playground/typescript-jsx-router-pinia-vitest-cypress/tsconfig.vitest.json
new file mode 100644
index 000000000..571995d11
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-vitest-cypress/tsconfig.vitest.json
@@ -0,0 +1,11 @@
+{
+ "extends": "./tsconfig.app.json",
+ "exclude": [],
+ "compilerOptions": {
+ "composite": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.vitest.tsbuildinfo",
+
+ "lib": [],
+ "types": ["node", "jsdom"]
+ }
+}
diff --git a/playground/typescript-jsx-router-pinia-vitest-cypress/vite.config.ts b/playground/typescript-jsx-router-pinia-vitest-cypress/vite.config.ts
new file mode 100644
index 000000000..36c618756
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-vitest-cypress/vite.config.ts
@@ -0,0 +1,18 @@
+import { fileURLToPath, URL } from 'node:url'
+
+import { defineConfig } from 'vite'
+import vue from '@vitejs/plugin-vue'
+import vueJsx from '@vitejs/plugin-vue-jsx'
+
+// https://vitejs.dev/config/
+export default defineConfig({
+ plugins: [
+ vue(),
+ vueJsx(),
+ ],
+ resolve: {
+ alias: {
+ '@': fileURLToPath(new URL('./src', import.meta.url))
+ }
+ }
+})
diff --git a/playground/typescript-jsx-router-pinia-vitest-cypress/vitest.config.ts b/playground/typescript-jsx-router-pinia-vitest-cypress/vitest.config.ts
new file mode 100644
index 000000000..10067d578
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-vitest-cypress/vitest.config.ts
@@ -0,0 +1,14 @@
+import { fileURLToPath } from 'node:url'
+import { mergeConfig, defineConfig, configDefaults } from 'vitest/config'
+import viteConfig from './vite.config'
+
+export default mergeConfig(
+ viteConfig,
+ defineConfig({
+ test: {
+ environment: 'jsdom',
+ exclude: [...configDefaults.exclude, 'e2e/*'],
+ root: fileURLToPath(new URL('./', import.meta.url))
+ }
+ })
+)
diff --git a/playground/typescript-jsx-router-pinia-vitest-nightwatch/.gitignore b/playground/typescript-jsx-router-pinia-vitest-nightwatch/.gitignore
new file mode 100644
index 000000000..0b938f131
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-vitest-nightwatch/.gitignore
@@ -0,0 +1,33 @@
+# 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/
+
+# Editor directories and files
+.vscode/*
+!.vscode/extensions.json
+.idea
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?
+
+*.tsbuildinfo
+
+logs/
+tests_output/
diff --git a/playground/typescript-jsx-router-pinia-vitest-nightwatch/.vscode/extensions.json b/playground/typescript-jsx-router-pinia-vitest-nightwatch/.vscode/extensions.json
new file mode 100644
index 000000000..dd9668a5c
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-vitest-nightwatch/.vscode/extensions.json
@@ -0,0 +1,3 @@
+{
+ "recommendations": ["browserstackcom.nightwatch"]
+}
diff --git a/playground/typescript-jsx-router-pinia-vitest-nightwatch/README.md b/playground/typescript-jsx-router-pinia-vitest-nightwatch/README.md
new file mode 100644
index 000000000..256859bfe
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-vitest-nightwatch/README.md
@@ -0,0 +1,69 @@
+# typescript-jsx-router-pinia-vitest-nightwatch
+
+This template should help get you started developing with Vue 3 in Vite.
+
+## Recommended IDE Setup
+
+[VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur) + [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin).
+
+## Type Support for `.vue` Imports in TS
+
+TypeScript cannot handle type information for `.vue` imports by default, so we replace the `tsc` CLI with `vue-tsc` for type checking. In editors, we need [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin) to make the TypeScript language service aware of `.vue` types.
+
+If the standalone TypeScript plugin doesn't feel fast enough to you, Volar has also implemented a [Take Over Mode](https://github.com/johnsoncodehk/volar/discussions/471#discussioncomment-1361669) that is more performant. You can enable it by the following steps:
+
+1. Disable the built-in TypeScript Extension
+ 1) Run `Extensions: Show Built-in Extensions` from VSCode's command palette
+ 2) Find `TypeScript and JavaScript Language Features`, right click and select `Disable (Workspace)`
+2. Reload the VSCode window by running `Developer: Reload Window` from the command palette.
+
+## Customize configuration
+
+See [Vite Configuration Reference](https://vitejs.dev/config/).
+
+## Project Setup
+
+```sh
+pnpm install
+```
+
+### Compile and Hot-Reload for Development
+
+```sh
+pnpm dev
+```
+
+### Type-Check, Compile and Minify for Production
+
+```sh
+pnpm build
+```
+
+### Run Unit Tests with [Vitest](https://vitest.dev/)
+
+```sh
+pnpm test:unit
+```
+
+### Run End-to-End Tests with [Nightwatch](https://nightwatchjs.org/)
+
+```sh
+# When using CI, the project must be built first.
+pnpm build
+
+# Runs the end-to-end tests
+pnpm test:e2e
+# Runs the tests only on Chrome
+pnpm test:e2e --env chrome
+# Runs the tests of a specific file
+pnpm test:e2e tests/e2e/example.ts
+# Runs the tests in debug mode
+pnpm test:e2e --debug
+```
+
+### Run Headed Component Tests with [Nightwatch Component Testing](https://nightwatchjs.org/guide/component-testing/introduction.html)
+
+```sh
+pnpm test:unit
+pnpm test:unit -- --headless # for headless testing
+```
diff --git a/playground/typescript-jsx-router-pinia-vitest-nightwatch/env.d.ts b/playground/typescript-jsx-router-pinia-vitest-nightwatch/env.d.ts
new file mode 100644
index 000000000..11f02fe2a
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-vitest-nightwatch/env.d.ts
@@ -0,0 +1 @@
+///
diff --git a/playground/typescript-jsx-router-pinia-vitest-nightwatch/index.html b/playground/typescript-jsx-router-pinia-vitest-nightwatch/index.html
new file mode 100644
index 000000000..a88854489
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-vitest-nightwatch/index.html
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+ Vite App
+
+
+
+
+
+
diff --git a/playground/typescript-jsx-router-pinia-vitest-nightwatch/nightwatch.conf.cjs b/playground/typescript-jsx-router-pinia-vitest-nightwatch/nightwatch.conf.cjs
new file mode 100644
index 000000000..542647e5e
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-vitest-nightwatch/nightwatch.conf.cjs
@@ -0,0 +1,153 @@
+//
+// Refer to the online docs for more details:
+// https://nightwatchjs.org/guide/configuration/nightwatch-configuration-file.html
+//
+// _ _ _ _ _ _ _
+// | \ | |(_) | | | | | | | |
+// | \| | _ __ _ | |__ | |_ __ __ __ _ | |_ ___ | |__
+// | . ` || | / _` || '_ \ | __|\ \ /\ / / / _` || __| / __|| '_ \
+// | |\ || || (_| || | | || |_ \ V V / | (_| || |_ | (__ | | | |
+// \_| \_/|_| \__, ||_| |_| \__| \_/\_/ \__,_| \__| \___||_| |_|
+// __/ |
+// |___/
+//
+
+module.exports = {
+ // An array of folders (excluding subfolders) where your tests are located;
+ // if this is not specified, the test source must be passed as the second argument to the test runner.
+ src_folders: [],
+
+ // See https://nightwatchjs.org/guide/concepts/page-object-model.html
+ page_objects_path: [],
+
+ // See https://nightwatchjs.org/guide/extending-nightwatch/adding-custom-commands.html
+ custom_commands_path: [],
+
+ // See https://nightwatchjs.org/guide/extending-nightwatch/adding-custom-assertions.html
+ custom_assertions_path: [],
+
+ // See https://nightwatchjs.org/guide/extending-nightwatch/adding-plugins.html
+ plugins: ['@nightwatch/vue'],
+
+ // See https://nightwatchjs.org/guide/concepts/test-globals.html#external-test-globals
+ globals_path: '',
+
+ vite_dev_server: {
+ start_vite: true,
+ port: process.env.CI ? 4173 : 5173
+ },
+
+ webdriver: {},
+
+ test_workers: {
+ enabled: true,
+ workers: 'auto'
+ },
+
+ test_settings: {
+ default: {
+ disable_error_log: false,
+ launch_url: `http://localhost:${process.env.CI ? '4173' : '5173'}`,
+
+ screenshots: {
+ enabled: false,
+ path: 'screens',
+ on_failure: true
+ },
+
+ desiredCapabilities: {
+ browserName: 'firefox'
+ },
+
+ webdriver: {
+ start_process: true,
+ server_path: ''
+ }
+ },
+
+ safari: {
+ desiredCapabilities: {
+ browserName: 'safari',
+ alwaysMatch: {
+ acceptInsecureCerts: false
+ }
+ },
+ webdriver: {
+ start_process: true,
+ server_path: ''
+ }
+ },
+
+ firefox: {
+ desiredCapabilities: {
+ browserName: 'firefox',
+ alwaysMatch: {
+ acceptInsecureCerts: true,
+ 'moz:firefoxOptions': {
+ args: [
+ // '-headless',
+ // '-verbose'
+ ]
+ }
+ }
+ },
+ webdriver: {
+ start_process: true,
+ server_path: '',
+ cli_args: [
+ // very verbose geckodriver logs
+ // '-vv'
+ ]
+ }
+ },
+
+ chrome: {
+ desiredCapabilities: {
+ browserName: 'chrome',
+ 'goog:chromeOptions': {
+ // More info on Chromedriver: https://sites.google.com/a/chromium.org/chromedriver/
+ //
+ // w3c:false tells Chromedriver to run using the legacy JSONWire protocol (not required in Chrome 78)
+ w3c: true,
+ args: [
+ //'--no-sandbox',
+ //'--ignore-certificate-errors',
+ //'--allow-insecure-localhost',
+ //'--headless'
+ ]
+ }
+ },
+
+ webdriver: {
+ start_process: true,
+ server_path: '',
+ cli_args: [
+ // --verbose
+ ]
+ }
+ },
+
+ edge: {
+ desiredCapabilities: {
+ browserName: 'MicrosoftEdge',
+ 'ms:edgeOptions': {
+ w3c: true,
+ // More info on EdgeDriver: https://docs.microsoft.com/en-us/microsoft-edge/webdriver-chromium/capabilities-edge-options
+ args: [
+ //'--headless'
+ ]
+ }
+ },
+
+ webdriver: {
+ start_process: true,
+ // Download msedgedriver from https://docs.microsoft.com/en-us/microsoft-edge/webdriver-chromium/
+ // and set the location below:
+ server_path: '',
+ cli_args: [
+ // --verbose
+ ]
+ }
+ }
+ }
+}
diff --git a/playground/typescript-jsx-router-pinia-vitest-nightwatch/nightwatch/nightwatch.d.ts b/playground/typescript-jsx-router-pinia-vitest-nightwatch/nightwatch/nightwatch.d.ts
new file mode 100644
index 000000000..616e63f9f
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-vitest-nightwatch/nightwatch/nightwatch.d.ts
@@ -0,0 +1,13 @@
+import { NightwatchCustomAssertions, NightwatchCustomCommands } from 'nightwatch'
+
+declare module 'nightwatch' {
+ interface NightwatchCustomAssertions {
+ // Add your custom assertions' types here
+ // elementHasCount: (selector: string, count: number) => NightwatchBrowser
+ }
+
+ interface NightwatchCustomCommands {
+ // Add your custom commands' types here
+ // strictClick: (selector: string) => NightwatchBrowser
+ }
+}
diff --git a/playground/typescript-jsx-router-pinia-vitest-nightwatch/nightwatch/tsconfig.json b/playground/typescript-jsx-router-pinia-vitest-nightwatch/nightwatch/tsconfig.json
new file mode 100644
index 000000000..8cd7ca1da
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-vitest-nightwatch/nightwatch/tsconfig.json
@@ -0,0 +1,20 @@
+{
+ "extends": "@tsconfig/node20/tsconfig.json",
+ "compilerOptions": {
+ "composite": true,
+ "noEmit": true,
+ "tsBuildInfoFile": "../node_modules/.tmp/tsconfig.nightwatch.tsbuildinfo",
+
+ "target": "ESNext",
+ "module": "commonjs",
+ "moduleResolution": "node",
+ "rootDir": "../",
+ "lib": ["ESNext", "dom"],
+ "types": ["nightwatch"]
+ },
+ "include": ["../node_modules/@nightwatch/**/*", "../src/components/**/*", "../tests/e2e/**/*"],
+ "ts-node": {
+ "transpileOnly": true
+ },
+ "files": ["nightwatch.d.ts"]
+}
diff --git a/playground/typescript-jsx-router-pinia-vitest-nightwatch/package.json b/playground/typescript-jsx-router-pinia-vitest-nightwatch/package.json
new file mode 100644
index 000000000..59f3d45dc
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-vitest-nightwatch/package.json
@@ -0,0 +1,41 @@
+{
+ "name": "typescript-jsx-router-pinia-vitest-nightwatch",
+ "version": "0.0.0",
+ "private": true,
+ "type": "module",
+ "scripts": {
+ "dev": "vite",
+ "build": "run-p type-check \"build-only {@}\" --",
+ "preview": "vite preview",
+ "test:unit": "vitest",
+ "test:e2e": "nightwatch tests/e2e/*",
+ "build-only": "vite build",
+ "type-check": "vue-tsc --build --force"
+ },
+ "dependencies": {
+ "pinia": "^2.1.7",
+ "vue": "^3.4.15",
+ "vue-router": "^4.2.5"
+ },
+ "devDependencies": {
+ "@nightwatch/vue": "^3.1.0",
+ "@tsconfig/node20": "^20.1.2",
+ "@types/jsdom": "^21.1.6",
+ "@types/node": "^20.11.16",
+ "@vitejs/plugin-vue": "^5.0.3",
+ "@vitejs/plugin-vue-jsx": "^3.1.0",
+ "@vue/test-utils": "^2.4.4",
+ "@vue/tsconfig": "^0.5.1",
+ "chromedriver": "^121.0.0",
+ "geckodriver": "^4.3.2",
+ "jsdom": "^24.0.0",
+ "nightwatch": "^3.4.0",
+ "npm-run-all2": "^6.1.2",
+ "ts-node": "^10.9.2",
+ "typescript": "~5.3.0",
+ "vite": "^5.0.11",
+ "vite-plugin-nightwatch": "^0.4.6",
+ "vitest": "^1.2.2",
+ "vue-tsc": "^1.8.27"
+ }
+}
diff --git a/playground/typescript-jsx-router-pinia-vitest-nightwatch/public/favicon.ico b/playground/typescript-jsx-router-pinia-vitest-nightwatch/public/favicon.ico
new file mode 100644
index 000000000..df36fcfb7
Binary files /dev/null and b/playground/typescript-jsx-router-pinia-vitest-nightwatch/public/favicon.ico differ
diff --git a/playground/typescript-jsx-router-pinia-vitest-nightwatch/src/App.vue b/playground/typescript-jsx-router-pinia-vitest-nightwatch/src/App.vue
new file mode 100644
index 000000000..7905b0516
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-vitest-nightwatch/src/App.vue
@@ -0,0 +1,85 @@
+
+
+
+
+
+
+
+ You’ve successfully created a project with
+ Vite +
+ Vue 3. What's next?
+
+
+
+
+
diff --git a/playground/typescript-jsx-router-pinia-vitest-nightwatch/src/components/TheWelcome.vue b/playground/typescript-jsx-router-pinia-vitest-nightwatch/src/components/TheWelcome.vue
new file mode 100644
index 000000000..49d8f7354
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-vitest-nightwatch/src/components/TheWelcome.vue
@@ -0,0 +1,88 @@
+
+
+
+
+
+
+
+ Documentation
+
+ Vue’s
+ official documentation
+ provides you with all information you need to get started.
+
+
+
+
+
+
+ Tooling
+
+ This project is served and bundled with
+ Vite. The
+ recommended IDE setup is
+ VSCode +
+ Volar. If
+ you need to test your components and web pages, check out
+ Cypress and
+ Cypress Component Testing.
+
+
+
+ More instructions are available in README.md.
+
+
+
+
+
+
+ Ecosystem
+
+ Get official tools and libraries for your project:
+ Pinia,
+ Vue Router,
+ Vue Test Utils, and
+ Vue Dev Tools. If
+ you need more resources, we suggest paying
+ Awesome Vue
+ a visit.
+
+
+
+
+
+
+ Community
+
+ Got stuck? Ask your question on
+ Vue Land, our official
+ Discord server, or
+ StackOverflow. You should also subscribe to
+ our mailing list and follow
+ the official
+ @vuejs
+ twitter account for latest news in the Vue world.
+
+
+
+
+
+
+ Support Vue
+
+ As an independent project, Vue relies on community backing for its sustainability. You can help
+ us by
+ becoming a sponsor.
+
+
diff --git a/playground/typescript-jsx-router-pinia-vitest-nightwatch/src/components/WelcomeItem.vue b/playground/typescript-jsx-router-pinia-vitest-nightwatch/src/components/WelcomeItem.vue
new file mode 100644
index 000000000..6d7086aea
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-vitest-nightwatch/src/components/WelcomeItem.vue
@@ -0,0 +1,87 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/playground/typescript-jsx-router-pinia-vitest-nightwatch/src/components/__tests__/HelloWorld.spec.ts b/playground/typescript-jsx-router-pinia-vitest-nightwatch/src/components/__tests__/HelloWorld.spec.ts
new file mode 100644
index 000000000..253320200
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-vitest-nightwatch/src/components/__tests__/HelloWorld.spec.ts
@@ -0,0 +1,11 @@
+import { describe, it, expect } from 'vitest'
+
+import { mount } from '@vue/test-utils'
+import HelloWorld from '../HelloWorld.vue'
+
+describe('HelloWorld', () => {
+ it('renders properly', () => {
+ const wrapper = mount(HelloWorld, { props: { msg: 'Hello Vitest' } })
+ expect(wrapper.text()).toContain('Hello Vitest')
+ })
+})
diff --git a/playground/typescript-jsx-router-pinia-vitest-nightwatch/src/components/icons/IconCommunity.vue b/playground/typescript-jsx-router-pinia-vitest-nightwatch/src/components/icons/IconCommunity.vue
new file mode 100644
index 000000000..2dc8b0552
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-vitest-nightwatch/src/components/icons/IconCommunity.vue
@@ -0,0 +1,7 @@
+
+
+
diff --git a/playground/typescript-jsx-router-pinia-vitest-nightwatch/src/components/icons/IconDocumentation.vue b/playground/typescript-jsx-router-pinia-vitest-nightwatch/src/components/icons/IconDocumentation.vue
new file mode 100644
index 000000000..6d4791cfb
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-vitest-nightwatch/src/components/icons/IconDocumentation.vue
@@ -0,0 +1,7 @@
+
+
+
diff --git a/playground/typescript-jsx-router-pinia-vitest-nightwatch/src/components/icons/IconEcosystem.vue b/playground/typescript-jsx-router-pinia-vitest-nightwatch/src/components/icons/IconEcosystem.vue
new file mode 100644
index 000000000..c3a4f078c
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-vitest-nightwatch/src/components/icons/IconEcosystem.vue
@@ -0,0 +1,7 @@
+
+
+
diff --git a/playground/typescript-jsx-router-pinia-vitest-nightwatch/src/components/icons/IconSupport.vue b/playground/typescript-jsx-router-pinia-vitest-nightwatch/src/components/icons/IconSupport.vue
new file mode 100644
index 000000000..7452834d3
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-vitest-nightwatch/src/components/icons/IconSupport.vue
@@ -0,0 +1,7 @@
+
+
+
diff --git a/playground/typescript-jsx-router-pinia-vitest-nightwatch/src/components/icons/IconTooling.vue b/playground/typescript-jsx-router-pinia-vitest-nightwatch/src/components/icons/IconTooling.vue
new file mode 100644
index 000000000..660598d7c
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-vitest-nightwatch/src/components/icons/IconTooling.vue
@@ -0,0 +1,19 @@
+
+
+
+
diff --git a/playground/typescript-jsx-router-pinia-vitest-nightwatch/src/main.ts b/playground/typescript-jsx-router-pinia-vitest-nightwatch/src/main.ts
new file mode 100644
index 000000000..5dcad83c3
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-vitest-nightwatch/src/main.ts
@@ -0,0 +1,14 @@
+import './assets/main.css'
+
+import { createApp } from 'vue'
+import { createPinia } from 'pinia'
+
+import App from './App.vue'
+import router from './router'
+
+const app = createApp(App)
+
+app.use(createPinia())
+app.use(router)
+
+app.mount('#app')
diff --git a/playground/typescript-jsx-router-pinia-vitest-nightwatch/src/router/index.ts b/playground/typescript-jsx-router-pinia-vitest-nightwatch/src/router/index.ts
new file mode 100644
index 000000000..a49ae507f
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-vitest-nightwatch/src/router/index.ts
@@ -0,0 +1,23 @@
+import { createRouter, createWebHistory } from 'vue-router'
+import HomeView from '../views/HomeView.vue'
+
+const router = createRouter({
+ history: createWebHistory(import.meta.env.BASE_URL),
+ routes: [
+ {
+ path: '/',
+ name: 'home',
+ component: HomeView
+ },
+ {
+ path: '/about',
+ name: 'about',
+ // route level code-splitting
+ // this generates a separate chunk (About.[hash].js) for this route
+ // which is lazy-loaded when the route is visited.
+ component: () => import('../views/AboutView.vue')
+ }
+ ]
+})
+
+export default router
diff --git a/playground/typescript-jsx-router-pinia-vitest-nightwatch/src/stores/counter.ts b/playground/typescript-jsx-router-pinia-vitest-nightwatch/src/stores/counter.ts
new file mode 100644
index 000000000..b6757ba57
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-vitest-nightwatch/src/stores/counter.ts
@@ -0,0 +1,12 @@
+import { ref, computed } from 'vue'
+import { defineStore } from 'pinia'
+
+export const useCounterStore = defineStore('counter', () => {
+ const count = ref(0)
+ const doubleCount = computed(() => count.value * 2)
+ function increment() {
+ count.value++
+ }
+
+ return { count, doubleCount, increment }
+})
diff --git a/playground/typescript-jsx-router-pinia-vitest-nightwatch/src/views/AboutView.vue b/playground/typescript-jsx-router-pinia-vitest-nightwatch/src/views/AboutView.vue
new file mode 100644
index 000000000..756ad2a17
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-vitest-nightwatch/src/views/AboutView.vue
@@ -0,0 +1,15 @@
+
+
+
This is an about page
+
+
+
+
diff --git a/playground/typescript-jsx-router-pinia-vitest-nightwatch/src/views/HomeView.vue b/playground/typescript-jsx-router-pinia-vitest-nightwatch/src/views/HomeView.vue
new file mode 100644
index 000000000..d5c0217e4
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-vitest-nightwatch/src/views/HomeView.vue
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
diff --git a/playground/typescript-jsx-router-pinia-vitest-nightwatch/tests/e2e/example.ts b/playground/typescript-jsx-router-pinia-vitest-nightwatch/tests/e2e/example.ts
new file mode 100644
index 000000000..43be3fce1
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-vitest-nightwatch/tests/e2e/example.ts
@@ -0,0 +1,11 @@
+describe('My First Test', function () {
+ before((browser) => {
+ browser.init()
+ })
+
+ it('visits the app root url', function () {
+ browser.assert.textContains('.green', 'You did it!')
+ })
+
+ after((browser) => browser.end())
+})
diff --git a/playground/typescript-jsx-router-pinia-vitest-nightwatch/tsconfig.app.json b/playground/typescript-jsx-router-pinia-vitest-nightwatch/tsconfig.app.json
new file mode 100644
index 000000000..e14c754d3
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-vitest-nightwatch/tsconfig.app.json
@@ -0,0 +1,14 @@
+{
+ "extends": "@vue/tsconfig/tsconfig.dom.json",
+ "include": ["env.d.ts", "src/**/*", "src/**/*.vue"],
+ "exclude": ["src/**/__tests__/*"],
+ "compilerOptions": {
+ "composite": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
+
+ "baseUrl": ".",
+ "paths": {
+ "@/*": ["./src/*"]
+ }
+ }
+}
diff --git a/playground/typescript-jsx-router-pinia-vitest-nightwatch/tsconfig.json b/playground/typescript-jsx-router-pinia-vitest-nightwatch/tsconfig.json
new file mode 100644
index 000000000..a5352e667
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-vitest-nightwatch/tsconfig.json
@@ -0,0 +1,17 @@
+{
+ "files": [],
+ "references": [
+ {
+ "path": "./tsconfig.node.json"
+ },
+ {
+ "path": "./tsconfig.app.json"
+ },
+ {
+ "path": "./tsconfig.vitest.json"
+ },
+ {
+ "path": "./nightwatch/tsconfig.json"
+ }
+ ]
+}
diff --git a/playground/typescript-jsx-router-pinia-vitest-nightwatch/tsconfig.node.json b/playground/typescript-jsx-router-pinia-vitest-nightwatch/tsconfig.node.json
new file mode 100644
index 000000000..f09406303
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-vitest-nightwatch/tsconfig.node.json
@@ -0,0 +1,19 @@
+{
+ "extends": "@tsconfig/node20/tsconfig.json",
+ "include": [
+ "vite.config.*",
+ "vitest.config.*",
+ "cypress.config.*",
+ "nightwatch.conf.*",
+ "playwright.config.*"
+ ],
+ "compilerOptions": {
+ "composite": true,
+ "noEmit": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
+
+ "module": "ESNext",
+ "moduleResolution": "Bundler",
+ "types": ["node"]
+ }
+}
diff --git a/playground/typescript-jsx-router-pinia-vitest-nightwatch/tsconfig.vitest.json b/playground/typescript-jsx-router-pinia-vitest-nightwatch/tsconfig.vitest.json
new file mode 100644
index 000000000..571995d11
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-vitest-nightwatch/tsconfig.vitest.json
@@ -0,0 +1,11 @@
+{
+ "extends": "./tsconfig.app.json",
+ "exclude": [],
+ "compilerOptions": {
+ "composite": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.vitest.tsbuildinfo",
+
+ "lib": [],
+ "types": ["node", "jsdom"]
+ }
+}
diff --git a/playground/typescript-jsx-router-pinia-vitest-nightwatch/vite.config.ts b/playground/typescript-jsx-router-pinia-vitest-nightwatch/vite.config.ts
new file mode 100644
index 000000000..3a6988230
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-vitest-nightwatch/vite.config.ts
@@ -0,0 +1,20 @@
+import { fileURLToPath, URL } from 'node:url'
+
+import { defineConfig } from 'vite'
+import vue from '@vitejs/plugin-vue'
+import vueJsx from '@vitejs/plugin-vue-jsx'
+import nightwatchPlugin from 'vite-plugin-nightwatch'
+
+// https://vitejs.dev/config/
+export default defineConfig({
+ plugins: [
+ vue(),
+ vueJsx(),
+ nightwatchPlugin(),
+ ],
+ resolve: {
+ alias: {
+ '@': fileURLToPath(new URL('./src', import.meta.url))
+ }
+ }
+})
diff --git a/playground/typescript-jsx-router-pinia-vitest-nightwatch/vitest.config.ts b/playground/typescript-jsx-router-pinia-vitest-nightwatch/vitest.config.ts
new file mode 100644
index 000000000..10067d578
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-vitest-nightwatch/vitest.config.ts
@@ -0,0 +1,14 @@
+import { fileURLToPath } from 'node:url'
+import { mergeConfig, defineConfig, configDefaults } from 'vitest/config'
+import viteConfig from './vite.config'
+
+export default mergeConfig(
+ viteConfig,
+ defineConfig({
+ test: {
+ environment: 'jsdom',
+ exclude: [...configDefaults.exclude, 'e2e/*'],
+ root: fileURLToPath(new URL('./', import.meta.url))
+ }
+ })
+)
diff --git a/playground/typescript-jsx-router-pinia-vitest-playwright/.gitignore b/playground/typescript-jsx-router-pinia-vitest-playwright/.gitignore
new file mode 100644
index 000000000..aef72d03c
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-vitest-playwright/.gitignore
@@ -0,0 +1,33 @@
+# 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/
+
+# Editor directories and files
+.vscode/*
+!.vscode/extensions.json
+.idea
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?
+
+*.tsbuildinfo
+
+test-results/
+playwright-report/
diff --git a/playground/typescript-jsx-router-pinia-vitest-playwright/.vscode/extensions.json b/playground/typescript-jsx-router-pinia-vitest-playwright/.vscode/extensions.json
new file mode 100644
index 000000000..7b3f8bdae
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-vitest-playwright/.vscode/extensions.json
@@ -0,0 +1,3 @@
+{
+ "recommendations": ["ms-playwright.playwright"]
+}
diff --git a/playground/typescript-jsx-router-pinia-vitest-playwright/README.md b/playground/typescript-jsx-router-pinia-vitest-playwright/README.md
new file mode 100644
index 000000000..e4650e499
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-vitest-playwright/README.md
@@ -0,0 +1,65 @@
+# typescript-jsx-router-pinia-vitest-playwright
+
+This template should help get you started developing with Vue 3 in Vite.
+
+## Recommended IDE Setup
+
+[VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur) + [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin).
+
+## Type Support for `.vue` Imports in TS
+
+TypeScript cannot handle type information for `.vue` imports by default, so we replace the `tsc` CLI with `vue-tsc` for type checking. In editors, we need [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin) to make the TypeScript language service aware of `.vue` types.
+
+If the standalone TypeScript plugin doesn't feel fast enough to you, Volar has also implemented a [Take Over Mode](https://github.com/johnsoncodehk/volar/discussions/471#discussioncomment-1361669) that is more performant. You can enable it by the following steps:
+
+1. Disable the built-in TypeScript Extension
+ 1) Run `Extensions: Show Built-in Extensions` from VSCode's command palette
+ 2) Find `TypeScript and JavaScript Language Features`, right click and select `Disable (Workspace)`
+2. Reload the VSCode window by running `Developer: Reload Window` from the command palette.
+
+## Customize configuration
+
+See [Vite Configuration Reference](https://vitejs.dev/config/).
+
+## Project Setup
+
+```sh
+pnpm install
+```
+
+### Compile and Hot-Reload for Development
+
+```sh
+pnpm dev
+```
+
+### Type-Check, Compile and Minify for Production
+
+```sh
+pnpm build
+```
+
+### Run Unit Tests with [Vitest](https://vitest.dev/)
+
+```sh
+pnpm test:unit
+```
+
+### Run End-to-End Tests with [Playwright](https://playwright.dev)
+
+```sh
+# Install browsers for the first run
+npx playwright install
+
+# When testing on CI, must build the project first
+pnpm build
+
+# Runs the end-to-end tests
+pnpm test:e2e
+# Runs the tests only on Chromium
+pnpm test:e2e --project=chromium
+# Runs the tests of a specific file
+pnpm test:e2e tests/example.spec.ts
+# Runs the tests in debug mode
+pnpm test:e2e --debug
+```
diff --git a/playground/typescript-jsx-router-pinia-vitest-playwright/e2e/tsconfig.json b/playground/typescript-jsx-router-pinia-vitest-playwright/e2e/tsconfig.json
new file mode 100644
index 000000000..be3bbfc0e
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-vitest-playwright/e2e/tsconfig.json
@@ -0,0 +1,4 @@
+{
+ "extends": "@tsconfig/node20/tsconfig.json",
+ "include": ["./**/*"]
+}
diff --git a/playground/typescript-jsx-router-pinia-vitest-playwright/e2e/vue.spec.ts b/playground/typescript-jsx-router-pinia-vitest-playwright/e2e/vue.spec.ts
new file mode 100644
index 000000000..3e5a3d02d
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-vitest-playwright/e2e/vue.spec.ts
@@ -0,0 +1,8 @@
+import { test, expect } from '@playwright/test';
+
+// See here how to get started:
+// https://playwright.dev/docs/intro
+test('visits the app root url', async ({ page }) => {
+ await page.goto('/');
+ await expect(page.locator('div.greetings > h1')).toHaveText('You did it!');
+})
diff --git a/playground/typescript-jsx-router-pinia-vitest-playwright/env.d.ts b/playground/typescript-jsx-router-pinia-vitest-playwright/env.d.ts
new file mode 100644
index 000000000..11f02fe2a
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-vitest-playwright/env.d.ts
@@ -0,0 +1 @@
+///
diff --git a/playground/typescript-jsx-router-pinia-vitest-playwright/index.html b/playground/typescript-jsx-router-pinia-vitest-playwright/index.html
new file mode 100644
index 000000000..a88854489
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-vitest-playwright/index.html
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+ Vite App
+
+
+
+
+
+
diff --git a/playground/typescript-jsx-router-pinia-vitest-playwright/package.json b/playground/typescript-jsx-router-pinia-vitest-playwright/package.json
new file mode 100644
index 000000000..d3e765479
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-vitest-playwright/package.json
@@ -0,0 +1,36 @@
+{
+ "name": "typescript-jsx-router-pinia-vitest-playwright",
+ "version": "0.0.0",
+ "private": true,
+ "type": "module",
+ "scripts": {
+ "dev": "vite",
+ "build": "run-p type-check \"build-only {@}\" --",
+ "preview": "vite preview",
+ "test:unit": "vitest",
+ "test:e2e": "playwright test",
+ "build-only": "vite build",
+ "type-check": "vue-tsc --build --force"
+ },
+ "dependencies": {
+ "pinia": "^2.1.7",
+ "vue": "^3.4.15",
+ "vue-router": "^4.2.5"
+ },
+ "devDependencies": {
+ "@playwright/test": "^1.41.2",
+ "@tsconfig/node20": "^20.1.2",
+ "@types/jsdom": "^21.1.6",
+ "@types/node": "^20.11.16",
+ "@vitejs/plugin-vue": "^5.0.3",
+ "@vitejs/plugin-vue-jsx": "^3.1.0",
+ "@vue/test-utils": "^2.4.4",
+ "@vue/tsconfig": "^0.5.1",
+ "jsdom": "^24.0.0",
+ "npm-run-all2": "^6.1.2",
+ "typescript": "~5.3.0",
+ "vite": "^5.0.11",
+ "vitest": "^1.2.2",
+ "vue-tsc": "^1.8.27"
+ }
+}
diff --git a/playground/typescript-jsx-router-pinia-vitest-playwright/playwright.config.ts b/playground/typescript-jsx-router-pinia-vitest-playwright/playwright.config.ts
new file mode 100644
index 000000000..92075cc1b
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-vitest-playwright/playwright.config.ts
@@ -0,0 +1,110 @@
+import process from 'node:process'
+import { defineConfig, devices } from '@playwright/test'
+
+/**
+ * Read environment variables from file.
+ * https://github.com/motdotla/dotenv
+ */
+// require('dotenv').config();
+
+/**
+ * See https://playwright.dev/docs/test-configuration.
+ */
+export default defineConfig({
+ testDir: './e2e',
+ /* Maximum time one test can run for. */
+ timeout: 30 * 1000,
+ expect: {
+ /**
+ * Maximum time expect() should wait for the condition to be met.
+ * For example in `await expect(locator).toHaveText();`
+ */
+ timeout: 5000
+ },
+ /* Fail the build on CI if you accidentally left test.only in the source code. */
+ forbidOnly: !!process.env.CI,
+ /* Retry on CI only */
+ retries: process.env.CI ? 2 : 0,
+ /* Opt out of parallel tests on CI. */
+ workers: process.env.CI ? 1 : undefined,
+ /* Reporter to use. See https://playwright.dev/docs/test-reporters */
+ reporter: 'html',
+ /* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
+ use: {
+ /* Maximum time each action such as `click()` can take. Defaults to 0 (no limit). */
+ actionTimeout: 0,
+ /* Base URL to use in actions like `await page.goto('/')`. */
+ baseURL: 'http://localhost:5173',
+
+ /* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
+ trace: 'on-first-retry',
+
+ /* Only on CI systems run the tests headless */
+ headless: !!process.env.CI
+ },
+
+ /* Configure projects for major browsers */
+ projects: [
+ {
+ name: 'chromium',
+ use: {
+ ...devices['Desktop Chrome']
+ }
+ },
+ {
+ name: 'firefox',
+ use: {
+ ...devices['Desktop Firefox']
+ }
+ },
+ {
+ name: 'webkit',
+ use: {
+ ...devices['Desktop Safari']
+ }
+ }
+
+ /* Test against mobile viewports. */
+ // {
+ // name: 'Mobile Chrome',
+ // use: {
+ // ...devices['Pixel 5'],
+ // },
+ // },
+ // {
+ // name: 'Mobile Safari',
+ // use: {
+ // ...devices['iPhone 12'],
+ // },
+ // },
+
+ /* Test against branded browsers. */
+ // {
+ // name: 'Microsoft Edge',
+ // use: {
+ // channel: 'msedge',
+ // },
+ // },
+ // {
+ // name: 'Google Chrome',
+ // use: {
+ // channel: 'chrome',
+ // },
+ // },
+ ],
+
+ /* Folder for test artifacts such as screenshots, videos, traces, etc. */
+ // outputDir: 'test-results/',
+
+ /* Run your local dev server before starting the tests */
+ webServer: {
+ /**
+ * Use the dev server by default for faster feedback loop.
+ * Use the preview server on CI for more realistic testing.
+ * Playwright will re-use the local server if there is already a dev-server running.
+ */
+ command: process.env.CI ? 'vite preview --port 5173' : 'vite dev',
+ port: 5173,
+ reuseExistingServer: !process.env.CI
+ }
+})
diff --git a/playground/typescript-jsx-router-pinia-vitest-playwright/public/favicon.ico b/playground/typescript-jsx-router-pinia-vitest-playwright/public/favicon.ico
new file mode 100644
index 000000000..df36fcfb7
Binary files /dev/null and b/playground/typescript-jsx-router-pinia-vitest-playwright/public/favicon.ico differ
diff --git a/playground/typescript-jsx-router-pinia-vitest-playwright/src/App.vue b/playground/typescript-jsx-router-pinia-vitest-playwright/src/App.vue
new file mode 100644
index 000000000..7905b0516
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-vitest-playwright/src/App.vue
@@ -0,0 +1,85 @@
+
+
+
+
+
+
+
+ You’ve successfully created a project with
+ Vite +
+ Vue 3. What's next?
+
+
+
+
+
diff --git a/playground/typescript-jsx-router-pinia-vitest-playwright/src/components/TheWelcome.vue b/playground/typescript-jsx-router-pinia-vitest-playwright/src/components/TheWelcome.vue
new file mode 100644
index 000000000..49d8f7354
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-vitest-playwright/src/components/TheWelcome.vue
@@ -0,0 +1,88 @@
+
+
+
+
+
+
+
+ Documentation
+
+ Vue’s
+ official documentation
+ provides you with all information you need to get started.
+
+
+
+
+
+
+ Tooling
+
+ This project is served and bundled with
+ Vite. The
+ recommended IDE setup is
+ VSCode +
+ Volar. If
+ you need to test your components and web pages, check out
+ Cypress and
+ Cypress Component Testing.
+
+
+
+ More instructions are available in README.md.
+
+
+
+
+
+
+ Ecosystem
+
+ Get official tools and libraries for your project:
+ Pinia,
+ Vue Router,
+ Vue Test Utils, and
+ Vue Dev Tools. If
+ you need more resources, we suggest paying
+ Awesome Vue
+ a visit.
+
+
+
+
+
+
+ Community
+
+ Got stuck? Ask your question on
+ Vue Land, our official
+ Discord server, or
+ StackOverflow. You should also subscribe to
+ our mailing list and follow
+ the official
+ @vuejs
+ twitter account for latest news in the Vue world.
+
+
+
+
+
+
+ Support Vue
+
+ As an independent project, Vue relies on community backing for its sustainability. You can help
+ us by
+ becoming a sponsor.
+
+
diff --git a/playground/typescript-jsx-router-pinia-vitest-playwright/src/components/WelcomeItem.vue b/playground/typescript-jsx-router-pinia-vitest-playwright/src/components/WelcomeItem.vue
new file mode 100644
index 000000000..6d7086aea
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-vitest-playwright/src/components/WelcomeItem.vue
@@ -0,0 +1,87 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/playground/typescript-jsx-router-pinia-vitest-playwright/src/components/__tests__/HelloWorld.spec.ts b/playground/typescript-jsx-router-pinia-vitest-playwright/src/components/__tests__/HelloWorld.spec.ts
new file mode 100644
index 000000000..253320200
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-vitest-playwright/src/components/__tests__/HelloWorld.spec.ts
@@ -0,0 +1,11 @@
+import { describe, it, expect } from 'vitest'
+
+import { mount } from '@vue/test-utils'
+import HelloWorld from '../HelloWorld.vue'
+
+describe('HelloWorld', () => {
+ it('renders properly', () => {
+ const wrapper = mount(HelloWorld, { props: { msg: 'Hello Vitest' } })
+ expect(wrapper.text()).toContain('Hello Vitest')
+ })
+})
diff --git a/playground/typescript-jsx-router-pinia-vitest-playwright/src/components/icons/IconCommunity.vue b/playground/typescript-jsx-router-pinia-vitest-playwright/src/components/icons/IconCommunity.vue
new file mode 100644
index 000000000..2dc8b0552
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-vitest-playwright/src/components/icons/IconCommunity.vue
@@ -0,0 +1,7 @@
+
+
+
diff --git a/playground/typescript-jsx-router-pinia-vitest-playwright/src/components/icons/IconDocumentation.vue b/playground/typescript-jsx-router-pinia-vitest-playwright/src/components/icons/IconDocumentation.vue
new file mode 100644
index 000000000..6d4791cfb
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-vitest-playwright/src/components/icons/IconDocumentation.vue
@@ -0,0 +1,7 @@
+
+
+
diff --git a/playground/typescript-jsx-router-pinia-vitest-playwright/src/components/icons/IconEcosystem.vue b/playground/typescript-jsx-router-pinia-vitest-playwright/src/components/icons/IconEcosystem.vue
new file mode 100644
index 000000000..c3a4f078c
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-vitest-playwright/src/components/icons/IconEcosystem.vue
@@ -0,0 +1,7 @@
+
+
+
diff --git a/playground/typescript-jsx-router-pinia-vitest-playwright/src/components/icons/IconSupport.vue b/playground/typescript-jsx-router-pinia-vitest-playwright/src/components/icons/IconSupport.vue
new file mode 100644
index 000000000..7452834d3
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-vitest-playwright/src/components/icons/IconSupport.vue
@@ -0,0 +1,7 @@
+
+
+
diff --git a/playground/typescript-jsx-router-pinia-vitest-playwright/src/components/icons/IconTooling.vue b/playground/typescript-jsx-router-pinia-vitest-playwright/src/components/icons/IconTooling.vue
new file mode 100644
index 000000000..660598d7c
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-vitest-playwright/src/components/icons/IconTooling.vue
@@ -0,0 +1,19 @@
+
+
+
+
diff --git a/playground/typescript-jsx-router-pinia-vitest-playwright/src/main.ts b/playground/typescript-jsx-router-pinia-vitest-playwright/src/main.ts
new file mode 100644
index 000000000..5dcad83c3
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-vitest-playwright/src/main.ts
@@ -0,0 +1,14 @@
+import './assets/main.css'
+
+import { createApp } from 'vue'
+import { createPinia } from 'pinia'
+
+import App from './App.vue'
+import router from './router'
+
+const app = createApp(App)
+
+app.use(createPinia())
+app.use(router)
+
+app.mount('#app')
diff --git a/playground/typescript-jsx-router-pinia-vitest-playwright/src/router/index.ts b/playground/typescript-jsx-router-pinia-vitest-playwright/src/router/index.ts
new file mode 100644
index 000000000..a49ae507f
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-vitest-playwright/src/router/index.ts
@@ -0,0 +1,23 @@
+import { createRouter, createWebHistory } from 'vue-router'
+import HomeView from '../views/HomeView.vue'
+
+const router = createRouter({
+ history: createWebHistory(import.meta.env.BASE_URL),
+ routes: [
+ {
+ path: '/',
+ name: 'home',
+ component: HomeView
+ },
+ {
+ path: '/about',
+ name: 'about',
+ // route level code-splitting
+ // this generates a separate chunk (About.[hash].js) for this route
+ // which is lazy-loaded when the route is visited.
+ component: () => import('../views/AboutView.vue')
+ }
+ ]
+})
+
+export default router
diff --git a/playground/typescript-jsx-router-pinia-vitest-playwright/src/stores/counter.ts b/playground/typescript-jsx-router-pinia-vitest-playwright/src/stores/counter.ts
new file mode 100644
index 000000000..b6757ba57
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-vitest-playwright/src/stores/counter.ts
@@ -0,0 +1,12 @@
+import { ref, computed } from 'vue'
+import { defineStore } from 'pinia'
+
+export const useCounterStore = defineStore('counter', () => {
+ const count = ref(0)
+ const doubleCount = computed(() => count.value * 2)
+ function increment() {
+ count.value++
+ }
+
+ return { count, doubleCount, increment }
+})
diff --git a/playground/typescript-jsx-router-pinia-vitest-playwright/src/views/AboutView.vue b/playground/typescript-jsx-router-pinia-vitest-playwright/src/views/AboutView.vue
new file mode 100644
index 000000000..756ad2a17
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-vitest-playwright/src/views/AboutView.vue
@@ -0,0 +1,15 @@
+
+
+
This is an about page
+
+
+
+
diff --git a/playground/typescript-jsx-router-pinia-vitest-playwright/src/views/HomeView.vue b/playground/typescript-jsx-router-pinia-vitest-playwright/src/views/HomeView.vue
new file mode 100644
index 000000000..d5c0217e4
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-vitest-playwright/src/views/HomeView.vue
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
diff --git a/playground/typescript-jsx-router-pinia-vitest-playwright/tsconfig.app.json b/playground/typescript-jsx-router-pinia-vitest-playwright/tsconfig.app.json
new file mode 100644
index 000000000..e14c754d3
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-vitest-playwright/tsconfig.app.json
@@ -0,0 +1,14 @@
+{
+ "extends": "@vue/tsconfig/tsconfig.dom.json",
+ "include": ["env.d.ts", "src/**/*", "src/**/*.vue"],
+ "exclude": ["src/**/__tests__/*"],
+ "compilerOptions": {
+ "composite": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
+
+ "baseUrl": ".",
+ "paths": {
+ "@/*": ["./src/*"]
+ }
+ }
+}
diff --git a/playground/typescript-jsx-router-pinia-vitest-playwright/tsconfig.json b/playground/typescript-jsx-router-pinia-vitest-playwright/tsconfig.json
new file mode 100644
index 000000000..100cf6a8f
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-vitest-playwright/tsconfig.json
@@ -0,0 +1,14 @@
+{
+ "files": [],
+ "references": [
+ {
+ "path": "./tsconfig.node.json"
+ },
+ {
+ "path": "./tsconfig.app.json"
+ },
+ {
+ "path": "./tsconfig.vitest.json"
+ }
+ ]
+}
diff --git a/playground/typescript-jsx-router-pinia-vitest-playwright/tsconfig.node.json b/playground/typescript-jsx-router-pinia-vitest-playwright/tsconfig.node.json
new file mode 100644
index 000000000..f09406303
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-vitest-playwright/tsconfig.node.json
@@ -0,0 +1,19 @@
+{
+ "extends": "@tsconfig/node20/tsconfig.json",
+ "include": [
+ "vite.config.*",
+ "vitest.config.*",
+ "cypress.config.*",
+ "nightwatch.conf.*",
+ "playwright.config.*"
+ ],
+ "compilerOptions": {
+ "composite": true,
+ "noEmit": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
+
+ "module": "ESNext",
+ "moduleResolution": "Bundler",
+ "types": ["node"]
+ }
+}
diff --git a/playground/typescript-jsx-router-pinia-vitest-playwright/tsconfig.vitest.json b/playground/typescript-jsx-router-pinia-vitest-playwright/tsconfig.vitest.json
new file mode 100644
index 000000000..571995d11
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-vitest-playwright/tsconfig.vitest.json
@@ -0,0 +1,11 @@
+{
+ "extends": "./tsconfig.app.json",
+ "exclude": [],
+ "compilerOptions": {
+ "composite": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.vitest.tsbuildinfo",
+
+ "lib": [],
+ "types": ["node", "jsdom"]
+ }
+}
diff --git a/playground/typescript-jsx-router-pinia-vitest-playwright/vite.config.ts b/playground/typescript-jsx-router-pinia-vitest-playwright/vite.config.ts
new file mode 100644
index 000000000..36c618756
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-vitest-playwright/vite.config.ts
@@ -0,0 +1,18 @@
+import { fileURLToPath, URL } from 'node:url'
+
+import { defineConfig } from 'vite'
+import vue from '@vitejs/plugin-vue'
+import vueJsx from '@vitejs/plugin-vue-jsx'
+
+// https://vitejs.dev/config/
+export default defineConfig({
+ plugins: [
+ vue(),
+ vueJsx(),
+ ],
+ resolve: {
+ alias: {
+ '@': fileURLToPath(new URL('./src', import.meta.url))
+ }
+ }
+})
diff --git a/playground/typescript-jsx-router-pinia-vitest-playwright/vitest.config.ts b/playground/typescript-jsx-router-pinia-vitest-playwright/vitest.config.ts
new file mode 100644
index 000000000..10067d578
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-vitest-playwright/vitest.config.ts
@@ -0,0 +1,14 @@
+import { fileURLToPath } from 'node:url'
+import { mergeConfig, defineConfig, configDefaults } from 'vitest/config'
+import viteConfig from './vite.config'
+
+export default mergeConfig(
+ viteConfig,
+ defineConfig({
+ test: {
+ environment: 'jsdom',
+ exclude: [...configDefaults.exclude, 'e2e/*'],
+ root: fileURLToPath(new URL('./', import.meta.url))
+ }
+ })
+)
diff --git a/playground/typescript-jsx-router-pinia-vitest/.gitignore b/playground/typescript-jsx-router-pinia-vitest/.gitignore
new file mode 100644
index 000000000..8ee54e8d3
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-vitest/.gitignore
@@ -0,0 +1,30 @@
+# 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/
+
+# Editor directories and files
+.vscode/*
+!.vscode/extensions.json
+.idea
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?
+
+*.tsbuildinfo
diff --git a/playground/typescript-jsx-router-pinia-vitest/README.md b/playground/typescript-jsx-router-pinia-vitest/README.md
new file mode 100644
index 000000000..6561c3315
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-vitest/README.md
@@ -0,0 +1,46 @@
+# typescript-jsx-router-pinia-vitest
+
+This template should help get you started developing with Vue 3 in Vite.
+
+## Recommended IDE Setup
+
+[VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur) + [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin).
+
+## Type Support for `.vue` Imports in TS
+
+TypeScript cannot handle type information for `.vue` imports by default, so we replace the `tsc` CLI with `vue-tsc` for type checking. In editors, we need [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin) to make the TypeScript language service aware of `.vue` types.
+
+If the standalone TypeScript plugin doesn't feel fast enough to you, Volar has also implemented a [Take Over Mode](https://github.com/johnsoncodehk/volar/discussions/471#discussioncomment-1361669) that is more performant. You can enable it by the following steps:
+
+1. Disable the built-in TypeScript Extension
+ 1) Run `Extensions: Show Built-in Extensions` from VSCode's command palette
+ 2) Find `TypeScript and JavaScript Language Features`, right click and select `Disable (Workspace)`
+2. Reload the VSCode window by running `Developer: Reload Window` from the command palette.
+
+## Customize configuration
+
+See [Vite Configuration Reference](https://vitejs.dev/config/).
+
+## Project Setup
+
+```sh
+pnpm install
+```
+
+### Compile and Hot-Reload for Development
+
+```sh
+pnpm dev
+```
+
+### Type-Check, Compile and Minify for Production
+
+```sh
+pnpm build
+```
+
+### Run Unit Tests with [Vitest](https://vitest.dev/)
+
+```sh
+pnpm test:unit
+```
diff --git a/playground/typescript-jsx-router-pinia-vitest/env.d.ts b/playground/typescript-jsx-router-pinia-vitest/env.d.ts
new file mode 100644
index 000000000..11f02fe2a
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-vitest/env.d.ts
@@ -0,0 +1 @@
+///
diff --git a/playground/typescript-jsx-router-pinia-vitest/index.html b/playground/typescript-jsx-router-pinia-vitest/index.html
new file mode 100644
index 000000000..a88854489
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-vitest/index.html
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+ Vite App
+
+
+
+
+
+
diff --git a/playground/typescript-jsx-router-pinia-vitest/package.json b/playground/typescript-jsx-router-pinia-vitest/package.json
new file mode 100644
index 000000000..a361e6c2a
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-vitest/package.json
@@ -0,0 +1,34 @@
+{
+ "name": "typescript-jsx-router-pinia-vitest",
+ "version": "0.0.0",
+ "private": true,
+ "type": "module",
+ "scripts": {
+ "dev": "vite",
+ "build": "run-p type-check \"build-only {@}\" --",
+ "preview": "vite preview",
+ "test:unit": "vitest",
+ "build-only": "vite build",
+ "type-check": "vue-tsc --build --force"
+ },
+ "dependencies": {
+ "pinia": "^2.1.7",
+ "vue": "^3.4.15",
+ "vue-router": "^4.2.5"
+ },
+ "devDependencies": {
+ "@tsconfig/node20": "^20.1.2",
+ "@types/jsdom": "^21.1.6",
+ "@types/node": "^20.11.16",
+ "@vitejs/plugin-vue": "^5.0.3",
+ "@vitejs/plugin-vue-jsx": "^3.1.0",
+ "@vue/test-utils": "^2.4.4",
+ "@vue/tsconfig": "^0.5.1",
+ "jsdom": "^24.0.0",
+ "npm-run-all2": "^6.1.2",
+ "typescript": "~5.3.0",
+ "vite": "^5.0.11",
+ "vitest": "^1.2.2",
+ "vue-tsc": "^1.8.27"
+ }
+}
diff --git a/playground/typescript-jsx-router-pinia-vitest/public/favicon.ico b/playground/typescript-jsx-router-pinia-vitest/public/favicon.ico
new file mode 100644
index 000000000..df36fcfb7
Binary files /dev/null and b/playground/typescript-jsx-router-pinia-vitest/public/favicon.ico differ
diff --git a/playground/typescript-jsx-router-pinia-vitest/src/App.vue b/playground/typescript-jsx-router-pinia-vitest/src/App.vue
new file mode 100644
index 000000000..7905b0516
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-vitest/src/App.vue
@@ -0,0 +1,85 @@
+
+
+
+
+
+
+
+ You’ve successfully created a project with
+ Vite +
+ Vue 3. What's next?
+
+
+
+
+
diff --git a/playground/typescript-jsx-router-pinia-vitest/src/components/TheWelcome.vue b/playground/typescript-jsx-router-pinia-vitest/src/components/TheWelcome.vue
new file mode 100644
index 000000000..49d8f7354
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-vitest/src/components/TheWelcome.vue
@@ -0,0 +1,88 @@
+
+
+
+
+
+
+
+ Documentation
+
+ Vue’s
+ official documentation
+ provides you with all information you need to get started.
+
+
+
+
+
+
+ Tooling
+
+ This project is served and bundled with
+ Vite. The
+ recommended IDE setup is
+ VSCode +
+ Volar. If
+ you need to test your components and web pages, check out
+ Cypress and
+ Cypress Component Testing.
+
+
+
+ More instructions are available in README.md.
+
+
+
+
+
+
+ Ecosystem
+
+ Get official tools and libraries for your project:
+ Pinia,
+ Vue Router,
+ Vue Test Utils, and
+ Vue Dev Tools. If
+ you need more resources, we suggest paying
+ Awesome Vue
+ a visit.
+
+
+
+
+
+
+ Community
+
+ Got stuck? Ask your question on
+ Vue Land, our official
+ Discord server, or
+ StackOverflow. You should also subscribe to
+ our mailing list and follow
+ the official
+ @vuejs
+ twitter account for latest news in the Vue world.
+
+
+
+
+
+
+ Support Vue
+
+ As an independent project, Vue relies on community backing for its sustainability. You can help
+ us by
+ becoming a sponsor.
+
+
diff --git a/playground/typescript-jsx-router-pinia-vitest/src/components/WelcomeItem.vue b/playground/typescript-jsx-router-pinia-vitest/src/components/WelcomeItem.vue
new file mode 100644
index 000000000..6d7086aea
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-vitest/src/components/WelcomeItem.vue
@@ -0,0 +1,87 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/playground/typescript-jsx-router-pinia-vitest/src/components/__tests__/HelloWorld.spec.ts b/playground/typescript-jsx-router-pinia-vitest/src/components/__tests__/HelloWorld.spec.ts
new file mode 100644
index 000000000..253320200
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-vitest/src/components/__tests__/HelloWorld.spec.ts
@@ -0,0 +1,11 @@
+import { describe, it, expect } from 'vitest'
+
+import { mount } from '@vue/test-utils'
+import HelloWorld from '../HelloWorld.vue'
+
+describe('HelloWorld', () => {
+ it('renders properly', () => {
+ const wrapper = mount(HelloWorld, { props: { msg: 'Hello Vitest' } })
+ expect(wrapper.text()).toContain('Hello Vitest')
+ })
+})
diff --git a/playground/typescript-jsx-router-pinia-vitest/src/components/icons/IconCommunity.vue b/playground/typescript-jsx-router-pinia-vitest/src/components/icons/IconCommunity.vue
new file mode 100644
index 000000000..2dc8b0552
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-vitest/src/components/icons/IconCommunity.vue
@@ -0,0 +1,7 @@
+
+
+
diff --git a/playground/typescript-jsx-router-pinia-vitest/src/components/icons/IconDocumentation.vue b/playground/typescript-jsx-router-pinia-vitest/src/components/icons/IconDocumentation.vue
new file mode 100644
index 000000000..6d4791cfb
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-vitest/src/components/icons/IconDocumentation.vue
@@ -0,0 +1,7 @@
+
+
+
diff --git a/playground/typescript-jsx-router-pinia-vitest/src/components/icons/IconEcosystem.vue b/playground/typescript-jsx-router-pinia-vitest/src/components/icons/IconEcosystem.vue
new file mode 100644
index 000000000..c3a4f078c
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-vitest/src/components/icons/IconEcosystem.vue
@@ -0,0 +1,7 @@
+
+
+
diff --git a/playground/typescript-jsx-router-pinia-vitest/src/components/icons/IconSupport.vue b/playground/typescript-jsx-router-pinia-vitest/src/components/icons/IconSupport.vue
new file mode 100644
index 000000000..7452834d3
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-vitest/src/components/icons/IconSupport.vue
@@ -0,0 +1,7 @@
+
+
+
diff --git a/playground/typescript-jsx-router-pinia-vitest/src/components/icons/IconTooling.vue b/playground/typescript-jsx-router-pinia-vitest/src/components/icons/IconTooling.vue
new file mode 100644
index 000000000..660598d7c
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-vitest/src/components/icons/IconTooling.vue
@@ -0,0 +1,19 @@
+
+
+
+
diff --git a/playground/typescript-jsx-router-pinia-vitest/src/main.ts b/playground/typescript-jsx-router-pinia-vitest/src/main.ts
new file mode 100644
index 000000000..5dcad83c3
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-vitest/src/main.ts
@@ -0,0 +1,14 @@
+import './assets/main.css'
+
+import { createApp } from 'vue'
+import { createPinia } from 'pinia'
+
+import App from './App.vue'
+import router from './router'
+
+const app = createApp(App)
+
+app.use(createPinia())
+app.use(router)
+
+app.mount('#app')
diff --git a/playground/typescript-jsx-router-pinia-vitest/src/router/index.ts b/playground/typescript-jsx-router-pinia-vitest/src/router/index.ts
new file mode 100644
index 000000000..a49ae507f
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-vitest/src/router/index.ts
@@ -0,0 +1,23 @@
+import { createRouter, createWebHistory } from 'vue-router'
+import HomeView from '../views/HomeView.vue'
+
+const router = createRouter({
+ history: createWebHistory(import.meta.env.BASE_URL),
+ routes: [
+ {
+ path: '/',
+ name: 'home',
+ component: HomeView
+ },
+ {
+ path: '/about',
+ name: 'about',
+ // route level code-splitting
+ // this generates a separate chunk (About.[hash].js) for this route
+ // which is lazy-loaded when the route is visited.
+ component: () => import('../views/AboutView.vue')
+ }
+ ]
+})
+
+export default router
diff --git a/playground/typescript-jsx-router-pinia-vitest/src/stores/counter.ts b/playground/typescript-jsx-router-pinia-vitest/src/stores/counter.ts
new file mode 100644
index 000000000..b6757ba57
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-vitest/src/stores/counter.ts
@@ -0,0 +1,12 @@
+import { ref, computed } from 'vue'
+import { defineStore } from 'pinia'
+
+export const useCounterStore = defineStore('counter', () => {
+ const count = ref(0)
+ const doubleCount = computed(() => count.value * 2)
+ function increment() {
+ count.value++
+ }
+
+ return { count, doubleCount, increment }
+})
diff --git a/playground/typescript-jsx-router-pinia-vitest/src/views/AboutView.vue b/playground/typescript-jsx-router-pinia-vitest/src/views/AboutView.vue
new file mode 100644
index 000000000..756ad2a17
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-vitest/src/views/AboutView.vue
@@ -0,0 +1,15 @@
+
+
+
This is an about page
+
+
+
+
diff --git a/playground/typescript-jsx-router-pinia-vitest/src/views/HomeView.vue b/playground/typescript-jsx-router-pinia-vitest/src/views/HomeView.vue
new file mode 100644
index 000000000..d5c0217e4
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-vitest/src/views/HomeView.vue
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
diff --git a/playground/typescript-jsx-router-pinia-vitest/tsconfig.app.json b/playground/typescript-jsx-router-pinia-vitest/tsconfig.app.json
new file mode 100644
index 000000000..e14c754d3
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-vitest/tsconfig.app.json
@@ -0,0 +1,14 @@
+{
+ "extends": "@vue/tsconfig/tsconfig.dom.json",
+ "include": ["env.d.ts", "src/**/*", "src/**/*.vue"],
+ "exclude": ["src/**/__tests__/*"],
+ "compilerOptions": {
+ "composite": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
+
+ "baseUrl": ".",
+ "paths": {
+ "@/*": ["./src/*"]
+ }
+ }
+}
diff --git a/playground/typescript-jsx-router-pinia-vitest/tsconfig.json b/playground/typescript-jsx-router-pinia-vitest/tsconfig.json
new file mode 100644
index 000000000..100cf6a8f
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-vitest/tsconfig.json
@@ -0,0 +1,14 @@
+{
+ "files": [],
+ "references": [
+ {
+ "path": "./tsconfig.node.json"
+ },
+ {
+ "path": "./tsconfig.app.json"
+ },
+ {
+ "path": "./tsconfig.vitest.json"
+ }
+ ]
+}
diff --git a/playground/typescript-jsx-router-pinia-vitest/tsconfig.node.json b/playground/typescript-jsx-router-pinia-vitest/tsconfig.node.json
new file mode 100644
index 000000000..f09406303
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-vitest/tsconfig.node.json
@@ -0,0 +1,19 @@
+{
+ "extends": "@tsconfig/node20/tsconfig.json",
+ "include": [
+ "vite.config.*",
+ "vitest.config.*",
+ "cypress.config.*",
+ "nightwatch.conf.*",
+ "playwright.config.*"
+ ],
+ "compilerOptions": {
+ "composite": true,
+ "noEmit": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
+
+ "module": "ESNext",
+ "moduleResolution": "Bundler",
+ "types": ["node"]
+ }
+}
diff --git a/playground/typescript-jsx-router-pinia-vitest/tsconfig.vitest.json b/playground/typescript-jsx-router-pinia-vitest/tsconfig.vitest.json
new file mode 100644
index 000000000..571995d11
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-vitest/tsconfig.vitest.json
@@ -0,0 +1,11 @@
+{
+ "extends": "./tsconfig.app.json",
+ "exclude": [],
+ "compilerOptions": {
+ "composite": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.vitest.tsbuildinfo",
+
+ "lib": [],
+ "types": ["node", "jsdom"]
+ }
+}
diff --git a/playground/typescript-jsx-router-pinia-vitest/vite.config.ts b/playground/typescript-jsx-router-pinia-vitest/vite.config.ts
new file mode 100644
index 000000000..36c618756
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-vitest/vite.config.ts
@@ -0,0 +1,18 @@
+import { fileURLToPath, URL } from 'node:url'
+
+import { defineConfig } from 'vite'
+import vue from '@vitejs/plugin-vue'
+import vueJsx from '@vitejs/plugin-vue-jsx'
+
+// https://vitejs.dev/config/
+export default defineConfig({
+ plugins: [
+ vue(),
+ vueJsx(),
+ ],
+ resolve: {
+ alias: {
+ '@': fileURLToPath(new URL('./src', import.meta.url))
+ }
+ }
+})
diff --git a/playground/typescript-jsx-router-pinia-vitest/vitest.config.ts b/playground/typescript-jsx-router-pinia-vitest/vitest.config.ts
new file mode 100644
index 000000000..10067d578
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-vitest/vitest.config.ts
@@ -0,0 +1,14 @@
+import { fileURLToPath } from 'node:url'
+import { mergeConfig, defineConfig, configDefaults } from 'vitest/config'
+import viteConfig from './vite.config'
+
+export default mergeConfig(
+ viteConfig,
+ defineConfig({
+ test: {
+ environment: 'jsdom',
+ exclude: [...configDefaults.exclude, 'e2e/*'],
+ root: fileURLToPath(new URL('./', import.meta.url))
+ }
+ })
+)
diff --git a/playground/typescript-jsx-router-pinia-with-tests/.gitignore b/playground/typescript-jsx-router-pinia-with-tests/.gitignore
new file mode 100644
index 000000000..8ee54e8d3
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-with-tests/.gitignore
@@ -0,0 +1,30 @@
+# 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/
+
+# Editor directories and files
+.vscode/*
+!.vscode/extensions.json
+.idea
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?
+
+*.tsbuildinfo
diff --git a/playground/typescript-jsx-router-pinia-with-tests/README.md b/playground/typescript-jsx-router-pinia-with-tests/README.md
new file mode 100644
index 000000000..cfbfc7f7e
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-with-tests/README.md
@@ -0,0 +1,62 @@
+# typescript-jsx-router-pinia-with-tests
+
+This template should help get you started developing with Vue 3 in Vite.
+
+## Recommended IDE Setup
+
+[VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur) + [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin).
+
+## Type Support for `.vue` Imports in TS
+
+TypeScript cannot handle type information for `.vue` imports by default, so we replace the `tsc` CLI with `vue-tsc` for type checking. In editors, we need [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin) to make the TypeScript language service aware of `.vue` types.
+
+If the standalone TypeScript plugin doesn't feel fast enough to you, Volar has also implemented a [Take Over Mode](https://github.com/johnsoncodehk/volar/discussions/471#discussioncomment-1361669) that is more performant. You can enable it by the following steps:
+
+1. Disable the built-in TypeScript Extension
+ 1) Run `Extensions: Show Built-in Extensions` from VSCode's command palette
+ 2) Find `TypeScript and JavaScript Language Features`, right click and select `Disable (Workspace)`
+2. Reload the VSCode window by running `Developer: Reload Window` from the command palette.
+
+## Customize configuration
+
+See [Vite Configuration Reference](https://vitejs.dev/config/).
+
+## Project Setup
+
+```sh
+pnpm install
+```
+
+### Compile and Hot-Reload for Development
+
+```sh
+pnpm dev
+```
+
+### Type-Check, Compile and Minify for Production
+
+```sh
+pnpm build
+```
+
+### Run Unit Tests with [Vitest](https://vitest.dev/)
+
+```sh
+pnpm test:unit
+```
+
+### Run End-to-End Tests with [Cypress](https://www.cypress.io/)
+
+```sh
+pnpm test:e2e:dev
+```
+
+This runs the end-to-end tests against the Vite development server.
+It is much faster than the production build.
+
+But it's still recommended to test the production build with `test:e2e` before deploying (e.g. in CI environments):
+
+```sh
+pnpm build
+pnpm test:e2e
+```
diff --git a/playground/typescript-jsx-router-pinia-with-tests/cypress.config.ts b/playground/typescript-jsx-router-pinia-with-tests/cypress.config.ts
new file mode 100644
index 000000000..0f66080fd
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-with-tests/cypress.config.ts
@@ -0,0 +1,8 @@
+import { defineConfig } from 'cypress'
+
+export default defineConfig({
+ e2e: {
+ specPattern: 'cypress/e2e/**/*.{cy,spec}.{js,jsx,ts,tsx}',
+ baseUrl: 'http://localhost:4173'
+ }
+})
diff --git a/playground/typescript-jsx-router-pinia-with-tests/cypress/e2e/example.cy.ts b/playground/typescript-jsx-router-pinia-with-tests/cypress/e2e/example.cy.ts
new file mode 100644
index 000000000..7554c35d8
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-with-tests/cypress/e2e/example.cy.ts
@@ -0,0 +1,8 @@
+// https://on.cypress.io/api
+
+describe('My First Test', () => {
+ it('visits the app root url', () => {
+ cy.visit('/')
+ cy.contains('h1', 'You did it!')
+ })
+})
diff --git a/playground/typescript-jsx-router-pinia-with-tests/cypress/e2e/tsconfig.json b/playground/typescript-jsx-router-pinia-with-tests/cypress/e2e/tsconfig.json
new file mode 100644
index 000000000..37748feb7
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-with-tests/cypress/e2e/tsconfig.json
@@ -0,0 +1,10 @@
+{
+ "extends": "@vue/tsconfig/tsconfig.dom.json",
+ "include": ["./**/*", "../support/**/*"],
+ "compilerOptions": {
+ "isolatedModules": false,
+ "target": "es5",
+ "lib": ["es5", "dom"],
+ "types": ["cypress"]
+ }
+}
diff --git a/playground/typescript-jsx-router-pinia-with-tests/cypress/fixtures/example.json b/playground/typescript-jsx-router-pinia-with-tests/cypress/fixtures/example.json
new file mode 100644
index 000000000..02e425437
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-with-tests/cypress/fixtures/example.json
@@ -0,0 +1,5 @@
+{
+ "name": "Using fixtures to represent data",
+ "email": "hello@cypress.io",
+ "body": "Fixtures are a great way to mock data for responses to routes"
+}
diff --git a/playground/typescript-jsx-router-pinia-with-tests/cypress/support/commands.ts b/playground/typescript-jsx-router-pinia-with-tests/cypress/support/commands.ts
new file mode 100644
index 000000000..9b7bb8e25
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-with-tests/cypress/support/commands.ts
@@ -0,0 +1,39 @@
+///
+// ***********************************************
+// This example commands.ts shows you how to
+// create various custom commands and overwrite
+// existing commands.
+//
+// For more comprehensive examples of custom
+// commands please read more here:
+// https://on.cypress.io/custom-commands
+// ***********************************************
+//
+//
+// -- This is a parent command --
+// Cypress.Commands.add('login', (email, password) => { ... })
+//
+//
+// -- This is a child command --
+// Cypress.Commands.add('drag', { prevSubject: 'element'}, (subject, options) => { ... })
+//
+//
+// -- This is a dual command --
+// Cypress.Commands.add('dismiss', { prevSubject: 'optional'}, (subject, options) => { ... })
+//
+//
+// -- This will overwrite an existing command --
+// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... })
+//
+// declare global {
+// namespace Cypress {
+// interface Chainable {
+// login(email: string, password: string): Chainable
+// drag(subject: string, options?: Partial): Chainable
+// dismiss(subject: string, options?: Partial): Chainable
+// visit(originalFn: CommandOriginalFn, url: string, options: Partial): Chainable
+// }
+// }
+// }
+
+export {}
diff --git a/playground/typescript-jsx-router-pinia-with-tests/cypress/support/e2e.ts b/playground/typescript-jsx-router-pinia-with-tests/cypress/support/e2e.ts
new file mode 100644
index 000000000..d68db96df
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-with-tests/cypress/support/e2e.ts
@@ -0,0 +1,20 @@
+// ***********************************************************
+// This example support/index.js is processed and
+// loaded automatically before your test files.
+//
+// This is a great place to put global configuration and
+// behavior that modifies Cypress.
+//
+// You can change the location of this file or turn off
+// automatically serving support files with the
+// 'supportFile' configuration option.
+//
+// You can read more here:
+// https://on.cypress.io/configuration
+// ***********************************************************
+
+// Import commands.js using ES2015 syntax:
+import './commands'
+
+// Alternatively you can use CommonJS syntax:
+// require('./commands')
diff --git a/playground/typescript-jsx-router-pinia-with-tests/env.d.ts b/playground/typescript-jsx-router-pinia-with-tests/env.d.ts
new file mode 100644
index 000000000..11f02fe2a
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-with-tests/env.d.ts
@@ -0,0 +1 @@
+///
diff --git a/playground/typescript-jsx-router-pinia-with-tests/index.html b/playground/typescript-jsx-router-pinia-with-tests/index.html
new file mode 100644
index 000000000..a88854489
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-with-tests/index.html
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+ Vite App
+
+
+
+
+
+
diff --git a/playground/typescript-jsx-router-pinia-with-tests/package.json b/playground/typescript-jsx-router-pinia-with-tests/package.json
new file mode 100644
index 000000000..8f521220b
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-with-tests/package.json
@@ -0,0 +1,38 @@
+{
+ "name": "typescript-jsx-router-pinia-with-tests",
+ "version": "0.0.0",
+ "private": true,
+ "type": "module",
+ "scripts": {
+ "dev": "vite",
+ "build": "run-p type-check \"build-only {@}\" --",
+ "preview": "vite preview",
+ "test:unit": "vitest",
+ "test:e2e": "start-server-and-test preview http://localhost:4173 'cypress run --e2e'",
+ "test:e2e:dev": "start-server-and-test 'vite dev --port 4173' http://localhost:4173 'cypress open --e2e'",
+ "build-only": "vite build",
+ "type-check": "vue-tsc --build --force"
+ },
+ "dependencies": {
+ "pinia": "^2.1.7",
+ "vue": "^3.4.15",
+ "vue-router": "^4.2.5"
+ },
+ "devDependencies": {
+ "@tsconfig/node20": "^20.1.2",
+ "@types/jsdom": "^21.1.6",
+ "@types/node": "^20.11.16",
+ "@vitejs/plugin-vue": "^5.0.3",
+ "@vitejs/plugin-vue-jsx": "^3.1.0",
+ "@vue/test-utils": "^2.4.4",
+ "@vue/tsconfig": "^0.5.1",
+ "cypress": "^13.6.4",
+ "jsdom": "^24.0.0",
+ "npm-run-all2": "^6.1.2",
+ "start-server-and-test": "^2.0.3",
+ "typescript": "~5.3.0",
+ "vite": "^5.0.11",
+ "vitest": "^1.2.2",
+ "vue-tsc": "^1.8.27"
+ }
+}
diff --git a/playground/typescript-jsx-router-pinia-with-tests/public/favicon.ico b/playground/typescript-jsx-router-pinia-with-tests/public/favicon.ico
new file mode 100644
index 000000000..df36fcfb7
Binary files /dev/null and b/playground/typescript-jsx-router-pinia-with-tests/public/favicon.ico differ
diff --git a/playground/typescript-jsx-router-pinia-with-tests/src/App.vue b/playground/typescript-jsx-router-pinia-with-tests/src/App.vue
new file mode 100644
index 000000000..7905b0516
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-with-tests/src/App.vue
@@ -0,0 +1,85 @@
+
+
+
+
+
+
+
+ You’ve successfully created a project with
+ Vite +
+ Vue 3. What's next?
+
+
+
+
+
diff --git a/playground/typescript-jsx-router-pinia-with-tests/src/components/TheWelcome.vue b/playground/typescript-jsx-router-pinia-with-tests/src/components/TheWelcome.vue
new file mode 100644
index 000000000..49d8f7354
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-with-tests/src/components/TheWelcome.vue
@@ -0,0 +1,88 @@
+
+
+
+
+
+
+
+ Documentation
+
+ Vue’s
+ official documentation
+ provides you with all information you need to get started.
+
+
+
+
+
+
+ Tooling
+
+ This project is served and bundled with
+ Vite. The
+ recommended IDE setup is
+ VSCode +
+ Volar. If
+ you need to test your components and web pages, check out
+ Cypress and
+ Cypress Component Testing.
+
+
+
+ More instructions are available in README.md.
+
+
+
+
+
+
+ Ecosystem
+
+ Get official tools and libraries for your project:
+ Pinia,
+ Vue Router,
+ Vue Test Utils, and
+ Vue Dev Tools. If
+ you need more resources, we suggest paying
+ Awesome Vue
+ a visit.
+
+
+
+
+
+
+ Community
+
+ Got stuck? Ask your question on
+ Vue Land, our official
+ Discord server, or
+ StackOverflow. You should also subscribe to
+ our mailing list and follow
+ the official
+ @vuejs
+ twitter account for latest news in the Vue world.
+
+
+
+
+
+
+ Support Vue
+
+ As an independent project, Vue relies on community backing for its sustainability. You can help
+ us by
+ becoming a sponsor.
+
+
diff --git a/playground/typescript-jsx-router-pinia-with-tests/src/components/WelcomeItem.vue b/playground/typescript-jsx-router-pinia-with-tests/src/components/WelcomeItem.vue
new file mode 100644
index 000000000..6d7086aea
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-with-tests/src/components/WelcomeItem.vue
@@ -0,0 +1,87 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/playground/typescript-jsx-router-pinia-with-tests/src/components/__tests__/HelloWorld.spec.ts b/playground/typescript-jsx-router-pinia-with-tests/src/components/__tests__/HelloWorld.spec.ts
new file mode 100644
index 000000000..253320200
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-with-tests/src/components/__tests__/HelloWorld.spec.ts
@@ -0,0 +1,11 @@
+import { describe, it, expect } from 'vitest'
+
+import { mount } from '@vue/test-utils'
+import HelloWorld from '../HelloWorld.vue'
+
+describe('HelloWorld', () => {
+ it('renders properly', () => {
+ const wrapper = mount(HelloWorld, { props: { msg: 'Hello Vitest' } })
+ expect(wrapper.text()).toContain('Hello Vitest')
+ })
+})
diff --git a/playground/typescript-jsx-router-pinia-with-tests/src/components/icons/IconCommunity.vue b/playground/typescript-jsx-router-pinia-with-tests/src/components/icons/IconCommunity.vue
new file mode 100644
index 000000000..2dc8b0552
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-with-tests/src/components/icons/IconCommunity.vue
@@ -0,0 +1,7 @@
+
+
+
diff --git a/playground/typescript-jsx-router-pinia-with-tests/src/components/icons/IconDocumentation.vue b/playground/typescript-jsx-router-pinia-with-tests/src/components/icons/IconDocumentation.vue
new file mode 100644
index 000000000..6d4791cfb
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-with-tests/src/components/icons/IconDocumentation.vue
@@ -0,0 +1,7 @@
+
+
+
diff --git a/playground/typescript-jsx-router-pinia-with-tests/src/components/icons/IconEcosystem.vue b/playground/typescript-jsx-router-pinia-with-tests/src/components/icons/IconEcosystem.vue
new file mode 100644
index 000000000..c3a4f078c
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-with-tests/src/components/icons/IconEcosystem.vue
@@ -0,0 +1,7 @@
+
+
+
diff --git a/playground/typescript-jsx-router-pinia-with-tests/src/components/icons/IconSupport.vue b/playground/typescript-jsx-router-pinia-with-tests/src/components/icons/IconSupport.vue
new file mode 100644
index 000000000..7452834d3
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-with-tests/src/components/icons/IconSupport.vue
@@ -0,0 +1,7 @@
+
+
+
diff --git a/playground/typescript-jsx-router-pinia-with-tests/src/components/icons/IconTooling.vue b/playground/typescript-jsx-router-pinia-with-tests/src/components/icons/IconTooling.vue
new file mode 100644
index 000000000..660598d7c
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-with-tests/src/components/icons/IconTooling.vue
@@ -0,0 +1,19 @@
+
+
+
+
diff --git a/playground/typescript-jsx-router-pinia-with-tests/src/main.ts b/playground/typescript-jsx-router-pinia-with-tests/src/main.ts
new file mode 100644
index 000000000..5dcad83c3
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-with-tests/src/main.ts
@@ -0,0 +1,14 @@
+import './assets/main.css'
+
+import { createApp } from 'vue'
+import { createPinia } from 'pinia'
+
+import App from './App.vue'
+import router from './router'
+
+const app = createApp(App)
+
+app.use(createPinia())
+app.use(router)
+
+app.mount('#app')
diff --git a/playground/typescript-jsx-router-pinia-with-tests/src/router/index.ts b/playground/typescript-jsx-router-pinia-with-tests/src/router/index.ts
new file mode 100644
index 000000000..a49ae507f
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-with-tests/src/router/index.ts
@@ -0,0 +1,23 @@
+import { createRouter, createWebHistory } from 'vue-router'
+import HomeView from '../views/HomeView.vue'
+
+const router = createRouter({
+ history: createWebHistory(import.meta.env.BASE_URL),
+ routes: [
+ {
+ path: '/',
+ name: 'home',
+ component: HomeView
+ },
+ {
+ path: '/about',
+ name: 'about',
+ // route level code-splitting
+ // this generates a separate chunk (About.[hash].js) for this route
+ // which is lazy-loaded when the route is visited.
+ component: () => import('../views/AboutView.vue')
+ }
+ ]
+})
+
+export default router
diff --git a/playground/typescript-jsx-router-pinia-with-tests/src/stores/counter.ts b/playground/typescript-jsx-router-pinia-with-tests/src/stores/counter.ts
new file mode 100644
index 000000000..b6757ba57
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-with-tests/src/stores/counter.ts
@@ -0,0 +1,12 @@
+import { ref, computed } from 'vue'
+import { defineStore } from 'pinia'
+
+export const useCounterStore = defineStore('counter', () => {
+ const count = ref(0)
+ const doubleCount = computed(() => count.value * 2)
+ function increment() {
+ count.value++
+ }
+
+ return { count, doubleCount, increment }
+})
diff --git a/playground/typescript-jsx-router-pinia-with-tests/src/views/AboutView.vue b/playground/typescript-jsx-router-pinia-with-tests/src/views/AboutView.vue
new file mode 100644
index 000000000..756ad2a17
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-with-tests/src/views/AboutView.vue
@@ -0,0 +1,15 @@
+
+
+
This is an about page
+
+
+
+
diff --git a/playground/typescript-jsx-router-pinia-with-tests/src/views/HomeView.vue b/playground/typescript-jsx-router-pinia-with-tests/src/views/HomeView.vue
new file mode 100644
index 000000000..d5c0217e4
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-with-tests/src/views/HomeView.vue
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
diff --git a/playground/typescript-jsx-router-pinia-with-tests/tsconfig.app.json b/playground/typescript-jsx-router-pinia-with-tests/tsconfig.app.json
new file mode 100644
index 000000000..e14c754d3
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-with-tests/tsconfig.app.json
@@ -0,0 +1,14 @@
+{
+ "extends": "@vue/tsconfig/tsconfig.dom.json",
+ "include": ["env.d.ts", "src/**/*", "src/**/*.vue"],
+ "exclude": ["src/**/__tests__/*"],
+ "compilerOptions": {
+ "composite": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
+
+ "baseUrl": ".",
+ "paths": {
+ "@/*": ["./src/*"]
+ }
+ }
+}
diff --git a/playground/typescript-jsx-router-pinia-with-tests/tsconfig.json b/playground/typescript-jsx-router-pinia-with-tests/tsconfig.json
new file mode 100644
index 000000000..5304731b8
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-with-tests/tsconfig.json
@@ -0,0 +1,17 @@
+{
+ "files": [],
+ "references": [
+ {
+ "path": "./tsconfig.node.json"
+ },
+ {
+ "path": "./tsconfig.app.json"
+ },
+ {
+ "path": "./tsconfig.vitest.json"
+ }
+ ],
+ "compilerOptions": {
+ "module": "NodeNext"
+ }
+}
diff --git a/playground/typescript-jsx-router-pinia-with-tests/tsconfig.node.json b/playground/typescript-jsx-router-pinia-with-tests/tsconfig.node.json
new file mode 100644
index 000000000..f09406303
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-with-tests/tsconfig.node.json
@@ -0,0 +1,19 @@
+{
+ "extends": "@tsconfig/node20/tsconfig.json",
+ "include": [
+ "vite.config.*",
+ "vitest.config.*",
+ "cypress.config.*",
+ "nightwatch.conf.*",
+ "playwright.config.*"
+ ],
+ "compilerOptions": {
+ "composite": true,
+ "noEmit": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
+
+ "module": "ESNext",
+ "moduleResolution": "Bundler",
+ "types": ["node"]
+ }
+}
diff --git a/playground/typescript-jsx-router-pinia-with-tests/tsconfig.vitest.json b/playground/typescript-jsx-router-pinia-with-tests/tsconfig.vitest.json
new file mode 100644
index 000000000..571995d11
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-with-tests/tsconfig.vitest.json
@@ -0,0 +1,11 @@
+{
+ "extends": "./tsconfig.app.json",
+ "exclude": [],
+ "compilerOptions": {
+ "composite": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.vitest.tsbuildinfo",
+
+ "lib": [],
+ "types": ["node", "jsdom"]
+ }
+}
diff --git a/playground/typescript-jsx-router-pinia-with-tests/vite.config.ts b/playground/typescript-jsx-router-pinia-with-tests/vite.config.ts
new file mode 100644
index 000000000..36c618756
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-with-tests/vite.config.ts
@@ -0,0 +1,18 @@
+import { fileURLToPath, URL } from 'node:url'
+
+import { defineConfig } from 'vite'
+import vue from '@vitejs/plugin-vue'
+import vueJsx from '@vitejs/plugin-vue-jsx'
+
+// https://vitejs.dev/config/
+export default defineConfig({
+ plugins: [
+ vue(),
+ vueJsx(),
+ ],
+ resolve: {
+ alias: {
+ '@': fileURLToPath(new URL('./src', import.meta.url))
+ }
+ }
+})
diff --git a/playground/typescript-jsx-router-pinia-with-tests/vitest.config.ts b/playground/typescript-jsx-router-pinia-with-tests/vitest.config.ts
new file mode 100644
index 000000000..10067d578
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia-with-tests/vitest.config.ts
@@ -0,0 +1,14 @@
+import { fileURLToPath } from 'node:url'
+import { mergeConfig, defineConfig, configDefaults } from 'vitest/config'
+import viteConfig from './vite.config'
+
+export default mergeConfig(
+ viteConfig,
+ defineConfig({
+ test: {
+ environment: 'jsdom',
+ exclude: [...configDefaults.exclude, 'e2e/*'],
+ root: fileURLToPath(new URL('./', import.meta.url))
+ }
+ })
+)
diff --git a/playground/typescript-jsx-router-pinia/.gitignore b/playground/typescript-jsx-router-pinia/.gitignore
new file mode 100644
index 000000000..8ee54e8d3
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia/.gitignore
@@ -0,0 +1,30 @@
+# 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/
+
+# Editor directories and files
+.vscode/*
+!.vscode/extensions.json
+.idea
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?
+
+*.tsbuildinfo
diff --git a/playground/typescript-jsx-router-pinia/README.md b/playground/typescript-jsx-router-pinia/README.md
new file mode 100644
index 000000000..dc923bd03
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia/README.md
@@ -0,0 +1,40 @@
+# typescript-jsx-router-pinia
+
+This template should help get you started developing with Vue 3 in Vite.
+
+## Recommended IDE Setup
+
+[VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur) + [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin).
+
+## Type Support for `.vue` Imports in TS
+
+TypeScript cannot handle type information for `.vue` imports by default, so we replace the `tsc` CLI with `vue-tsc` for type checking. In editors, we need [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin) to make the TypeScript language service aware of `.vue` types.
+
+If the standalone TypeScript plugin doesn't feel fast enough to you, Volar has also implemented a [Take Over Mode](https://github.com/johnsoncodehk/volar/discussions/471#discussioncomment-1361669) that is more performant. You can enable it by the following steps:
+
+1. Disable the built-in TypeScript Extension
+ 1) Run `Extensions: Show Built-in Extensions` from VSCode's command palette
+ 2) Find `TypeScript and JavaScript Language Features`, right click and select `Disable (Workspace)`
+2. Reload the VSCode window by running `Developer: Reload Window` from the command palette.
+
+## Customize configuration
+
+See [Vite Configuration Reference](https://vitejs.dev/config/).
+
+## Project Setup
+
+```sh
+pnpm install
+```
+
+### Compile and Hot-Reload for Development
+
+```sh
+pnpm dev
+```
+
+### Type-Check, Compile and Minify for Production
+
+```sh
+pnpm build
+```
diff --git a/playground/typescript-jsx-router-pinia/env.d.ts b/playground/typescript-jsx-router-pinia/env.d.ts
new file mode 100644
index 000000000..11f02fe2a
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia/env.d.ts
@@ -0,0 +1 @@
+///
diff --git a/playground/typescript-jsx-router-pinia/index.html b/playground/typescript-jsx-router-pinia/index.html
new file mode 100644
index 000000000..a88854489
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia/index.html
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+ Vite App
+
+
+
+
+
+
diff --git a/playground/typescript-jsx-router-pinia/package.json b/playground/typescript-jsx-router-pinia/package.json
new file mode 100644
index 000000000..65a59563f
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia/package.json
@@ -0,0 +1,29 @@
+{
+ "name": "typescript-jsx-router-pinia",
+ "version": "0.0.0",
+ "private": true,
+ "type": "module",
+ "scripts": {
+ "dev": "vite",
+ "build": "run-p type-check \"build-only {@}\" --",
+ "preview": "vite preview",
+ "build-only": "vite build",
+ "type-check": "vue-tsc --build --force"
+ },
+ "dependencies": {
+ "pinia": "^2.1.7",
+ "vue": "^3.4.15",
+ "vue-router": "^4.2.5"
+ },
+ "devDependencies": {
+ "@tsconfig/node20": "^20.1.2",
+ "@types/node": "^20.11.16",
+ "@vitejs/plugin-vue": "^5.0.3",
+ "@vitejs/plugin-vue-jsx": "^3.1.0",
+ "@vue/tsconfig": "^0.5.1",
+ "npm-run-all2": "^6.1.2",
+ "typescript": "~5.3.0",
+ "vite": "^5.0.11",
+ "vue-tsc": "^1.8.27"
+ }
+}
diff --git a/playground/typescript-jsx-router-pinia/public/favicon.ico b/playground/typescript-jsx-router-pinia/public/favicon.ico
new file mode 100644
index 000000000..df36fcfb7
Binary files /dev/null and b/playground/typescript-jsx-router-pinia/public/favicon.ico differ
diff --git a/playground/typescript-jsx-router-pinia/src/App.vue b/playground/typescript-jsx-router-pinia/src/App.vue
new file mode 100644
index 000000000..7905b0516
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia/src/App.vue
@@ -0,0 +1,85 @@
+
+
+
+
+
+
+
+ You’ve successfully created a project with
+ Vite +
+ Vue 3. What's next?
+
+
+
+
+
diff --git a/playground/typescript-jsx-router-pinia/src/components/TheWelcome.vue b/playground/typescript-jsx-router-pinia/src/components/TheWelcome.vue
new file mode 100644
index 000000000..49d8f7354
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia/src/components/TheWelcome.vue
@@ -0,0 +1,88 @@
+
+
+
+
+
+
+
+ Documentation
+
+ Vue’s
+ official documentation
+ provides you with all information you need to get started.
+
+
+
+
+
+
+ Tooling
+
+ This project is served and bundled with
+ Vite. The
+ recommended IDE setup is
+ VSCode +
+ Volar. If
+ you need to test your components and web pages, check out
+ Cypress and
+ Cypress Component Testing.
+
+
+
+ More instructions are available in README.md.
+
+
+
+
+
+
+ Ecosystem
+
+ Get official tools and libraries for your project:
+ Pinia,
+ Vue Router,
+ Vue Test Utils, and
+ Vue Dev Tools. If
+ you need more resources, we suggest paying
+ Awesome Vue
+ a visit.
+
+
+
+
+
+
+ Community
+
+ Got stuck? Ask your question on
+ Vue Land, our official
+ Discord server, or
+ StackOverflow. You should also subscribe to
+ our mailing list and follow
+ the official
+ @vuejs
+ twitter account for latest news in the Vue world.
+
+
+
+
+
+
+ Support Vue
+
+ As an independent project, Vue relies on community backing for its sustainability. You can help
+ us by
+ becoming a sponsor.
+
+
diff --git a/playground/typescript-jsx-router-pinia/src/components/WelcomeItem.vue b/playground/typescript-jsx-router-pinia/src/components/WelcomeItem.vue
new file mode 100644
index 000000000..6d7086aea
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia/src/components/WelcomeItem.vue
@@ -0,0 +1,87 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/playground/typescript-jsx-router-pinia/src/components/icons/IconCommunity.vue b/playground/typescript-jsx-router-pinia/src/components/icons/IconCommunity.vue
new file mode 100644
index 000000000..2dc8b0552
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia/src/components/icons/IconCommunity.vue
@@ -0,0 +1,7 @@
+
+
+
diff --git a/playground/typescript-jsx-router-pinia/src/components/icons/IconDocumentation.vue b/playground/typescript-jsx-router-pinia/src/components/icons/IconDocumentation.vue
new file mode 100644
index 000000000..6d4791cfb
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia/src/components/icons/IconDocumentation.vue
@@ -0,0 +1,7 @@
+
+
+
diff --git a/playground/typescript-jsx-router-pinia/src/components/icons/IconEcosystem.vue b/playground/typescript-jsx-router-pinia/src/components/icons/IconEcosystem.vue
new file mode 100644
index 000000000..c3a4f078c
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia/src/components/icons/IconEcosystem.vue
@@ -0,0 +1,7 @@
+
+
+
diff --git a/playground/typescript-jsx-router-pinia/src/components/icons/IconSupport.vue b/playground/typescript-jsx-router-pinia/src/components/icons/IconSupport.vue
new file mode 100644
index 000000000..7452834d3
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia/src/components/icons/IconSupport.vue
@@ -0,0 +1,7 @@
+
+
+
diff --git a/playground/typescript-jsx-router-pinia/src/components/icons/IconTooling.vue b/playground/typescript-jsx-router-pinia/src/components/icons/IconTooling.vue
new file mode 100644
index 000000000..660598d7c
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia/src/components/icons/IconTooling.vue
@@ -0,0 +1,19 @@
+
+
+
+
diff --git a/playground/typescript-jsx-router-pinia/src/main.ts b/playground/typescript-jsx-router-pinia/src/main.ts
new file mode 100644
index 000000000..5dcad83c3
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia/src/main.ts
@@ -0,0 +1,14 @@
+import './assets/main.css'
+
+import { createApp } from 'vue'
+import { createPinia } from 'pinia'
+
+import App from './App.vue'
+import router from './router'
+
+const app = createApp(App)
+
+app.use(createPinia())
+app.use(router)
+
+app.mount('#app')
diff --git a/playground/typescript-jsx-router-pinia/src/router/index.ts b/playground/typescript-jsx-router-pinia/src/router/index.ts
new file mode 100644
index 000000000..a49ae507f
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia/src/router/index.ts
@@ -0,0 +1,23 @@
+import { createRouter, createWebHistory } from 'vue-router'
+import HomeView from '../views/HomeView.vue'
+
+const router = createRouter({
+ history: createWebHistory(import.meta.env.BASE_URL),
+ routes: [
+ {
+ path: '/',
+ name: 'home',
+ component: HomeView
+ },
+ {
+ path: '/about',
+ name: 'about',
+ // route level code-splitting
+ // this generates a separate chunk (About.[hash].js) for this route
+ // which is lazy-loaded when the route is visited.
+ component: () => import('../views/AboutView.vue')
+ }
+ ]
+})
+
+export default router
diff --git a/playground/typescript-jsx-router-pinia/src/stores/counter.ts b/playground/typescript-jsx-router-pinia/src/stores/counter.ts
new file mode 100644
index 000000000..b6757ba57
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia/src/stores/counter.ts
@@ -0,0 +1,12 @@
+import { ref, computed } from 'vue'
+import { defineStore } from 'pinia'
+
+export const useCounterStore = defineStore('counter', () => {
+ const count = ref(0)
+ const doubleCount = computed(() => count.value * 2)
+ function increment() {
+ count.value++
+ }
+
+ return { count, doubleCount, increment }
+})
diff --git a/playground/typescript-jsx-router-pinia/src/views/AboutView.vue b/playground/typescript-jsx-router-pinia/src/views/AboutView.vue
new file mode 100644
index 000000000..756ad2a17
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia/src/views/AboutView.vue
@@ -0,0 +1,15 @@
+
+
+
This is an about page
+
+
+
+
diff --git a/playground/typescript-jsx-router-pinia/src/views/HomeView.vue b/playground/typescript-jsx-router-pinia/src/views/HomeView.vue
new file mode 100644
index 000000000..d5c0217e4
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia/src/views/HomeView.vue
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
diff --git a/playground/typescript-jsx-router-pinia/tsconfig.app.json b/playground/typescript-jsx-router-pinia/tsconfig.app.json
new file mode 100644
index 000000000..e14c754d3
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia/tsconfig.app.json
@@ -0,0 +1,14 @@
+{
+ "extends": "@vue/tsconfig/tsconfig.dom.json",
+ "include": ["env.d.ts", "src/**/*", "src/**/*.vue"],
+ "exclude": ["src/**/__tests__/*"],
+ "compilerOptions": {
+ "composite": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
+
+ "baseUrl": ".",
+ "paths": {
+ "@/*": ["./src/*"]
+ }
+ }
+}
diff --git a/playground/typescript-jsx-router-pinia/tsconfig.json b/playground/typescript-jsx-router-pinia/tsconfig.json
new file mode 100644
index 000000000..66b5e5703
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia/tsconfig.json
@@ -0,0 +1,11 @@
+{
+ "files": [],
+ "references": [
+ {
+ "path": "./tsconfig.node.json"
+ },
+ {
+ "path": "./tsconfig.app.json"
+ }
+ ]
+}
diff --git a/playground/typescript-jsx-router-pinia/tsconfig.node.json b/playground/typescript-jsx-router-pinia/tsconfig.node.json
new file mode 100644
index 000000000..f09406303
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia/tsconfig.node.json
@@ -0,0 +1,19 @@
+{
+ "extends": "@tsconfig/node20/tsconfig.json",
+ "include": [
+ "vite.config.*",
+ "vitest.config.*",
+ "cypress.config.*",
+ "nightwatch.conf.*",
+ "playwright.config.*"
+ ],
+ "compilerOptions": {
+ "composite": true,
+ "noEmit": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
+
+ "module": "ESNext",
+ "moduleResolution": "Bundler",
+ "types": ["node"]
+ }
+}
diff --git a/playground/typescript-jsx-router-pinia/vite.config.ts b/playground/typescript-jsx-router-pinia/vite.config.ts
new file mode 100644
index 000000000..36c618756
--- /dev/null
+++ b/playground/typescript-jsx-router-pinia/vite.config.ts
@@ -0,0 +1,18 @@
+import { fileURLToPath, URL } from 'node:url'
+
+import { defineConfig } from 'vite'
+import vue from '@vitejs/plugin-vue'
+import vueJsx from '@vitejs/plugin-vue-jsx'
+
+// https://vitejs.dev/config/
+export default defineConfig({
+ plugins: [
+ vue(),
+ vueJsx(),
+ ],
+ resolve: {
+ alias: {
+ '@': fileURLToPath(new URL('./src', import.meta.url))
+ }
+ }
+})
diff --git a/playground/typescript-jsx-router-playwright/.gitignore b/playground/typescript-jsx-router-playwright/.gitignore
new file mode 100644
index 000000000..aef72d03c
--- /dev/null
+++ b/playground/typescript-jsx-router-playwright/.gitignore
@@ -0,0 +1,33 @@
+# 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/
+
+# Editor directories and files
+.vscode/*
+!.vscode/extensions.json
+.idea
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?
+
+*.tsbuildinfo
+
+test-results/
+playwright-report/
diff --git a/playground/typescript-jsx-router-playwright/.vscode/extensions.json b/playground/typescript-jsx-router-playwright/.vscode/extensions.json
new file mode 100644
index 000000000..7b3f8bdae
--- /dev/null
+++ b/playground/typescript-jsx-router-playwright/.vscode/extensions.json
@@ -0,0 +1,3 @@
+{
+ "recommendations": ["ms-playwright.playwright"]
+}
diff --git a/playground/typescript-jsx-router-playwright/README.md b/playground/typescript-jsx-router-playwright/README.md
new file mode 100644
index 000000000..eaca2b354
--- /dev/null
+++ b/playground/typescript-jsx-router-playwright/README.md
@@ -0,0 +1,59 @@
+# typescript-jsx-router-playwright
+
+This template should help get you started developing with Vue 3 in Vite.
+
+## Recommended IDE Setup
+
+[VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur) + [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin).
+
+## Type Support for `.vue` Imports in TS
+
+TypeScript cannot handle type information for `.vue` imports by default, so we replace the `tsc` CLI with `vue-tsc` for type checking. In editors, we need [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin) to make the TypeScript language service aware of `.vue` types.
+
+If the standalone TypeScript plugin doesn't feel fast enough to you, Volar has also implemented a [Take Over Mode](https://github.com/johnsoncodehk/volar/discussions/471#discussioncomment-1361669) that is more performant. You can enable it by the following steps:
+
+1. Disable the built-in TypeScript Extension
+ 1) Run `Extensions: Show Built-in Extensions` from VSCode's command palette
+ 2) Find `TypeScript and JavaScript Language Features`, right click and select `Disable (Workspace)`
+2. Reload the VSCode window by running `Developer: Reload Window` from the command palette.
+
+## Customize configuration
+
+See [Vite Configuration Reference](https://vitejs.dev/config/).
+
+## Project Setup
+
+```sh
+pnpm install
+```
+
+### Compile and Hot-Reload for Development
+
+```sh
+pnpm dev
+```
+
+### Type-Check, Compile and Minify for Production
+
+```sh
+pnpm build
+```
+
+### Run End-to-End Tests with [Playwright](https://playwright.dev)
+
+```sh
+# Install browsers for the first run
+npx playwright install
+
+# When testing on CI, must build the project first
+pnpm build
+
+# Runs the end-to-end tests
+pnpm test:e2e
+# Runs the tests only on Chromium
+pnpm test:e2e --project=chromium
+# Runs the tests of a specific file
+pnpm test:e2e tests/example.spec.ts
+# Runs the tests in debug mode
+pnpm test:e2e --debug
+```
diff --git a/playground/typescript-jsx-router-playwright/e2e/tsconfig.json b/playground/typescript-jsx-router-playwright/e2e/tsconfig.json
new file mode 100644
index 000000000..be3bbfc0e
--- /dev/null
+++ b/playground/typescript-jsx-router-playwright/e2e/tsconfig.json
@@ -0,0 +1,4 @@
+{
+ "extends": "@tsconfig/node20/tsconfig.json",
+ "include": ["./**/*"]
+}
diff --git a/playground/typescript-jsx-router-playwright/e2e/vue.spec.ts b/playground/typescript-jsx-router-playwright/e2e/vue.spec.ts
new file mode 100644
index 000000000..3e5a3d02d
--- /dev/null
+++ b/playground/typescript-jsx-router-playwright/e2e/vue.spec.ts
@@ -0,0 +1,8 @@
+import { test, expect } from '@playwright/test';
+
+// See here how to get started:
+// https://playwright.dev/docs/intro
+test('visits the app root url', async ({ page }) => {
+ await page.goto('/');
+ await expect(page.locator('div.greetings > h1')).toHaveText('You did it!');
+})
diff --git a/playground/typescript-jsx-router-playwright/env.d.ts b/playground/typescript-jsx-router-playwright/env.d.ts
new file mode 100644
index 000000000..11f02fe2a
--- /dev/null
+++ b/playground/typescript-jsx-router-playwright/env.d.ts
@@ -0,0 +1 @@
+///
diff --git a/playground/typescript-jsx-router-playwright/index.html b/playground/typescript-jsx-router-playwright/index.html
new file mode 100644
index 000000000..a88854489
--- /dev/null
+++ b/playground/typescript-jsx-router-playwright/index.html
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+ Vite App
+
+
+
+
+
+
diff --git a/playground/typescript-jsx-router-playwright/package.json b/playground/typescript-jsx-router-playwright/package.json
new file mode 100644
index 000000000..a1afa5663
--- /dev/null
+++ b/playground/typescript-jsx-router-playwright/package.json
@@ -0,0 +1,30 @@
+{
+ "name": "typescript-jsx-router-playwright",
+ "version": "0.0.0",
+ "private": true,
+ "type": "module",
+ "scripts": {
+ "dev": "vite",
+ "build": "run-p type-check \"build-only {@}\" --",
+ "preview": "vite preview",
+ "test:e2e": "playwright test",
+ "build-only": "vite build",
+ "type-check": "vue-tsc --build --force"
+ },
+ "dependencies": {
+ "vue": "^3.4.15",
+ "vue-router": "^4.2.5"
+ },
+ "devDependencies": {
+ "@playwright/test": "^1.41.2",
+ "@tsconfig/node20": "^20.1.2",
+ "@types/node": "^20.11.16",
+ "@vitejs/plugin-vue": "^5.0.3",
+ "@vitejs/plugin-vue-jsx": "^3.1.0",
+ "@vue/tsconfig": "^0.5.1",
+ "npm-run-all2": "^6.1.2",
+ "typescript": "~5.3.0",
+ "vite": "^5.0.11",
+ "vue-tsc": "^1.8.27"
+ }
+}
diff --git a/playground/typescript-jsx-router-playwright/playwright.config.ts b/playground/typescript-jsx-router-playwright/playwright.config.ts
new file mode 100644
index 000000000..92075cc1b
--- /dev/null
+++ b/playground/typescript-jsx-router-playwright/playwright.config.ts
@@ -0,0 +1,110 @@
+import process from 'node:process'
+import { defineConfig, devices } from '@playwright/test'
+
+/**
+ * Read environment variables from file.
+ * https://github.com/motdotla/dotenv
+ */
+// require('dotenv').config();
+
+/**
+ * See https://playwright.dev/docs/test-configuration.
+ */
+export default defineConfig({
+ testDir: './e2e',
+ /* Maximum time one test can run for. */
+ timeout: 30 * 1000,
+ expect: {
+ /**
+ * Maximum time expect() should wait for the condition to be met.
+ * For example in `await expect(locator).toHaveText();`
+ */
+ timeout: 5000
+ },
+ /* Fail the build on CI if you accidentally left test.only in the source code. */
+ forbidOnly: !!process.env.CI,
+ /* Retry on CI only */
+ retries: process.env.CI ? 2 : 0,
+ /* Opt out of parallel tests on CI. */
+ workers: process.env.CI ? 1 : undefined,
+ /* Reporter to use. See https://playwright.dev/docs/test-reporters */
+ reporter: 'html',
+ /* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
+ use: {
+ /* Maximum time each action such as `click()` can take. Defaults to 0 (no limit). */
+ actionTimeout: 0,
+ /* Base URL to use in actions like `await page.goto('/')`. */
+ baseURL: 'http://localhost:5173',
+
+ /* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
+ trace: 'on-first-retry',
+
+ /* Only on CI systems run the tests headless */
+ headless: !!process.env.CI
+ },
+
+ /* Configure projects for major browsers */
+ projects: [
+ {
+ name: 'chromium',
+ use: {
+ ...devices['Desktop Chrome']
+ }
+ },
+ {
+ name: 'firefox',
+ use: {
+ ...devices['Desktop Firefox']
+ }
+ },
+ {
+ name: 'webkit',
+ use: {
+ ...devices['Desktop Safari']
+ }
+ }
+
+ /* Test against mobile viewports. */
+ // {
+ // name: 'Mobile Chrome',
+ // use: {
+ // ...devices['Pixel 5'],
+ // },
+ // },
+ // {
+ // name: 'Mobile Safari',
+ // use: {
+ // ...devices['iPhone 12'],
+ // },
+ // },
+
+ /* Test against branded browsers. */
+ // {
+ // name: 'Microsoft Edge',
+ // use: {
+ // channel: 'msedge',
+ // },
+ // },
+ // {
+ // name: 'Google Chrome',
+ // use: {
+ // channel: 'chrome',
+ // },
+ // },
+ ],
+
+ /* Folder for test artifacts such as screenshots, videos, traces, etc. */
+ // outputDir: 'test-results/',
+
+ /* Run your local dev server before starting the tests */
+ webServer: {
+ /**
+ * Use the dev server by default for faster feedback loop.
+ * Use the preview server on CI for more realistic testing.
+ * Playwright will re-use the local server if there is already a dev-server running.
+ */
+ command: process.env.CI ? 'vite preview --port 5173' : 'vite dev',
+ port: 5173,
+ reuseExistingServer: !process.env.CI
+ }
+})
diff --git a/playground/typescript-jsx-router-playwright/public/favicon.ico b/playground/typescript-jsx-router-playwright/public/favicon.ico
new file mode 100644
index 000000000..df36fcfb7
Binary files /dev/null and b/playground/typescript-jsx-router-playwright/public/favicon.ico differ
diff --git a/playground/typescript-jsx-router-playwright/src/App.vue b/playground/typescript-jsx-router-playwright/src/App.vue
new file mode 100644
index 000000000..7905b0516
--- /dev/null
+++ b/playground/typescript-jsx-router-playwright/src/App.vue
@@ -0,0 +1,85 @@
+
+
+
+
+
+
+
+ You’ve successfully created a project with
+ Vite +
+ Vue 3. What's next?
+
+
+
+
+
diff --git a/playground/typescript-jsx-router-playwright/src/components/TheWelcome.vue b/playground/typescript-jsx-router-playwright/src/components/TheWelcome.vue
new file mode 100644
index 000000000..49d8f7354
--- /dev/null
+++ b/playground/typescript-jsx-router-playwright/src/components/TheWelcome.vue
@@ -0,0 +1,88 @@
+
+
+
+
+
+
+
+ Documentation
+
+ Vue’s
+ official documentation
+ provides you with all information you need to get started.
+
+
+
+
+
+
+ Tooling
+
+ This project is served and bundled with
+ Vite. The
+ recommended IDE setup is
+ VSCode +
+ Volar. If
+ you need to test your components and web pages, check out
+ Cypress and
+ Cypress Component Testing.
+
+
+
+ More instructions are available in README.md.
+
+
+
+
+
+
+ Ecosystem
+
+ Get official tools and libraries for your project:
+ Pinia,
+ Vue Router,
+ Vue Test Utils, and
+ Vue Dev Tools. If
+ you need more resources, we suggest paying
+ Awesome Vue
+ a visit.
+
+
+
+
+
+
+ Community
+
+ Got stuck? Ask your question on
+ Vue Land, our official
+ Discord server, or
+ StackOverflow. You should also subscribe to
+ our mailing list and follow
+ the official
+ @vuejs
+ twitter account for latest news in the Vue world.
+
+
+
+
+
+
+ Support Vue
+
+ As an independent project, Vue relies on community backing for its sustainability. You can help
+ us by
+ becoming a sponsor.
+
+
diff --git a/playground/typescript-jsx-router-playwright/src/components/WelcomeItem.vue b/playground/typescript-jsx-router-playwright/src/components/WelcomeItem.vue
new file mode 100644
index 000000000..6d7086aea
--- /dev/null
+++ b/playground/typescript-jsx-router-playwright/src/components/WelcomeItem.vue
@@ -0,0 +1,87 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/playground/typescript-jsx-router-playwright/src/components/icons/IconCommunity.vue b/playground/typescript-jsx-router-playwright/src/components/icons/IconCommunity.vue
new file mode 100644
index 000000000..2dc8b0552
--- /dev/null
+++ b/playground/typescript-jsx-router-playwright/src/components/icons/IconCommunity.vue
@@ -0,0 +1,7 @@
+
+
+
diff --git a/playground/typescript-jsx-router-playwright/src/components/icons/IconDocumentation.vue b/playground/typescript-jsx-router-playwright/src/components/icons/IconDocumentation.vue
new file mode 100644
index 000000000..6d4791cfb
--- /dev/null
+++ b/playground/typescript-jsx-router-playwright/src/components/icons/IconDocumentation.vue
@@ -0,0 +1,7 @@
+
+
+
diff --git a/playground/typescript-jsx-router-playwright/src/components/icons/IconEcosystem.vue b/playground/typescript-jsx-router-playwright/src/components/icons/IconEcosystem.vue
new file mode 100644
index 000000000..c3a4f078c
--- /dev/null
+++ b/playground/typescript-jsx-router-playwright/src/components/icons/IconEcosystem.vue
@@ -0,0 +1,7 @@
+
+
+
diff --git a/playground/typescript-jsx-router-playwright/src/components/icons/IconSupport.vue b/playground/typescript-jsx-router-playwright/src/components/icons/IconSupport.vue
new file mode 100644
index 000000000..7452834d3
--- /dev/null
+++ b/playground/typescript-jsx-router-playwright/src/components/icons/IconSupport.vue
@@ -0,0 +1,7 @@
+
+
+
diff --git a/playground/typescript-jsx-router-playwright/src/components/icons/IconTooling.vue b/playground/typescript-jsx-router-playwright/src/components/icons/IconTooling.vue
new file mode 100644
index 000000000..660598d7c
--- /dev/null
+++ b/playground/typescript-jsx-router-playwright/src/components/icons/IconTooling.vue
@@ -0,0 +1,19 @@
+
+
+
+
diff --git a/playground/typescript-jsx-router-playwright/src/main.ts b/playground/typescript-jsx-router-playwright/src/main.ts
new file mode 100644
index 000000000..5a5dbdba7
--- /dev/null
+++ b/playground/typescript-jsx-router-playwright/src/main.ts
@@ -0,0 +1,11 @@
+import './assets/main.css'
+
+import { createApp } from 'vue'
+import App from './App.vue'
+import router from './router'
+
+const app = createApp(App)
+
+app.use(router)
+
+app.mount('#app')
diff --git a/playground/typescript-jsx-router-playwright/src/router/index.ts b/playground/typescript-jsx-router-playwright/src/router/index.ts
new file mode 100644
index 000000000..a49ae507f
--- /dev/null
+++ b/playground/typescript-jsx-router-playwright/src/router/index.ts
@@ -0,0 +1,23 @@
+import { createRouter, createWebHistory } from 'vue-router'
+import HomeView from '../views/HomeView.vue'
+
+const router = createRouter({
+ history: createWebHistory(import.meta.env.BASE_URL),
+ routes: [
+ {
+ path: '/',
+ name: 'home',
+ component: HomeView
+ },
+ {
+ path: '/about',
+ name: 'about',
+ // route level code-splitting
+ // this generates a separate chunk (About.[hash].js) for this route
+ // which is lazy-loaded when the route is visited.
+ component: () => import('../views/AboutView.vue')
+ }
+ ]
+})
+
+export default router
diff --git a/playground/typescript-jsx-router-playwright/src/views/AboutView.vue b/playground/typescript-jsx-router-playwright/src/views/AboutView.vue
new file mode 100644
index 000000000..756ad2a17
--- /dev/null
+++ b/playground/typescript-jsx-router-playwright/src/views/AboutView.vue
@@ -0,0 +1,15 @@
+
+
+
This is an about page
+
+
+
+
diff --git a/playground/typescript-jsx-router-playwright/src/views/HomeView.vue b/playground/typescript-jsx-router-playwright/src/views/HomeView.vue
new file mode 100644
index 000000000..d5c0217e4
--- /dev/null
+++ b/playground/typescript-jsx-router-playwright/src/views/HomeView.vue
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
diff --git a/playground/typescript-jsx-router-playwright/tsconfig.app.json b/playground/typescript-jsx-router-playwright/tsconfig.app.json
new file mode 100644
index 000000000..e14c754d3
--- /dev/null
+++ b/playground/typescript-jsx-router-playwright/tsconfig.app.json
@@ -0,0 +1,14 @@
+{
+ "extends": "@vue/tsconfig/tsconfig.dom.json",
+ "include": ["env.d.ts", "src/**/*", "src/**/*.vue"],
+ "exclude": ["src/**/__tests__/*"],
+ "compilerOptions": {
+ "composite": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
+
+ "baseUrl": ".",
+ "paths": {
+ "@/*": ["./src/*"]
+ }
+ }
+}
diff --git a/playground/typescript-jsx-router-playwright/tsconfig.json b/playground/typescript-jsx-router-playwright/tsconfig.json
new file mode 100644
index 000000000..66b5e5703
--- /dev/null
+++ b/playground/typescript-jsx-router-playwright/tsconfig.json
@@ -0,0 +1,11 @@
+{
+ "files": [],
+ "references": [
+ {
+ "path": "./tsconfig.node.json"
+ },
+ {
+ "path": "./tsconfig.app.json"
+ }
+ ]
+}
diff --git a/playground/typescript-jsx-router-playwright/tsconfig.node.json b/playground/typescript-jsx-router-playwright/tsconfig.node.json
new file mode 100644
index 000000000..f09406303
--- /dev/null
+++ b/playground/typescript-jsx-router-playwright/tsconfig.node.json
@@ -0,0 +1,19 @@
+{
+ "extends": "@tsconfig/node20/tsconfig.json",
+ "include": [
+ "vite.config.*",
+ "vitest.config.*",
+ "cypress.config.*",
+ "nightwatch.conf.*",
+ "playwright.config.*"
+ ],
+ "compilerOptions": {
+ "composite": true,
+ "noEmit": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
+
+ "module": "ESNext",
+ "moduleResolution": "Bundler",
+ "types": ["node"]
+ }
+}
diff --git a/playground/typescript-jsx-router-playwright/vite.config.ts b/playground/typescript-jsx-router-playwright/vite.config.ts
new file mode 100644
index 000000000..36c618756
--- /dev/null
+++ b/playground/typescript-jsx-router-playwright/vite.config.ts
@@ -0,0 +1,18 @@
+import { fileURLToPath, URL } from 'node:url'
+
+import { defineConfig } from 'vite'
+import vue from '@vitejs/plugin-vue'
+import vueJsx from '@vitejs/plugin-vue-jsx'
+
+// https://vitejs.dev/config/
+export default defineConfig({
+ plugins: [
+ vue(),
+ vueJsx(),
+ ],
+ resolve: {
+ alias: {
+ '@': fileURLToPath(new URL('./src', import.meta.url))
+ }
+ }
+})
diff --git a/playground/typescript-jsx-router-vitest-cypress/.gitignore b/playground/typescript-jsx-router-vitest-cypress/.gitignore
new file mode 100644
index 000000000..8ee54e8d3
--- /dev/null
+++ b/playground/typescript-jsx-router-vitest-cypress/.gitignore
@@ -0,0 +1,30 @@
+# 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/
+
+# Editor directories and files
+.vscode/*
+!.vscode/extensions.json
+.idea
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?
+
+*.tsbuildinfo
diff --git a/playground/typescript-jsx-router-vitest-cypress/README.md b/playground/typescript-jsx-router-vitest-cypress/README.md
new file mode 100644
index 000000000..8cdb45fc0
--- /dev/null
+++ b/playground/typescript-jsx-router-vitest-cypress/README.md
@@ -0,0 +1,62 @@
+# typescript-jsx-router-vitest-cypress
+
+This template should help get you started developing with Vue 3 in Vite.
+
+## Recommended IDE Setup
+
+[VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur) + [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin).
+
+## Type Support for `.vue` Imports in TS
+
+TypeScript cannot handle type information for `.vue` imports by default, so we replace the `tsc` CLI with `vue-tsc` for type checking. In editors, we need [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin) to make the TypeScript language service aware of `.vue` types.
+
+If the standalone TypeScript plugin doesn't feel fast enough to you, Volar has also implemented a [Take Over Mode](https://github.com/johnsoncodehk/volar/discussions/471#discussioncomment-1361669) that is more performant. You can enable it by the following steps:
+
+1. Disable the built-in TypeScript Extension
+ 1) Run `Extensions: Show Built-in Extensions` from VSCode's command palette
+ 2) Find `TypeScript and JavaScript Language Features`, right click and select `Disable (Workspace)`
+2. Reload the VSCode window by running `Developer: Reload Window` from the command palette.
+
+## Customize configuration
+
+See [Vite Configuration Reference](https://vitejs.dev/config/).
+
+## Project Setup
+
+```sh
+pnpm install
+```
+
+### Compile and Hot-Reload for Development
+
+```sh
+pnpm dev
+```
+
+### Type-Check, Compile and Minify for Production
+
+```sh
+pnpm build
+```
+
+### Run Unit Tests with [Vitest](https://vitest.dev/)
+
+```sh
+pnpm test:unit
+```
+
+### Run End-to-End Tests with [Cypress](https://www.cypress.io/)
+
+```sh
+pnpm test:e2e:dev
+```
+
+This runs the end-to-end tests against the Vite development server.
+It is much faster than the production build.
+
+But it's still recommended to test the production build with `test:e2e` before deploying (e.g. in CI environments):
+
+```sh
+pnpm build
+pnpm test:e2e
+```
diff --git a/playground/typescript-jsx-router-vitest-cypress/cypress.config.ts b/playground/typescript-jsx-router-vitest-cypress/cypress.config.ts
new file mode 100644
index 000000000..0f66080fd
--- /dev/null
+++ b/playground/typescript-jsx-router-vitest-cypress/cypress.config.ts
@@ -0,0 +1,8 @@
+import { defineConfig } from 'cypress'
+
+export default defineConfig({
+ e2e: {
+ specPattern: 'cypress/e2e/**/*.{cy,spec}.{js,jsx,ts,tsx}',
+ baseUrl: 'http://localhost:4173'
+ }
+})
diff --git a/playground/typescript-jsx-router-vitest-cypress/cypress/e2e/example.cy.ts b/playground/typescript-jsx-router-vitest-cypress/cypress/e2e/example.cy.ts
new file mode 100644
index 000000000..7554c35d8
--- /dev/null
+++ b/playground/typescript-jsx-router-vitest-cypress/cypress/e2e/example.cy.ts
@@ -0,0 +1,8 @@
+// https://on.cypress.io/api
+
+describe('My First Test', () => {
+ it('visits the app root url', () => {
+ cy.visit('/')
+ cy.contains('h1', 'You did it!')
+ })
+})
diff --git a/playground/typescript-jsx-router-vitest-cypress/cypress/e2e/tsconfig.json b/playground/typescript-jsx-router-vitest-cypress/cypress/e2e/tsconfig.json
new file mode 100644
index 000000000..37748feb7
--- /dev/null
+++ b/playground/typescript-jsx-router-vitest-cypress/cypress/e2e/tsconfig.json
@@ -0,0 +1,10 @@
+{
+ "extends": "@vue/tsconfig/tsconfig.dom.json",
+ "include": ["./**/*", "../support/**/*"],
+ "compilerOptions": {
+ "isolatedModules": false,
+ "target": "es5",
+ "lib": ["es5", "dom"],
+ "types": ["cypress"]
+ }
+}
diff --git a/playground/typescript-jsx-router-vitest-cypress/cypress/fixtures/example.json b/playground/typescript-jsx-router-vitest-cypress/cypress/fixtures/example.json
new file mode 100644
index 000000000..02e425437
--- /dev/null
+++ b/playground/typescript-jsx-router-vitest-cypress/cypress/fixtures/example.json
@@ -0,0 +1,5 @@
+{
+ "name": "Using fixtures to represent data",
+ "email": "hello@cypress.io",
+ "body": "Fixtures are a great way to mock data for responses to routes"
+}
diff --git a/playground/typescript-jsx-router-vitest-cypress/cypress/support/commands.ts b/playground/typescript-jsx-router-vitest-cypress/cypress/support/commands.ts
new file mode 100644
index 000000000..9b7bb8e25
--- /dev/null
+++ b/playground/typescript-jsx-router-vitest-cypress/cypress/support/commands.ts
@@ -0,0 +1,39 @@
+///
+// ***********************************************
+// This example commands.ts shows you how to
+// create various custom commands and overwrite
+// existing commands.
+//
+// For more comprehensive examples of custom
+// commands please read more here:
+// https://on.cypress.io/custom-commands
+// ***********************************************
+//
+//
+// -- This is a parent command --
+// Cypress.Commands.add('login', (email, password) => { ... })
+//
+//
+// -- This is a child command --
+// Cypress.Commands.add('drag', { prevSubject: 'element'}, (subject, options) => { ... })
+//
+//
+// -- This is a dual command --
+// Cypress.Commands.add('dismiss', { prevSubject: 'optional'}, (subject, options) => { ... })
+//
+//
+// -- This will overwrite an existing command --
+// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... })
+//
+// declare global {
+// namespace Cypress {
+// interface Chainable {
+// login(email: string, password: string): Chainable
+// drag(subject: string, options?: Partial): Chainable
+// dismiss(subject: string, options?: Partial): Chainable
+// visit(originalFn: CommandOriginalFn, url: string, options: Partial): Chainable
+// }
+// }
+// }
+
+export {}
diff --git a/playground/typescript-jsx-router-vitest-cypress/cypress/support/e2e.ts b/playground/typescript-jsx-router-vitest-cypress/cypress/support/e2e.ts
new file mode 100644
index 000000000..d68db96df
--- /dev/null
+++ b/playground/typescript-jsx-router-vitest-cypress/cypress/support/e2e.ts
@@ -0,0 +1,20 @@
+// ***********************************************************
+// This example support/index.js is processed and
+// loaded automatically before your test files.
+//
+// This is a great place to put global configuration and
+// behavior that modifies Cypress.
+//
+// You can change the location of this file or turn off
+// automatically serving support files with the
+// 'supportFile' configuration option.
+//
+// You can read more here:
+// https://on.cypress.io/configuration
+// ***********************************************************
+
+// Import commands.js using ES2015 syntax:
+import './commands'
+
+// Alternatively you can use CommonJS syntax:
+// require('./commands')
diff --git a/playground/typescript-jsx-router-vitest-cypress/env.d.ts b/playground/typescript-jsx-router-vitest-cypress/env.d.ts
new file mode 100644
index 000000000..11f02fe2a
--- /dev/null
+++ b/playground/typescript-jsx-router-vitest-cypress/env.d.ts
@@ -0,0 +1 @@
+///
diff --git a/playground/typescript-jsx-router-vitest-cypress/index.html b/playground/typescript-jsx-router-vitest-cypress/index.html
new file mode 100644
index 000000000..a88854489
--- /dev/null
+++ b/playground/typescript-jsx-router-vitest-cypress/index.html
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+ Vite App
+
+
+
+
+
+
diff --git a/playground/typescript-jsx-router-vitest-cypress/package.json b/playground/typescript-jsx-router-vitest-cypress/package.json
new file mode 100644
index 000000000..5e61eaab6
--- /dev/null
+++ b/playground/typescript-jsx-router-vitest-cypress/package.json
@@ -0,0 +1,37 @@
+{
+ "name": "typescript-jsx-router-vitest-cypress",
+ "version": "0.0.0",
+ "private": true,
+ "type": "module",
+ "scripts": {
+ "dev": "vite",
+ "build": "run-p type-check \"build-only {@}\" --",
+ "preview": "vite preview",
+ "test:unit": "vitest",
+ "test:e2e": "start-server-and-test preview http://localhost:4173 'cypress run --e2e'",
+ "test:e2e:dev": "start-server-and-test 'vite dev --port 4173' http://localhost:4173 'cypress open --e2e'",
+ "build-only": "vite build",
+ "type-check": "vue-tsc --build --force"
+ },
+ "dependencies": {
+ "vue": "^3.4.15",
+ "vue-router": "^4.2.5"
+ },
+ "devDependencies": {
+ "@tsconfig/node20": "^20.1.2",
+ "@types/jsdom": "^21.1.6",
+ "@types/node": "^20.11.16",
+ "@vitejs/plugin-vue": "^5.0.3",
+ "@vitejs/plugin-vue-jsx": "^3.1.0",
+ "@vue/test-utils": "^2.4.4",
+ "@vue/tsconfig": "^0.5.1",
+ "cypress": "^13.6.4",
+ "jsdom": "^24.0.0",
+ "npm-run-all2": "^6.1.2",
+ "start-server-and-test": "^2.0.3",
+ "typescript": "~5.3.0",
+ "vite": "^5.0.11",
+ "vitest": "^1.2.2",
+ "vue-tsc": "^1.8.27"
+ }
+}
diff --git a/playground/typescript-jsx-router-vitest-cypress/public/favicon.ico b/playground/typescript-jsx-router-vitest-cypress/public/favicon.ico
new file mode 100644
index 000000000..df36fcfb7
Binary files /dev/null and b/playground/typescript-jsx-router-vitest-cypress/public/favicon.ico differ
diff --git a/playground/typescript-jsx-router-vitest-cypress/src/App.vue b/playground/typescript-jsx-router-vitest-cypress/src/App.vue
new file mode 100644
index 000000000..7905b0516
--- /dev/null
+++ b/playground/typescript-jsx-router-vitest-cypress/src/App.vue
@@ -0,0 +1,85 @@
+
+
+
+
+
+
+
+ You’ve successfully created a project with
+ Vite +
+ Vue 3. What's next?
+
+
+
+
+
diff --git a/playground/typescript-jsx-router-vitest-cypress/src/components/TheWelcome.vue b/playground/typescript-jsx-router-vitest-cypress/src/components/TheWelcome.vue
new file mode 100644
index 000000000..49d8f7354
--- /dev/null
+++ b/playground/typescript-jsx-router-vitest-cypress/src/components/TheWelcome.vue
@@ -0,0 +1,88 @@
+
+
+
+
+
+
+
+ Documentation
+
+ Vue’s
+ official documentation
+ provides you with all information you need to get started.
+
+
+
+
+
+
+ Tooling
+
+ This project is served and bundled with
+ Vite. The
+ recommended IDE setup is
+ VSCode +
+ Volar. If
+ you need to test your components and web pages, check out
+ Cypress and
+ Cypress Component Testing.
+
+
+
+ More instructions are available in README.md.
+
+
+
+
+
+
+ Ecosystem
+
+ Get official tools and libraries for your project:
+ Pinia,
+ Vue Router,
+ Vue Test Utils, and
+ Vue Dev Tools. If
+ you need more resources, we suggest paying
+ Awesome Vue
+ a visit.
+
+
+
+
+
+
+ Community
+
+ Got stuck? Ask your question on
+ Vue Land, our official
+ Discord server, or
+ StackOverflow. You should also subscribe to
+ our mailing list and follow
+ the official
+ @vuejs
+ twitter account for latest news in the Vue world.
+
+
+
+
+
+
+ Support Vue
+
+ As an independent project, Vue relies on community backing for its sustainability. You can help
+ us by
+ becoming a sponsor.
+
+
diff --git a/playground/typescript-jsx-router-vitest-cypress/src/components/WelcomeItem.vue b/playground/typescript-jsx-router-vitest-cypress/src/components/WelcomeItem.vue
new file mode 100644
index 000000000..6d7086aea
--- /dev/null
+++ b/playground/typescript-jsx-router-vitest-cypress/src/components/WelcomeItem.vue
@@ -0,0 +1,87 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/playground/typescript-jsx-router-vitest-cypress/src/components/__tests__/HelloWorld.spec.ts b/playground/typescript-jsx-router-vitest-cypress/src/components/__tests__/HelloWorld.spec.ts
new file mode 100644
index 000000000..253320200
--- /dev/null
+++ b/playground/typescript-jsx-router-vitest-cypress/src/components/__tests__/HelloWorld.spec.ts
@@ -0,0 +1,11 @@
+import { describe, it, expect } from 'vitest'
+
+import { mount } from '@vue/test-utils'
+import HelloWorld from '../HelloWorld.vue'
+
+describe('HelloWorld', () => {
+ it('renders properly', () => {
+ const wrapper = mount(HelloWorld, { props: { msg: 'Hello Vitest' } })
+ expect(wrapper.text()).toContain('Hello Vitest')
+ })
+})
diff --git a/playground/typescript-jsx-router-vitest-cypress/src/components/icons/IconCommunity.vue b/playground/typescript-jsx-router-vitest-cypress/src/components/icons/IconCommunity.vue
new file mode 100644
index 000000000..2dc8b0552
--- /dev/null
+++ b/playground/typescript-jsx-router-vitest-cypress/src/components/icons/IconCommunity.vue
@@ -0,0 +1,7 @@
+
+
+
diff --git a/playground/typescript-jsx-router-vitest-cypress/src/components/icons/IconDocumentation.vue b/playground/typescript-jsx-router-vitest-cypress/src/components/icons/IconDocumentation.vue
new file mode 100644
index 000000000..6d4791cfb
--- /dev/null
+++ b/playground/typescript-jsx-router-vitest-cypress/src/components/icons/IconDocumentation.vue
@@ -0,0 +1,7 @@
+
+
+
diff --git a/playground/typescript-jsx-router-vitest-cypress/src/components/icons/IconEcosystem.vue b/playground/typescript-jsx-router-vitest-cypress/src/components/icons/IconEcosystem.vue
new file mode 100644
index 000000000..c3a4f078c
--- /dev/null
+++ b/playground/typescript-jsx-router-vitest-cypress/src/components/icons/IconEcosystem.vue
@@ -0,0 +1,7 @@
+
+
+
diff --git a/playground/typescript-jsx-router-vitest-cypress/src/components/icons/IconSupport.vue b/playground/typescript-jsx-router-vitest-cypress/src/components/icons/IconSupport.vue
new file mode 100644
index 000000000..7452834d3
--- /dev/null
+++ b/playground/typescript-jsx-router-vitest-cypress/src/components/icons/IconSupport.vue
@@ -0,0 +1,7 @@
+
+
+
diff --git a/playground/typescript-jsx-router-vitest-cypress/src/components/icons/IconTooling.vue b/playground/typescript-jsx-router-vitest-cypress/src/components/icons/IconTooling.vue
new file mode 100644
index 000000000..660598d7c
--- /dev/null
+++ b/playground/typescript-jsx-router-vitest-cypress/src/components/icons/IconTooling.vue
@@ -0,0 +1,19 @@
+
+
+
+
diff --git a/playground/typescript-jsx-router-vitest-cypress/src/main.ts b/playground/typescript-jsx-router-vitest-cypress/src/main.ts
new file mode 100644
index 000000000..5a5dbdba7
--- /dev/null
+++ b/playground/typescript-jsx-router-vitest-cypress/src/main.ts
@@ -0,0 +1,11 @@
+import './assets/main.css'
+
+import { createApp } from 'vue'
+import App from './App.vue'
+import router from './router'
+
+const app = createApp(App)
+
+app.use(router)
+
+app.mount('#app')
diff --git a/playground/typescript-jsx-router-vitest-cypress/src/router/index.ts b/playground/typescript-jsx-router-vitest-cypress/src/router/index.ts
new file mode 100644
index 000000000..a49ae507f
--- /dev/null
+++ b/playground/typescript-jsx-router-vitest-cypress/src/router/index.ts
@@ -0,0 +1,23 @@
+import { createRouter, createWebHistory } from 'vue-router'
+import HomeView from '../views/HomeView.vue'
+
+const router = createRouter({
+ history: createWebHistory(import.meta.env.BASE_URL),
+ routes: [
+ {
+ path: '/',
+ name: 'home',
+ component: HomeView
+ },
+ {
+ path: '/about',
+ name: 'about',
+ // route level code-splitting
+ // this generates a separate chunk (About.[hash].js) for this route
+ // which is lazy-loaded when the route is visited.
+ component: () => import('../views/AboutView.vue')
+ }
+ ]
+})
+
+export default router
diff --git a/playground/typescript-jsx-router-vitest-cypress/src/views/AboutView.vue b/playground/typescript-jsx-router-vitest-cypress/src/views/AboutView.vue
new file mode 100644
index 000000000..756ad2a17
--- /dev/null
+++ b/playground/typescript-jsx-router-vitest-cypress/src/views/AboutView.vue
@@ -0,0 +1,15 @@
+
+
+
This is an about page
+
+
+
+
diff --git a/playground/typescript-jsx-router-vitest-cypress/src/views/HomeView.vue b/playground/typescript-jsx-router-vitest-cypress/src/views/HomeView.vue
new file mode 100644
index 000000000..d5c0217e4
--- /dev/null
+++ b/playground/typescript-jsx-router-vitest-cypress/src/views/HomeView.vue
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
diff --git a/playground/typescript-jsx-router-vitest-cypress/tsconfig.app.json b/playground/typescript-jsx-router-vitest-cypress/tsconfig.app.json
new file mode 100644
index 000000000..e14c754d3
--- /dev/null
+++ b/playground/typescript-jsx-router-vitest-cypress/tsconfig.app.json
@@ -0,0 +1,14 @@
+{
+ "extends": "@vue/tsconfig/tsconfig.dom.json",
+ "include": ["env.d.ts", "src/**/*", "src/**/*.vue"],
+ "exclude": ["src/**/__tests__/*"],
+ "compilerOptions": {
+ "composite": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
+
+ "baseUrl": ".",
+ "paths": {
+ "@/*": ["./src/*"]
+ }
+ }
+}
diff --git a/playground/typescript-jsx-router-vitest-cypress/tsconfig.json b/playground/typescript-jsx-router-vitest-cypress/tsconfig.json
new file mode 100644
index 000000000..5304731b8
--- /dev/null
+++ b/playground/typescript-jsx-router-vitest-cypress/tsconfig.json
@@ -0,0 +1,17 @@
+{
+ "files": [],
+ "references": [
+ {
+ "path": "./tsconfig.node.json"
+ },
+ {
+ "path": "./tsconfig.app.json"
+ },
+ {
+ "path": "./tsconfig.vitest.json"
+ }
+ ],
+ "compilerOptions": {
+ "module": "NodeNext"
+ }
+}
diff --git a/playground/typescript-jsx-router-vitest-cypress/tsconfig.node.json b/playground/typescript-jsx-router-vitest-cypress/tsconfig.node.json
new file mode 100644
index 000000000..f09406303
--- /dev/null
+++ b/playground/typescript-jsx-router-vitest-cypress/tsconfig.node.json
@@ -0,0 +1,19 @@
+{
+ "extends": "@tsconfig/node20/tsconfig.json",
+ "include": [
+ "vite.config.*",
+ "vitest.config.*",
+ "cypress.config.*",
+ "nightwatch.conf.*",
+ "playwright.config.*"
+ ],
+ "compilerOptions": {
+ "composite": true,
+ "noEmit": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
+
+ "module": "ESNext",
+ "moduleResolution": "Bundler",
+ "types": ["node"]
+ }
+}
diff --git a/playground/typescript-jsx-router-vitest-cypress/tsconfig.vitest.json b/playground/typescript-jsx-router-vitest-cypress/tsconfig.vitest.json
new file mode 100644
index 000000000..571995d11
--- /dev/null
+++ b/playground/typescript-jsx-router-vitest-cypress/tsconfig.vitest.json
@@ -0,0 +1,11 @@
+{
+ "extends": "./tsconfig.app.json",
+ "exclude": [],
+ "compilerOptions": {
+ "composite": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.vitest.tsbuildinfo",
+
+ "lib": [],
+ "types": ["node", "jsdom"]
+ }
+}
diff --git a/playground/typescript-jsx-router-vitest-cypress/vite.config.ts b/playground/typescript-jsx-router-vitest-cypress/vite.config.ts
new file mode 100644
index 000000000..36c618756
--- /dev/null
+++ b/playground/typescript-jsx-router-vitest-cypress/vite.config.ts
@@ -0,0 +1,18 @@
+import { fileURLToPath, URL } from 'node:url'
+
+import { defineConfig } from 'vite'
+import vue from '@vitejs/plugin-vue'
+import vueJsx from '@vitejs/plugin-vue-jsx'
+
+// https://vitejs.dev/config/
+export default defineConfig({
+ plugins: [
+ vue(),
+ vueJsx(),
+ ],
+ resolve: {
+ alias: {
+ '@': fileURLToPath(new URL('./src', import.meta.url))
+ }
+ }
+})
diff --git a/playground/typescript-jsx-router-vitest-cypress/vitest.config.ts b/playground/typescript-jsx-router-vitest-cypress/vitest.config.ts
new file mode 100644
index 000000000..10067d578
--- /dev/null
+++ b/playground/typescript-jsx-router-vitest-cypress/vitest.config.ts
@@ -0,0 +1,14 @@
+import { fileURLToPath } from 'node:url'
+import { mergeConfig, defineConfig, configDefaults } from 'vitest/config'
+import viteConfig from './vite.config'
+
+export default mergeConfig(
+ viteConfig,
+ defineConfig({
+ test: {
+ environment: 'jsdom',
+ exclude: [...configDefaults.exclude, 'e2e/*'],
+ root: fileURLToPath(new URL('./', import.meta.url))
+ }
+ })
+)
diff --git a/playground/typescript-jsx-router-vitest-nightwatch/.gitignore b/playground/typescript-jsx-router-vitest-nightwatch/.gitignore
new file mode 100644
index 000000000..0b938f131
--- /dev/null
+++ b/playground/typescript-jsx-router-vitest-nightwatch/.gitignore
@@ -0,0 +1,33 @@
+# 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/
+
+# Editor directories and files
+.vscode/*
+!.vscode/extensions.json
+.idea
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?
+
+*.tsbuildinfo
+
+logs/
+tests_output/
diff --git a/playground/typescript-jsx-router-vitest-nightwatch/.vscode/extensions.json b/playground/typescript-jsx-router-vitest-nightwatch/.vscode/extensions.json
new file mode 100644
index 000000000..dd9668a5c
--- /dev/null
+++ b/playground/typescript-jsx-router-vitest-nightwatch/.vscode/extensions.json
@@ -0,0 +1,3 @@
+{
+ "recommendations": ["browserstackcom.nightwatch"]
+}
diff --git a/playground/typescript-jsx-router-vitest-nightwatch/README.md b/playground/typescript-jsx-router-vitest-nightwatch/README.md
new file mode 100644
index 000000000..1617507ad
--- /dev/null
+++ b/playground/typescript-jsx-router-vitest-nightwatch/README.md
@@ -0,0 +1,69 @@
+# typescript-jsx-router-vitest-nightwatch
+
+This template should help get you started developing with Vue 3 in Vite.
+
+## Recommended IDE Setup
+
+[VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur) + [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin).
+
+## Type Support for `.vue` Imports in TS
+
+TypeScript cannot handle type information for `.vue` imports by default, so we replace the `tsc` CLI with `vue-tsc` for type checking. In editors, we need [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin) to make the TypeScript language service aware of `.vue` types.
+
+If the standalone TypeScript plugin doesn't feel fast enough to you, Volar has also implemented a [Take Over Mode](https://github.com/johnsoncodehk/volar/discussions/471#discussioncomment-1361669) that is more performant. You can enable it by the following steps:
+
+1. Disable the built-in TypeScript Extension
+ 1) Run `Extensions: Show Built-in Extensions` from VSCode's command palette
+ 2) Find `TypeScript and JavaScript Language Features`, right click and select `Disable (Workspace)`
+2. Reload the VSCode window by running `Developer: Reload Window` from the command palette.
+
+## Customize configuration
+
+See [Vite Configuration Reference](https://vitejs.dev/config/).
+
+## Project Setup
+
+```sh
+pnpm install
+```
+
+### Compile and Hot-Reload for Development
+
+```sh
+pnpm dev
+```
+
+### Type-Check, Compile and Minify for Production
+
+```sh
+pnpm build
+```
+
+### Run Unit Tests with [Vitest](https://vitest.dev/)
+
+```sh
+pnpm test:unit
+```
+
+### Run End-to-End Tests with [Nightwatch](https://nightwatchjs.org/)
+
+```sh
+# When using CI, the project must be built first.
+pnpm build
+
+# Runs the end-to-end tests
+pnpm test:e2e
+# Runs the tests only on Chrome
+pnpm test:e2e --env chrome
+# Runs the tests of a specific file
+pnpm test:e2e tests/e2e/example.ts
+# Runs the tests in debug mode
+pnpm test:e2e --debug
+```
+
+### Run Headed Component Tests with [Nightwatch Component Testing](https://nightwatchjs.org/guide/component-testing/introduction.html)
+
+```sh
+pnpm test:unit
+pnpm test:unit -- --headless # for headless testing
+```
diff --git a/playground/typescript-jsx-router-vitest-nightwatch/env.d.ts b/playground/typescript-jsx-router-vitest-nightwatch/env.d.ts
new file mode 100644
index 000000000..11f02fe2a
--- /dev/null
+++ b/playground/typescript-jsx-router-vitest-nightwatch/env.d.ts
@@ -0,0 +1 @@
+///
diff --git a/playground/typescript-jsx-router-vitest-nightwatch/index.html b/playground/typescript-jsx-router-vitest-nightwatch/index.html
new file mode 100644
index 000000000..a88854489
--- /dev/null
+++ b/playground/typescript-jsx-router-vitest-nightwatch/index.html
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+ Vite App
+
+
+
+
+
+
diff --git a/playground/typescript-jsx-router-vitest-nightwatch/nightwatch.conf.cjs b/playground/typescript-jsx-router-vitest-nightwatch/nightwatch.conf.cjs
new file mode 100644
index 000000000..542647e5e
--- /dev/null
+++ b/playground/typescript-jsx-router-vitest-nightwatch/nightwatch.conf.cjs
@@ -0,0 +1,153 @@
+//
+// Refer to the online docs for more details:
+// https://nightwatchjs.org/guide/configuration/nightwatch-configuration-file.html
+//
+// _ _ _ _ _ _ _
+// | \ | |(_) | | | | | | | |
+// | \| | _ __ _ | |__ | |_ __ __ __ _ | |_ ___ | |__
+// | . ` || | / _` || '_ \ | __|\ \ /\ / / / _` || __| / __|| '_ \
+// | |\ || || (_| || | | || |_ \ V V / | (_| || |_ | (__ | | | |
+// \_| \_/|_| \__, ||_| |_| \__| \_/\_/ \__,_| \__| \___||_| |_|
+// __/ |
+// |___/
+//
+
+module.exports = {
+ // An array of folders (excluding subfolders) where your tests are located;
+ // if this is not specified, the test source must be passed as the second argument to the test runner.
+ src_folders: [],
+
+ // See https://nightwatchjs.org/guide/concepts/page-object-model.html
+ page_objects_path: [],
+
+ // See https://nightwatchjs.org/guide/extending-nightwatch/adding-custom-commands.html
+ custom_commands_path: [],
+
+ // See https://nightwatchjs.org/guide/extending-nightwatch/adding-custom-assertions.html
+ custom_assertions_path: [],
+
+ // See https://nightwatchjs.org/guide/extending-nightwatch/adding-plugins.html
+ plugins: ['@nightwatch/vue'],
+
+ // See https://nightwatchjs.org/guide/concepts/test-globals.html#external-test-globals
+ globals_path: '',
+
+ vite_dev_server: {
+ start_vite: true,
+ port: process.env.CI ? 4173 : 5173
+ },
+
+ webdriver: {},
+
+ test_workers: {
+ enabled: true,
+ workers: 'auto'
+ },
+
+ test_settings: {
+ default: {
+ disable_error_log: false,
+ launch_url: `http://localhost:${process.env.CI ? '4173' : '5173'}`,
+
+ screenshots: {
+ enabled: false,
+ path: 'screens',
+ on_failure: true
+ },
+
+ desiredCapabilities: {
+ browserName: 'firefox'
+ },
+
+ webdriver: {
+ start_process: true,
+ server_path: ''
+ }
+ },
+
+ safari: {
+ desiredCapabilities: {
+ browserName: 'safari',
+ alwaysMatch: {
+ acceptInsecureCerts: false
+ }
+ },
+ webdriver: {
+ start_process: true,
+ server_path: ''
+ }
+ },
+
+ firefox: {
+ desiredCapabilities: {
+ browserName: 'firefox',
+ alwaysMatch: {
+ acceptInsecureCerts: true,
+ 'moz:firefoxOptions': {
+ args: [
+ // '-headless',
+ // '-verbose'
+ ]
+ }
+ }
+ },
+ webdriver: {
+ start_process: true,
+ server_path: '',
+ cli_args: [
+ // very verbose geckodriver logs
+ // '-vv'
+ ]
+ }
+ },
+
+ chrome: {
+ desiredCapabilities: {
+ browserName: 'chrome',
+ 'goog:chromeOptions': {
+ // More info on Chromedriver: https://sites.google.com/a/chromium.org/chromedriver/
+ //
+ // w3c:false tells Chromedriver to run using the legacy JSONWire protocol (not required in Chrome 78)
+ w3c: true,
+ args: [
+ //'--no-sandbox',
+ //'--ignore-certificate-errors',
+ //'--allow-insecure-localhost',
+ //'--headless'
+ ]
+ }
+ },
+
+ webdriver: {
+ start_process: true,
+ server_path: '',
+ cli_args: [
+ // --verbose
+ ]
+ }
+ },
+
+ edge: {
+ desiredCapabilities: {
+ browserName: 'MicrosoftEdge',
+ 'ms:edgeOptions': {
+ w3c: true,
+ // More info on EdgeDriver: https://docs.microsoft.com/en-us/microsoft-edge/webdriver-chromium/capabilities-edge-options
+ args: [
+ //'--headless'
+ ]
+ }
+ },
+
+ webdriver: {
+ start_process: true,
+ // Download msedgedriver from https://docs.microsoft.com/en-us/microsoft-edge/webdriver-chromium/
+ // and set the location below:
+ server_path: '',
+ cli_args: [
+ // --verbose
+ ]
+ }
+ }
+ }
+}
diff --git a/playground/typescript-jsx-router-vitest-nightwatch/nightwatch/nightwatch.d.ts b/playground/typescript-jsx-router-vitest-nightwatch/nightwatch/nightwatch.d.ts
new file mode 100644
index 000000000..616e63f9f
--- /dev/null
+++ b/playground/typescript-jsx-router-vitest-nightwatch/nightwatch/nightwatch.d.ts
@@ -0,0 +1,13 @@
+import { NightwatchCustomAssertions, NightwatchCustomCommands } from 'nightwatch'
+
+declare module 'nightwatch' {
+ interface NightwatchCustomAssertions {
+ // Add your custom assertions' types here
+ // elementHasCount: (selector: string, count: number) => NightwatchBrowser
+ }
+
+ interface NightwatchCustomCommands {
+ // Add your custom commands' types here
+ // strictClick: (selector: string) => NightwatchBrowser
+ }
+}
diff --git a/playground/typescript-jsx-router-vitest-nightwatch/nightwatch/tsconfig.json b/playground/typescript-jsx-router-vitest-nightwatch/nightwatch/tsconfig.json
new file mode 100644
index 000000000..8cd7ca1da
--- /dev/null
+++ b/playground/typescript-jsx-router-vitest-nightwatch/nightwatch/tsconfig.json
@@ -0,0 +1,20 @@
+{
+ "extends": "@tsconfig/node20/tsconfig.json",
+ "compilerOptions": {
+ "composite": true,
+ "noEmit": true,
+ "tsBuildInfoFile": "../node_modules/.tmp/tsconfig.nightwatch.tsbuildinfo",
+
+ "target": "ESNext",
+ "module": "commonjs",
+ "moduleResolution": "node",
+ "rootDir": "../",
+ "lib": ["ESNext", "dom"],
+ "types": ["nightwatch"]
+ },
+ "include": ["../node_modules/@nightwatch/**/*", "../src/components/**/*", "../tests/e2e/**/*"],
+ "ts-node": {
+ "transpileOnly": true
+ },
+ "files": ["nightwatch.d.ts"]
+}
diff --git a/playground/typescript-jsx-router-vitest-nightwatch/package.json b/playground/typescript-jsx-router-vitest-nightwatch/package.json
new file mode 100644
index 000000000..3817e4954
--- /dev/null
+++ b/playground/typescript-jsx-router-vitest-nightwatch/package.json
@@ -0,0 +1,40 @@
+{
+ "name": "typescript-jsx-router-vitest-nightwatch",
+ "version": "0.0.0",
+ "private": true,
+ "type": "module",
+ "scripts": {
+ "dev": "vite",
+ "build": "run-p type-check \"build-only {@}\" --",
+ "preview": "vite preview",
+ "test:unit": "vitest",
+ "test:e2e": "nightwatch tests/e2e/*",
+ "build-only": "vite build",
+ "type-check": "vue-tsc --build --force"
+ },
+ "dependencies": {
+ "vue": "^3.4.15",
+ "vue-router": "^4.2.5"
+ },
+ "devDependencies": {
+ "@nightwatch/vue": "^3.1.0",
+ "@tsconfig/node20": "^20.1.2",
+ "@types/jsdom": "^21.1.6",
+ "@types/node": "^20.11.16",
+ "@vitejs/plugin-vue": "^5.0.3",
+ "@vitejs/plugin-vue-jsx": "^3.1.0",
+ "@vue/test-utils": "^2.4.4",
+ "@vue/tsconfig": "^0.5.1",
+ "chromedriver": "^121.0.0",
+ "geckodriver": "^4.3.2",
+ "jsdom": "^24.0.0",
+ "nightwatch": "^3.4.0",
+ "npm-run-all2": "^6.1.2",
+ "ts-node": "^10.9.2",
+ "typescript": "~5.3.0",
+ "vite": "^5.0.11",
+ "vite-plugin-nightwatch": "^0.4.6",
+ "vitest": "^1.2.2",
+ "vue-tsc": "^1.8.27"
+ }
+}
diff --git a/playground/typescript-jsx-router-vitest-nightwatch/public/favicon.ico b/playground/typescript-jsx-router-vitest-nightwatch/public/favicon.ico
new file mode 100644
index 000000000..df36fcfb7
Binary files /dev/null and b/playground/typescript-jsx-router-vitest-nightwatch/public/favicon.ico differ
diff --git a/playground/typescript-jsx-router-vitest-nightwatch/src/App.vue b/playground/typescript-jsx-router-vitest-nightwatch/src/App.vue
new file mode 100644
index 000000000..7905b0516
--- /dev/null
+++ b/playground/typescript-jsx-router-vitest-nightwatch/src/App.vue
@@ -0,0 +1,85 @@
+
+
+
+
+
+
+
+ You’ve successfully created a project with
+ Vite +
+ Vue 3. What's next?
+
+
+
+
+
diff --git a/playground/typescript-jsx-router-vitest-nightwatch/src/components/TheWelcome.vue b/playground/typescript-jsx-router-vitest-nightwatch/src/components/TheWelcome.vue
new file mode 100644
index 000000000..49d8f7354
--- /dev/null
+++ b/playground/typescript-jsx-router-vitest-nightwatch/src/components/TheWelcome.vue
@@ -0,0 +1,88 @@
+
+
+
+
+
+
+
+ Documentation
+
+ Vue’s
+ official documentation
+ provides you with all information you need to get started.
+
+
+
+
+
+
+ Tooling
+
+ This project is served and bundled with
+ Vite. The
+ recommended IDE setup is
+ VSCode +
+ Volar. If
+ you need to test your components and web pages, check out
+ Cypress and
+ Cypress Component Testing.
+
+
+
+ More instructions are available in README.md.
+
+
+
+
+
+
+ Ecosystem
+
+ Get official tools and libraries for your project:
+ Pinia,
+ Vue Router,
+ Vue Test Utils, and
+ Vue Dev Tools. If
+ you need more resources, we suggest paying
+ Awesome Vue
+ a visit.
+
+
+
+
+
+
+ Community
+
+ Got stuck? Ask your question on
+ Vue Land, our official
+ Discord server, or
+ StackOverflow. You should also subscribe to
+ our mailing list and follow
+ the official
+ @vuejs
+ twitter account for latest news in the Vue world.
+
+
+
+
+
+
+ Support Vue
+
+ As an independent project, Vue relies on community backing for its sustainability. You can help
+ us by
+ becoming a sponsor.
+
+
diff --git a/playground/typescript-jsx-router-vitest-nightwatch/src/components/WelcomeItem.vue b/playground/typescript-jsx-router-vitest-nightwatch/src/components/WelcomeItem.vue
new file mode 100644
index 000000000..6d7086aea
--- /dev/null
+++ b/playground/typescript-jsx-router-vitest-nightwatch/src/components/WelcomeItem.vue
@@ -0,0 +1,87 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/playground/typescript-jsx-router-vitest-nightwatch/src/components/__tests__/HelloWorld.spec.ts b/playground/typescript-jsx-router-vitest-nightwatch/src/components/__tests__/HelloWorld.spec.ts
new file mode 100644
index 000000000..253320200
--- /dev/null
+++ b/playground/typescript-jsx-router-vitest-nightwatch/src/components/__tests__/HelloWorld.spec.ts
@@ -0,0 +1,11 @@
+import { describe, it, expect } from 'vitest'
+
+import { mount } from '@vue/test-utils'
+import HelloWorld from '../HelloWorld.vue'
+
+describe('HelloWorld', () => {
+ it('renders properly', () => {
+ const wrapper = mount(HelloWorld, { props: { msg: 'Hello Vitest' } })
+ expect(wrapper.text()).toContain('Hello Vitest')
+ })
+})
diff --git a/playground/typescript-jsx-router-vitest-nightwatch/src/components/icons/IconCommunity.vue b/playground/typescript-jsx-router-vitest-nightwatch/src/components/icons/IconCommunity.vue
new file mode 100644
index 000000000..2dc8b0552
--- /dev/null
+++ b/playground/typescript-jsx-router-vitest-nightwatch/src/components/icons/IconCommunity.vue
@@ -0,0 +1,7 @@
+
+
+
diff --git a/playground/typescript-jsx-router-vitest-nightwatch/src/components/icons/IconDocumentation.vue b/playground/typescript-jsx-router-vitest-nightwatch/src/components/icons/IconDocumentation.vue
new file mode 100644
index 000000000..6d4791cfb
--- /dev/null
+++ b/playground/typescript-jsx-router-vitest-nightwatch/src/components/icons/IconDocumentation.vue
@@ -0,0 +1,7 @@
+
+
+
diff --git a/playground/typescript-jsx-router-vitest-nightwatch/src/components/icons/IconEcosystem.vue b/playground/typescript-jsx-router-vitest-nightwatch/src/components/icons/IconEcosystem.vue
new file mode 100644
index 000000000..c3a4f078c
--- /dev/null
+++ b/playground/typescript-jsx-router-vitest-nightwatch/src/components/icons/IconEcosystem.vue
@@ -0,0 +1,7 @@
+
+
+
diff --git a/playground/typescript-jsx-router-vitest-nightwatch/src/components/icons/IconSupport.vue b/playground/typescript-jsx-router-vitest-nightwatch/src/components/icons/IconSupport.vue
new file mode 100644
index 000000000..7452834d3
--- /dev/null
+++ b/playground/typescript-jsx-router-vitest-nightwatch/src/components/icons/IconSupport.vue
@@ -0,0 +1,7 @@
+
+
+
diff --git a/playground/typescript-jsx-router-vitest-nightwatch/src/components/icons/IconTooling.vue b/playground/typescript-jsx-router-vitest-nightwatch/src/components/icons/IconTooling.vue
new file mode 100644
index 000000000..660598d7c
--- /dev/null
+++ b/playground/typescript-jsx-router-vitest-nightwatch/src/components/icons/IconTooling.vue
@@ -0,0 +1,19 @@
+
+
+
+
diff --git a/playground/typescript-jsx-router-vitest-nightwatch/src/main.ts b/playground/typescript-jsx-router-vitest-nightwatch/src/main.ts
new file mode 100644
index 000000000..5a5dbdba7
--- /dev/null
+++ b/playground/typescript-jsx-router-vitest-nightwatch/src/main.ts
@@ -0,0 +1,11 @@
+import './assets/main.css'
+
+import { createApp } from 'vue'
+import App from './App.vue'
+import router from './router'
+
+const app = createApp(App)
+
+app.use(router)
+
+app.mount('#app')
diff --git a/playground/typescript-jsx-router-vitest-nightwatch/src/router/index.ts b/playground/typescript-jsx-router-vitest-nightwatch/src/router/index.ts
new file mode 100644
index 000000000..a49ae507f
--- /dev/null
+++ b/playground/typescript-jsx-router-vitest-nightwatch/src/router/index.ts
@@ -0,0 +1,23 @@
+import { createRouter, createWebHistory } from 'vue-router'
+import HomeView from '../views/HomeView.vue'
+
+const router = createRouter({
+ history: createWebHistory(import.meta.env.BASE_URL),
+ routes: [
+ {
+ path: '/',
+ name: 'home',
+ component: HomeView
+ },
+ {
+ path: '/about',
+ name: 'about',
+ // route level code-splitting
+ // this generates a separate chunk (About.[hash].js) for this route
+ // which is lazy-loaded when the route is visited.
+ component: () => import('../views/AboutView.vue')
+ }
+ ]
+})
+
+export default router
diff --git a/playground/typescript-jsx-router-vitest-nightwatch/src/views/AboutView.vue b/playground/typescript-jsx-router-vitest-nightwatch/src/views/AboutView.vue
new file mode 100644
index 000000000..756ad2a17
--- /dev/null
+++ b/playground/typescript-jsx-router-vitest-nightwatch/src/views/AboutView.vue
@@ -0,0 +1,15 @@
+
+
+
This is an about page
+
+
+
+
diff --git a/playground/typescript-jsx-router-vitest-nightwatch/src/views/HomeView.vue b/playground/typescript-jsx-router-vitest-nightwatch/src/views/HomeView.vue
new file mode 100644
index 000000000..d5c0217e4
--- /dev/null
+++ b/playground/typescript-jsx-router-vitest-nightwatch/src/views/HomeView.vue
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
diff --git a/playground/typescript-jsx-router-vitest-nightwatch/tests/e2e/example.ts b/playground/typescript-jsx-router-vitest-nightwatch/tests/e2e/example.ts
new file mode 100644
index 000000000..43be3fce1
--- /dev/null
+++ b/playground/typescript-jsx-router-vitest-nightwatch/tests/e2e/example.ts
@@ -0,0 +1,11 @@
+describe('My First Test', function () {
+ before((browser) => {
+ browser.init()
+ })
+
+ it('visits the app root url', function () {
+ browser.assert.textContains('.green', 'You did it!')
+ })
+
+ after((browser) => browser.end())
+})
diff --git a/playground/typescript-jsx-router-vitest-nightwatch/tsconfig.app.json b/playground/typescript-jsx-router-vitest-nightwatch/tsconfig.app.json
new file mode 100644
index 000000000..e14c754d3
--- /dev/null
+++ b/playground/typescript-jsx-router-vitest-nightwatch/tsconfig.app.json
@@ -0,0 +1,14 @@
+{
+ "extends": "@vue/tsconfig/tsconfig.dom.json",
+ "include": ["env.d.ts", "src/**/*", "src/**/*.vue"],
+ "exclude": ["src/**/__tests__/*"],
+ "compilerOptions": {
+ "composite": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
+
+ "baseUrl": ".",
+ "paths": {
+ "@/*": ["./src/*"]
+ }
+ }
+}
diff --git a/playground/typescript-jsx-router-vitest-nightwatch/tsconfig.json b/playground/typescript-jsx-router-vitest-nightwatch/tsconfig.json
new file mode 100644
index 000000000..a5352e667
--- /dev/null
+++ b/playground/typescript-jsx-router-vitest-nightwatch/tsconfig.json
@@ -0,0 +1,17 @@
+{
+ "files": [],
+ "references": [
+ {
+ "path": "./tsconfig.node.json"
+ },
+ {
+ "path": "./tsconfig.app.json"
+ },
+ {
+ "path": "./tsconfig.vitest.json"
+ },
+ {
+ "path": "./nightwatch/tsconfig.json"
+ }
+ ]
+}
diff --git a/playground/typescript-jsx-router-vitest-nightwatch/tsconfig.node.json b/playground/typescript-jsx-router-vitest-nightwatch/tsconfig.node.json
new file mode 100644
index 000000000..f09406303
--- /dev/null
+++ b/playground/typescript-jsx-router-vitest-nightwatch/tsconfig.node.json
@@ -0,0 +1,19 @@
+{
+ "extends": "@tsconfig/node20/tsconfig.json",
+ "include": [
+ "vite.config.*",
+ "vitest.config.*",
+ "cypress.config.*",
+ "nightwatch.conf.*",
+ "playwright.config.*"
+ ],
+ "compilerOptions": {
+ "composite": true,
+ "noEmit": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
+
+ "module": "ESNext",
+ "moduleResolution": "Bundler",
+ "types": ["node"]
+ }
+}
diff --git a/playground/typescript-jsx-router-vitest-nightwatch/tsconfig.vitest.json b/playground/typescript-jsx-router-vitest-nightwatch/tsconfig.vitest.json
new file mode 100644
index 000000000..571995d11
--- /dev/null
+++ b/playground/typescript-jsx-router-vitest-nightwatch/tsconfig.vitest.json
@@ -0,0 +1,11 @@
+{
+ "extends": "./tsconfig.app.json",
+ "exclude": [],
+ "compilerOptions": {
+ "composite": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.vitest.tsbuildinfo",
+
+ "lib": [],
+ "types": ["node", "jsdom"]
+ }
+}
diff --git a/playground/typescript-jsx-router-vitest-nightwatch/vite.config.ts b/playground/typescript-jsx-router-vitest-nightwatch/vite.config.ts
new file mode 100644
index 000000000..3a6988230
--- /dev/null
+++ b/playground/typescript-jsx-router-vitest-nightwatch/vite.config.ts
@@ -0,0 +1,20 @@
+import { fileURLToPath, URL } from 'node:url'
+
+import { defineConfig } from 'vite'
+import vue from '@vitejs/plugin-vue'
+import vueJsx from '@vitejs/plugin-vue-jsx'
+import nightwatchPlugin from 'vite-plugin-nightwatch'
+
+// https://vitejs.dev/config/
+export default defineConfig({
+ plugins: [
+ vue(),
+ vueJsx(),
+ nightwatchPlugin(),
+ ],
+ resolve: {
+ alias: {
+ '@': fileURLToPath(new URL('./src', import.meta.url))
+ }
+ }
+})
diff --git a/playground/typescript-jsx-router-vitest-nightwatch/vitest.config.ts b/playground/typescript-jsx-router-vitest-nightwatch/vitest.config.ts
new file mode 100644
index 000000000..10067d578
--- /dev/null
+++ b/playground/typescript-jsx-router-vitest-nightwatch/vitest.config.ts
@@ -0,0 +1,14 @@
+import { fileURLToPath } from 'node:url'
+import { mergeConfig, defineConfig, configDefaults } from 'vitest/config'
+import viteConfig from './vite.config'
+
+export default mergeConfig(
+ viteConfig,
+ defineConfig({
+ test: {
+ environment: 'jsdom',
+ exclude: [...configDefaults.exclude, 'e2e/*'],
+ root: fileURLToPath(new URL('./', import.meta.url))
+ }
+ })
+)
diff --git a/playground/typescript-jsx-router-vitest-playwright/.gitignore b/playground/typescript-jsx-router-vitest-playwright/.gitignore
new file mode 100644
index 000000000..aef72d03c
--- /dev/null
+++ b/playground/typescript-jsx-router-vitest-playwright/.gitignore
@@ -0,0 +1,33 @@
+# 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/
+
+# Editor directories and files
+.vscode/*
+!.vscode/extensions.json
+.idea
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?
+
+*.tsbuildinfo
+
+test-results/
+playwright-report/
diff --git a/playground/typescript-jsx-router-vitest-playwright/.vscode/extensions.json b/playground/typescript-jsx-router-vitest-playwright/.vscode/extensions.json
new file mode 100644
index 000000000..7b3f8bdae
--- /dev/null
+++ b/playground/typescript-jsx-router-vitest-playwright/.vscode/extensions.json
@@ -0,0 +1,3 @@
+{
+ "recommendations": ["ms-playwright.playwright"]
+}
diff --git a/playground/typescript-jsx-router-vitest-playwright/README.md b/playground/typescript-jsx-router-vitest-playwright/README.md
new file mode 100644
index 000000000..14a06543c
--- /dev/null
+++ b/playground/typescript-jsx-router-vitest-playwright/README.md
@@ -0,0 +1,65 @@
+# typescript-jsx-router-vitest-playwright
+
+This template should help get you started developing with Vue 3 in Vite.
+
+## Recommended IDE Setup
+
+[VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur) + [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin).
+
+## Type Support for `.vue` Imports in TS
+
+TypeScript cannot handle type information for `.vue` imports by default, so we replace the `tsc` CLI with `vue-tsc` for type checking. In editors, we need [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin) to make the TypeScript language service aware of `.vue` types.
+
+If the standalone TypeScript plugin doesn't feel fast enough to you, Volar has also implemented a [Take Over Mode](https://github.com/johnsoncodehk/volar/discussions/471#discussioncomment-1361669) that is more performant. You can enable it by the following steps:
+
+1. Disable the built-in TypeScript Extension
+ 1) Run `Extensions: Show Built-in Extensions` from VSCode's command palette
+ 2) Find `TypeScript and JavaScript Language Features`, right click and select `Disable (Workspace)`
+2. Reload the VSCode window by running `Developer: Reload Window` from the command palette.
+
+## Customize configuration
+
+See [Vite Configuration Reference](https://vitejs.dev/config/).
+
+## Project Setup
+
+```sh
+pnpm install
+```
+
+### Compile and Hot-Reload for Development
+
+```sh
+pnpm dev
+```
+
+### Type-Check, Compile and Minify for Production
+
+```sh
+pnpm build
+```
+
+### Run Unit Tests with [Vitest](https://vitest.dev/)
+
+```sh
+pnpm test:unit
+```
+
+### Run End-to-End Tests with [Playwright](https://playwright.dev)
+
+```sh
+# Install browsers for the first run
+npx playwright install
+
+# When testing on CI, must build the project first
+pnpm build
+
+# Runs the end-to-end tests
+pnpm test:e2e
+# Runs the tests only on Chromium
+pnpm test:e2e --project=chromium
+# Runs the tests of a specific file
+pnpm test:e2e tests/example.spec.ts
+# Runs the tests in debug mode
+pnpm test:e2e --debug
+```
diff --git a/playground/typescript-jsx-router-vitest-playwright/e2e/tsconfig.json b/playground/typescript-jsx-router-vitest-playwright/e2e/tsconfig.json
new file mode 100644
index 000000000..be3bbfc0e
--- /dev/null
+++ b/playground/typescript-jsx-router-vitest-playwright/e2e/tsconfig.json
@@ -0,0 +1,4 @@
+{
+ "extends": "@tsconfig/node20/tsconfig.json",
+ "include": ["./**/*"]
+}
diff --git a/playground/typescript-jsx-router-vitest-playwright/e2e/vue.spec.ts b/playground/typescript-jsx-router-vitest-playwright/e2e/vue.spec.ts
new file mode 100644
index 000000000..3e5a3d02d
--- /dev/null
+++ b/playground/typescript-jsx-router-vitest-playwright/e2e/vue.spec.ts
@@ -0,0 +1,8 @@
+import { test, expect } from '@playwright/test';
+
+// See here how to get started:
+// https://playwright.dev/docs/intro
+test('visits the app root url', async ({ page }) => {
+ await page.goto('/');
+ await expect(page.locator('div.greetings > h1')).toHaveText('You did it!');
+})
diff --git a/playground/typescript-jsx-router-vitest-playwright/env.d.ts b/playground/typescript-jsx-router-vitest-playwright/env.d.ts
new file mode 100644
index 000000000..11f02fe2a
--- /dev/null
+++ b/playground/typescript-jsx-router-vitest-playwright/env.d.ts
@@ -0,0 +1 @@
+///
diff --git a/playground/typescript-jsx-router-vitest-playwright/index.html b/playground/typescript-jsx-router-vitest-playwright/index.html
new file mode 100644
index 000000000..a88854489
--- /dev/null
+++ b/playground/typescript-jsx-router-vitest-playwright/index.html
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+ Vite App
+
+
+
+
+
+
diff --git a/playground/typescript-jsx-router-vitest-playwright/package.json b/playground/typescript-jsx-router-vitest-playwright/package.json
new file mode 100644
index 000000000..4e79a643b
--- /dev/null
+++ b/playground/typescript-jsx-router-vitest-playwright/package.json
@@ -0,0 +1,35 @@
+{
+ "name": "typescript-jsx-router-vitest-playwright",
+ "version": "0.0.0",
+ "private": true,
+ "type": "module",
+ "scripts": {
+ "dev": "vite",
+ "build": "run-p type-check \"build-only {@}\" --",
+ "preview": "vite preview",
+ "test:unit": "vitest",
+ "test:e2e": "playwright test",
+ "build-only": "vite build",
+ "type-check": "vue-tsc --build --force"
+ },
+ "dependencies": {
+ "vue": "^3.4.15",
+ "vue-router": "^4.2.5"
+ },
+ "devDependencies": {
+ "@playwright/test": "^1.41.2",
+ "@tsconfig/node20": "^20.1.2",
+ "@types/jsdom": "^21.1.6",
+ "@types/node": "^20.11.16",
+ "@vitejs/plugin-vue": "^5.0.3",
+ "@vitejs/plugin-vue-jsx": "^3.1.0",
+ "@vue/test-utils": "^2.4.4",
+ "@vue/tsconfig": "^0.5.1",
+ "jsdom": "^24.0.0",
+ "npm-run-all2": "^6.1.2",
+ "typescript": "~5.3.0",
+ "vite": "^5.0.11",
+ "vitest": "^1.2.2",
+ "vue-tsc": "^1.8.27"
+ }
+}
diff --git a/playground/typescript-jsx-router-vitest-playwright/playwright.config.ts b/playground/typescript-jsx-router-vitest-playwright/playwright.config.ts
new file mode 100644
index 000000000..92075cc1b
--- /dev/null
+++ b/playground/typescript-jsx-router-vitest-playwright/playwright.config.ts
@@ -0,0 +1,110 @@
+import process from 'node:process'
+import { defineConfig, devices } from '@playwright/test'
+
+/**
+ * Read environment variables from file.
+ * https://github.com/motdotla/dotenv
+ */
+// require('dotenv').config();
+
+/**
+ * See https://playwright.dev/docs/test-configuration.
+ */
+export default defineConfig({
+ testDir: './e2e',
+ /* Maximum time one test can run for. */
+ timeout: 30 * 1000,
+ expect: {
+ /**
+ * Maximum time expect() should wait for the condition to be met.
+ * For example in `await expect(locator).toHaveText();`
+ */
+ timeout: 5000
+ },
+ /* Fail the build on CI if you accidentally left test.only in the source code. */
+ forbidOnly: !!process.env.CI,
+ /* Retry on CI only */
+ retries: process.env.CI ? 2 : 0,
+ /* Opt out of parallel tests on CI. */
+ workers: process.env.CI ? 1 : undefined,
+ /* Reporter to use. See https://playwright.dev/docs/test-reporters */
+ reporter: 'html',
+ /* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
+ use: {
+ /* Maximum time each action such as `click()` can take. Defaults to 0 (no limit). */
+ actionTimeout: 0,
+ /* Base URL to use in actions like `await page.goto('/')`. */
+ baseURL: 'http://localhost:5173',
+
+ /* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
+ trace: 'on-first-retry',
+
+ /* Only on CI systems run the tests headless */
+ headless: !!process.env.CI
+ },
+
+ /* Configure projects for major browsers */
+ projects: [
+ {
+ name: 'chromium',
+ use: {
+ ...devices['Desktop Chrome']
+ }
+ },
+ {
+ name: 'firefox',
+ use: {
+ ...devices['Desktop Firefox']
+ }
+ },
+ {
+ name: 'webkit',
+ use: {
+ ...devices['Desktop Safari']
+ }
+ }
+
+ /* Test against mobile viewports. */
+ // {
+ // name: 'Mobile Chrome',
+ // use: {
+ // ...devices['Pixel 5'],
+ // },
+ // },
+ // {
+ // name: 'Mobile Safari',
+ // use: {
+ // ...devices['iPhone 12'],
+ // },
+ // },
+
+ /* Test against branded browsers. */
+ // {
+ // name: 'Microsoft Edge',
+ // use: {
+ // channel: 'msedge',
+ // },
+ // },
+ // {
+ // name: 'Google Chrome',
+ // use: {
+ // channel: 'chrome',
+ // },
+ // },
+ ],
+
+ /* Folder for test artifacts such as screenshots, videos, traces, etc. */
+ // outputDir: 'test-results/',
+
+ /* Run your local dev server before starting the tests */
+ webServer: {
+ /**
+ * Use the dev server by default for faster feedback loop.
+ * Use the preview server on CI for more realistic testing.
+ * Playwright will re-use the local server if there is already a dev-server running.
+ */
+ command: process.env.CI ? 'vite preview --port 5173' : 'vite dev',
+ port: 5173,
+ reuseExistingServer: !process.env.CI
+ }
+})
diff --git a/playground/typescript-jsx-router-vitest-playwright/public/favicon.ico b/playground/typescript-jsx-router-vitest-playwright/public/favicon.ico
new file mode 100644
index 000000000..df36fcfb7
Binary files /dev/null and b/playground/typescript-jsx-router-vitest-playwright/public/favicon.ico differ
diff --git a/playground/typescript-jsx-router-vitest-playwright/src/App.vue b/playground/typescript-jsx-router-vitest-playwright/src/App.vue
new file mode 100644
index 000000000..7905b0516
--- /dev/null
+++ b/playground/typescript-jsx-router-vitest-playwright/src/App.vue
@@ -0,0 +1,85 @@
+
+
+
+
+
+
+
+ You’ve successfully created a project with
+ Vite +
+ Vue 3. What's next?
+
+
+
+
+
diff --git a/playground/typescript-jsx-router-vitest-playwright/src/components/TheWelcome.vue b/playground/typescript-jsx-router-vitest-playwright/src/components/TheWelcome.vue
new file mode 100644
index 000000000..49d8f7354
--- /dev/null
+++ b/playground/typescript-jsx-router-vitest-playwright/src/components/TheWelcome.vue
@@ -0,0 +1,88 @@
+
+
+
+
+
+
+
+ Documentation
+
+ Vue’s
+ official documentation
+ provides you with all information you need to get started.
+
+
+
+
+
+
+ Tooling
+
+ This project is served and bundled with
+ Vite. The
+ recommended IDE setup is
+ VSCode +
+ Volar. If
+ you need to test your components and web pages, check out
+ Cypress and
+ Cypress Component Testing.
+
+
+
+ More instructions are available in README.md.
+
+
+
+
+
+
+ Ecosystem
+
+ Get official tools and libraries for your project:
+ Pinia,
+ Vue Router,
+ Vue Test Utils, and
+ Vue Dev Tools. If
+ you need more resources, we suggest paying
+ Awesome Vue
+ a visit.
+
+
+
+
+
+
+ Community
+
+ Got stuck? Ask your question on
+ Vue Land, our official
+ Discord server, or
+ StackOverflow. You should also subscribe to
+ our mailing list and follow
+ the official
+ @vuejs
+ twitter account for latest news in the Vue world.
+
+
+
+
+
+
+ Support Vue
+
+ As an independent project, Vue relies on community backing for its sustainability. You can help
+ us by
+ becoming a sponsor.
+
+
diff --git a/playground/typescript-jsx-router-vitest-playwright/src/components/WelcomeItem.vue b/playground/typescript-jsx-router-vitest-playwright/src/components/WelcomeItem.vue
new file mode 100644
index 000000000..6d7086aea
--- /dev/null
+++ b/playground/typescript-jsx-router-vitest-playwright/src/components/WelcomeItem.vue
@@ -0,0 +1,87 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/playground/typescript-jsx-router-vitest-playwright/src/components/__tests__/HelloWorld.spec.ts b/playground/typescript-jsx-router-vitest-playwright/src/components/__tests__/HelloWorld.spec.ts
new file mode 100644
index 000000000..253320200
--- /dev/null
+++ b/playground/typescript-jsx-router-vitest-playwright/src/components/__tests__/HelloWorld.spec.ts
@@ -0,0 +1,11 @@
+import { describe, it, expect } from 'vitest'
+
+import { mount } from '@vue/test-utils'
+import HelloWorld from '../HelloWorld.vue'
+
+describe('HelloWorld', () => {
+ it('renders properly', () => {
+ const wrapper = mount(HelloWorld, { props: { msg: 'Hello Vitest' } })
+ expect(wrapper.text()).toContain('Hello Vitest')
+ })
+})
diff --git a/playground/typescript-jsx-router-vitest-playwright/src/components/icons/IconCommunity.vue b/playground/typescript-jsx-router-vitest-playwright/src/components/icons/IconCommunity.vue
new file mode 100644
index 000000000..2dc8b0552
--- /dev/null
+++ b/playground/typescript-jsx-router-vitest-playwright/src/components/icons/IconCommunity.vue
@@ -0,0 +1,7 @@
+
+
+
diff --git a/playground/typescript-jsx-router-vitest-playwright/src/components/icons/IconDocumentation.vue b/playground/typescript-jsx-router-vitest-playwright/src/components/icons/IconDocumentation.vue
new file mode 100644
index 000000000..6d4791cfb
--- /dev/null
+++ b/playground/typescript-jsx-router-vitest-playwright/src/components/icons/IconDocumentation.vue
@@ -0,0 +1,7 @@
+
+
+
diff --git a/playground/typescript-jsx-router-vitest-playwright/src/components/icons/IconEcosystem.vue b/playground/typescript-jsx-router-vitest-playwright/src/components/icons/IconEcosystem.vue
new file mode 100644
index 000000000..c3a4f078c
--- /dev/null
+++ b/playground/typescript-jsx-router-vitest-playwright/src/components/icons/IconEcosystem.vue
@@ -0,0 +1,7 @@
+
+
+
diff --git a/playground/typescript-jsx-router-vitest-playwright/src/components/icons/IconSupport.vue b/playground/typescript-jsx-router-vitest-playwright/src/components/icons/IconSupport.vue
new file mode 100644
index 000000000..7452834d3
--- /dev/null
+++ b/playground/typescript-jsx-router-vitest-playwright/src/components/icons/IconSupport.vue
@@ -0,0 +1,7 @@
+
+
+
diff --git a/playground/typescript-jsx-router-vitest-playwright/src/components/icons/IconTooling.vue b/playground/typescript-jsx-router-vitest-playwright/src/components/icons/IconTooling.vue
new file mode 100644
index 000000000..660598d7c
--- /dev/null
+++ b/playground/typescript-jsx-router-vitest-playwright/src/components/icons/IconTooling.vue
@@ -0,0 +1,19 @@
+
+
+
+
diff --git a/playground/typescript-jsx-router-vitest-playwright/src/main.ts b/playground/typescript-jsx-router-vitest-playwright/src/main.ts
new file mode 100644
index 000000000..5a5dbdba7
--- /dev/null
+++ b/playground/typescript-jsx-router-vitest-playwright/src/main.ts
@@ -0,0 +1,11 @@
+import './assets/main.css'
+
+import { createApp } from 'vue'
+import App from './App.vue'
+import router from './router'
+
+const app = createApp(App)
+
+app.use(router)
+
+app.mount('#app')
diff --git a/playground/typescript-jsx-router-vitest-playwright/src/router/index.ts b/playground/typescript-jsx-router-vitest-playwright/src/router/index.ts
new file mode 100644
index 000000000..a49ae507f
--- /dev/null
+++ b/playground/typescript-jsx-router-vitest-playwright/src/router/index.ts
@@ -0,0 +1,23 @@
+import { createRouter, createWebHistory } from 'vue-router'
+import HomeView from '../views/HomeView.vue'
+
+const router = createRouter({
+ history: createWebHistory(import.meta.env.BASE_URL),
+ routes: [
+ {
+ path: '/',
+ name: 'home',
+ component: HomeView
+ },
+ {
+ path: '/about',
+ name: 'about',
+ // route level code-splitting
+ // this generates a separate chunk (About.[hash].js) for this route
+ // which is lazy-loaded when the route is visited.
+ component: () => import('../views/AboutView.vue')
+ }
+ ]
+})
+
+export default router
diff --git a/playground/typescript-jsx-router-vitest-playwright/src/views/AboutView.vue b/playground/typescript-jsx-router-vitest-playwright/src/views/AboutView.vue
new file mode 100644
index 000000000..756ad2a17
--- /dev/null
+++ b/playground/typescript-jsx-router-vitest-playwright/src/views/AboutView.vue
@@ -0,0 +1,15 @@
+
+
+
This is an about page
+
+
+
+
diff --git a/playground/typescript-jsx-router-vitest-playwright/src/views/HomeView.vue b/playground/typescript-jsx-router-vitest-playwright/src/views/HomeView.vue
new file mode 100644
index 000000000..d5c0217e4
--- /dev/null
+++ b/playground/typescript-jsx-router-vitest-playwright/src/views/HomeView.vue
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
diff --git a/playground/typescript-jsx-router-vitest-playwright/tsconfig.app.json b/playground/typescript-jsx-router-vitest-playwright/tsconfig.app.json
new file mode 100644
index 000000000..e14c754d3
--- /dev/null
+++ b/playground/typescript-jsx-router-vitest-playwright/tsconfig.app.json
@@ -0,0 +1,14 @@
+{
+ "extends": "@vue/tsconfig/tsconfig.dom.json",
+ "include": ["env.d.ts", "src/**/*", "src/**/*.vue"],
+ "exclude": ["src/**/__tests__/*"],
+ "compilerOptions": {
+ "composite": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
+
+ "baseUrl": ".",
+ "paths": {
+ "@/*": ["./src/*"]
+ }
+ }
+}
diff --git a/playground/typescript-jsx-router-vitest-playwright/tsconfig.json b/playground/typescript-jsx-router-vitest-playwright/tsconfig.json
new file mode 100644
index 000000000..100cf6a8f
--- /dev/null
+++ b/playground/typescript-jsx-router-vitest-playwright/tsconfig.json
@@ -0,0 +1,14 @@
+{
+ "files": [],
+ "references": [
+ {
+ "path": "./tsconfig.node.json"
+ },
+ {
+ "path": "./tsconfig.app.json"
+ },
+ {
+ "path": "./tsconfig.vitest.json"
+ }
+ ]
+}
diff --git a/playground/typescript-jsx-router-vitest-playwright/tsconfig.node.json b/playground/typescript-jsx-router-vitest-playwright/tsconfig.node.json
new file mode 100644
index 000000000..f09406303
--- /dev/null
+++ b/playground/typescript-jsx-router-vitest-playwright/tsconfig.node.json
@@ -0,0 +1,19 @@
+{
+ "extends": "@tsconfig/node20/tsconfig.json",
+ "include": [
+ "vite.config.*",
+ "vitest.config.*",
+ "cypress.config.*",
+ "nightwatch.conf.*",
+ "playwright.config.*"
+ ],
+ "compilerOptions": {
+ "composite": true,
+ "noEmit": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
+
+ "module": "ESNext",
+ "moduleResolution": "Bundler",
+ "types": ["node"]
+ }
+}
diff --git a/playground/typescript-jsx-router-vitest-playwright/tsconfig.vitest.json b/playground/typescript-jsx-router-vitest-playwright/tsconfig.vitest.json
new file mode 100644
index 000000000..571995d11
--- /dev/null
+++ b/playground/typescript-jsx-router-vitest-playwright/tsconfig.vitest.json
@@ -0,0 +1,11 @@
+{
+ "extends": "./tsconfig.app.json",
+ "exclude": [],
+ "compilerOptions": {
+ "composite": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.vitest.tsbuildinfo",
+
+ "lib": [],
+ "types": ["node", "jsdom"]
+ }
+}
diff --git a/playground/typescript-jsx-router-vitest-playwright/vite.config.ts b/playground/typescript-jsx-router-vitest-playwright/vite.config.ts
new file mode 100644
index 000000000..36c618756
--- /dev/null
+++ b/playground/typescript-jsx-router-vitest-playwright/vite.config.ts
@@ -0,0 +1,18 @@
+import { fileURLToPath, URL } from 'node:url'
+
+import { defineConfig } from 'vite'
+import vue from '@vitejs/plugin-vue'
+import vueJsx from '@vitejs/plugin-vue-jsx'
+
+// https://vitejs.dev/config/
+export default defineConfig({
+ plugins: [
+ vue(),
+ vueJsx(),
+ ],
+ resolve: {
+ alias: {
+ '@': fileURLToPath(new URL('./src', import.meta.url))
+ }
+ }
+})
diff --git a/playground/typescript-jsx-router-vitest-playwright/vitest.config.ts b/playground/typescript-jsx-router-vitest-playwright/vitest.config.ts
new file mode 100644
index 000000000..10067d578
--- /dev/null
+++ b/playground/typescript-jsx-router-vitest-playwright/vitest.config.ts
@@ -0,0 +1,14 @@
+import { fileURLToPath } from 'node:url'
+import { mergeConfig, defineConfig, configDefaults } from 'vitest/config'
+import viteConfig from './vite.config'
+
+export default mergeConfig(
+ viteConfig,
+ defineConfig({
+ test: {
+ environment: 'jsdom',
+ exclude: [...configDefaults.exclude, 'e2e/*'],
+ root: fileURLToPath(new URL('./', import.meta.url))
+ }
+ })
+)
diff --git a/playground/typescript-jsx-router-vitest/.gitignore b/playground/typescript-jsx-router-vitest/.gitignore
new file mode 100644
index 000000000..8ee54e8d3
--- /dev/null
+++ b/playground/typescript-jsx-router-vitest/.gitignore
@@ -0,0 +1,30 @@
+# 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/
+
+# Editor directories and files
+.vscode/*
+!.vscode/extensions.json
+.idea
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?
+
+*.tsbuildinfo
diff --git a/playground/typescript-jsx-router-vitest/README.md b/playground/typescript-jsx-router-vitest/README.md
new file mode 100644
index 000000000..51d21c67d
--- /dev/null
+++ b/playground/typescript-jsx-router-vitest/README.md
@@ -0,0 +1,46 @@
+# typescript-jsx-router-vitest
+
+This template should help get you started developing with Vue 3 in Vite.
+
+## Recommended IDE Setup
+
+[VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur) + [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin).
+
+## Type Support for `.vue` Imports in TS
+
+TypeScript cannot handle type information for `.vue` imports by default, so we replace the `tsc` CLI with `vue-tsc` for type checking. In editors, we need [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin) to make the TypeScript language service aware of `.vue` types.
+
+If the standalone TypeScript plugin doesn't feel fast enough to you, Volar has also implemented a [Take Over Mode](https://github.com/johnsoncodehk/volar/discussions/471#discussioncomment-1361669) that is more performant. You can enable it by the following steps:
+
+1. Disable the built-in TypeScript Extension
+ 1) Run `Extensions: Show Built-in Extensions` from VSCode's command palette
+ 2) Find `TypeScript and JavaScript Language Features`, right click and select `Disable (Workspace)`
+2. Reload the VSCode window by running `Developer: Reload Window` from the command palette.
+
+## Customize configuration
+
+See [Vite Configuration Reference](https://vitejs.dev/config/).
+
+## Project Setup
+
+```sh
+pnpm install
+```
+
+### Compile and Hot-Reload for Development
+
+```sh
+pnpm dev
+```
+
+### Type-Check, Compile and Minify for Production
+
+```sh
+pnpm build
+```
+
+### Run Unit Tests with [Vitest](https://vitest.dev/)
+
+```sh
+pnpm test:unit
+```
diff --git a/playground/typescript-jsx-router-vitest/env.d.ts b/playground/typescript-jsx-router-vitest/env.d.ts
new file mode 100644
index 000000000..11f02fe2a
--- /dev/null
+++ b/playground/typescript-jsx-router-vitest/env.d.ts
@@ -0,0 +1 @@
+///
diff --git a/playground/typescript-jsx-router-vitest/index.html b/playground/typescript-jsx-router-vitest/index.html
new file mode 100644
index 000000000..a88854489
--- /dev/null
+++ b/playground/typescript-jsx-router-vitest/index.html
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+ Vite App
+
+
+
+
+
+
diff --git a/playground/typescript-jsx-router-vitest/package.json b/playground/typescript-jsx-router-vitest/package.json
new file mode 100644
index 000000000..163fc1038
--- /dev/null
+++ b/playground/typescript-jsx-router-vitest/package.json
@@ -0,0 +1,33 @@
+{
+ "name": "typescript-jsx-router-vitest",
+ "version": "0.0.0",
+ "private": true,
+ "type": "module",
+ "scripts": {
+ "dev": "vite",
+ "build": "run-p type-check \"build-only {@}\" --",
+ "preview": "vite preview",
+ "test:unit": "vitest",
+ "build-only": "vite build",
+ "type-check": "vue-tsc --build --force"
+ },
+ "dependencies": {
+ "vue": "^3.4.15",
+ "vue-router": "^4.2.5"
+ },
+ "devDependencies": {
+ "@tsconfig/node20": "^20.1.2",
+ "@types/jsdom": "^21.1.6",
+ "@types/node": "^20.11.16",
+ "@vitejs/plugin-vue": "^5.0.3",
+ "@vitejs/plugin-vue-jsx": "^3.1.0",
+ "@vue/test-utils": "^2.4.4",
+ "@vue/tsconfig": "^0.5.1",
+ "jsdom": "^24.0.0",
+ "npm-run-all2": "^6.1.2",
+ "typescript": "~5.3.0",
+ "vite": "^5.0.11",
+ "vitest": "^1.2.2",
+ "vue-tsc": "^1.8.27"
+ }
+}
diff --git a/playground/typescript-jsx-router-vitest/public/favicon.ico b/playground/typescript-jsx-router-vitest/public/favicon.ico
new file mode 100644
index 000000000..df36fcfb7
Binary files /dev/null and b/playground/typescript-jsx-router-vitest/public/favicon.ico differ
diff --git a/playground/typescript-jsx-router-vitest/src/App.vue b/playground/typescript-jsx-router-vitest/src/App.vue
new file mode 100644
index 000000000..7905b0516
--- /dev/null
+++ b/playground/typescript-jsx-router-vitest/src/App.vue
@@ -0,0 +1,85 @@
+
+
+
+
+
+
+
+ You’ve successfully created a project with
+ Vite +
+ Vue 3. What's next?
+
+
+
+
+
diff --git a/playground/typescript-jsx-router-vitest/src/components/TheWelcome.vue b/playground/typescript-jsx-router-vitest/src/components/TheWelcome.vue
new file mode 100644
index 000000000..49d8f7354
--- /dev/null
+++ b/playground/typescript-jsx-router-vitest/src/components/TheWelcome.vue
@@ -0,0 +1,88 @@
+
+
+
+
+
+
+
+ Documentation
+
+ Vue’s
+ official documentation
+ provides you with all information you need to get started.
+
+
+
+
+
+
+ Tooling
+
+ This project is served and bundled with
+ Vite. The
+ recommended IDE setup is
+ VSCode +
+ Volar. If
+ you need to test your components and web pages, check out
+ Cypress and
+ Cypress Component Testing.
+
+
+
+ More instructions are available in README.md.
+
+
+
+
+
+
+ Ecosystem
+
+ Get official tools and libraries for your project:
+ Pinia,
+ Vue Router,
+ Vue Test Utils, and
+ Vue Dev Tools. If
+ you need more resources, we suggest paying
+ Awesome Vue
+ a visit.
+
+
+
+
+
+
+ Community
+
+ Got stuck? Ask your question on
+ Vue Land, our official
+ Discord server, or
+ StackOverflow. You should also subscribe to
+ our mailing list and follow
+ the official
+ @vuejs
+ twitter account for latest news in the Vue world.
+
+
+
+
+
+
+ Support Vue
+
+ As an independent project, Vue relies on community backing for its sustainability. You can help
+ us by
+ becoming a sponsor.
+
+
diff --git a/playground/typescript-jsx-router-vitest/src/components/WelcomeItem.vue b/playground/typescript-jsx-router-vitest/src/components/WelcomeItem.vue
new file mode 100644
index 000000000..6d7086aea
--- /dev/null
+++ b/playground/typescript-jsx-router-vitest/src/components/WelcomeItem.vue
@@ -0,0 +1,87 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/playground/typescript-jsx-router-vitest/src/components/__tests__/HelloWorld.spec.ts b/playground/typescript-jsx-router-vitest/src/components/__tests__/HelloWorld.spec.ts
new file mode 100644
index 000000000..253320200
--- /dev/null
+++ b/playground/typescript-jsx-router-vitest/src/components/__tests__/HelloWorld.spec.ts
@@ -0,0 +1,11 @@
+import { describe, it, expect } from 'vitest'
+
+import { mount } from '@vue/test-utils'
+import HelloWorld from '../HelloWorld.vue'
+
+describe('HelloWorld', () => {
+ it('renders properly', () => {
+ const wrapper = mount(HelloWorld, { props: { msg: 'Hello Vitest' } })
+ expect(wrapper.text()).toContain('Hello Vitest')
+ })
+})
diff --git a/playground/typescript-jsx-router-vitest/src/components/icons/IconCommunity.vue b/playground/typescript-jsx-router-vitest/src/components/icons/IconCommunity.vue
new file mode 100644
index 000000000..2dc8b0552
--- /dev/null
+++ b/playground/typescript-jsx-router-vitest/src/components/icons/IconCommunity.vue
@@ -0,0 +1,7 @@
+
+
+
diff --git a/playground/typescript-jsx-router-vitest/src/components/icons/IconDocumentation.vue b/playground/typescript-jsx-router-vitest/src/components/icons/IconDocumentation.vue
new file mode 100644
index 000000000..6d4791cfb
--- /dev/null
+++ b/playground/typescript-jsx-router-vitest/src/components/icons/IconDocumentation.vue
@@ -0,0 +1,7 @@
+
+
+
diff --git a/playground/typescript-jsx-router-vitest/src/components/icons/IconEcosystem.vue b/playground/typescript-jsx-router-vitest/src/components/icons/IconEcosystem.vue
new file mode 100644
index 000000000..c3a4f078c
--- /dev/null
+++ b/playground/typescript-jsx-router-vitest/src/components/icons/IconEcosystem.vue
@@ -0,0 +1,7 @@
+
+
+
diff --git a/playground/typescript-jsx-router-vitest/src/components/icons/IconSupport.vue b/playground/typescript-jsx-router-vitest/src/components/icons/IconSupport.vue
new file mode 100644
index 000000000..7452834d3
--- /dev/null
+++ b/playground/typescript-jsx-router-vitest/src/components/icons/IconSupport.vue
@@ -0,0 +1,7 @@
+
+
+
diff --git a/playground/typescript-jsx-router-vitest/src/components/icons/IconTooling.vue b/playground/typescript-jsx-router-vitest/src/components/icons/IconTooling.vue
new file mode 100644
index 000000000..660598d7c
--- /dev/null
+++ b/playground/typescript-jsx-router-vitest/src/components/icons/IconTooling.vue
@@ -0,0 +1,19 @@
+
+
+
+
diff --git a/playground/typescript-jsx-router-vitest/src/main.ts b/playground/typescript-jsx-router-vitest/src/main.ts
new file mode 100644
index 000000000..5a5dbdba7
--- /dev/null
+++ b/playground/typescript-jsx-router-vitest/src/main.ts
@@ -0,0 +1,11 @@
+import './assets/main.css'
+
+import { createApp } from 'vue'
+import App from './App.vue'
+import router from './router'
+
+const app = createApp(App)
+
+app.use(router)
+
+app.mount('#app')
diff --git a/playground/typescript-jsx-router-vitest/src/router/index.ts b/playground/typescript-jsx-router-vitest/src/router/index.ts
new file mode 100644
index 000000000..a49ae507f
--- /dev/null
+++ b/playground/typescript-jsx-router-vitest/src/router/index.ts
@@ -0,0 +1,23 @@
+import { createRouter, createWebHistory } from 'vue-router'
+import HomeView from '../views/HomeView.vue'
+
+const router = createRouter({
+ history: createWebHistory(import.meta.env.BASE_URL),
+ routes: [
+ {
+ path: '/',
+ name: 'home',
+ component: HomeView
+ },
+ {
+ path: '/about',
+ name: 'about',
+ // route level code-splitting
+ // this generates a separate chunk (About.[hash].js) for this route
+ // which is lazy-loaded when the route is visited.
+ component: () => import('../views/AboutView.vue')
+ }
+ ]
+})
+
+export default router
diff --git a/playground/typescript-jsx-router-vitest/src/views/AboutView.vue b/playground/typescript-jsx-router-vitest/src/views/AboutView.vue
new file mode 100644
index 000000000..756ad2a17
--- /dev/null
+++ b/playground/typescript-jsx-router-vitest/src/views/AboutView.vue
@@ -0,0 +1,15 @@
+
+
+
This is an about page
+
+
+
+
diff --git a/playground/typescript-jsx-router-vitest/src/views/HomeView.vue b/playground/typescript-jsx-router-vitest/src/views/HomeView.vue
new file mode 100644
index 000000000..d5c0217e4
--- /dev/null
+++ b/playground/typescript-jsx-router-vitest/src/views/HomeView.vue
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
diff --git a/playground/typescript-jsx-router-vitest/tsconfig.app.json b/playground/typescript-jsx-router-vitest/tsconfig.app.json
new file mode 100644
index 000000000..e14c754d3
--- /dev/null
+++ b/playground/typescript-jsx-router-vitest/tsconfig.app.json
@@ -0,0 +1,14 @@
+{
+ "extends": "@vue/tsconfig/tsconfig.dom.json",
+ "include": ["env.d.ts", "src/**/*", "src/**/*.vue"],
+ "exclude": ["src/**/__tests__/*"],
+ "compilerOptions": {
+ "composite": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
+
+ "baseUrl": ".",
+ "paths": {
+ "@/*": ["./src/*"]
+ }
+ }
+}
diff --git a/playground/typescript-jsx-router-vitest/tsconfig.json b/playground/typescript-jsx-router-vitest/tsconfig.json
new file mode 100644
index 000000000..100cf6a8f
--- /dev/null
+++ b/playground/typescript-jsx-router-vitest/tsconfig.json
@@ -0,0 +1,14 @@
+{
+ "files": [],
+ "references": [
+ {
+ "path": "./tsconfig.node.json"
+ },
+ {
+ "path": "./tsconfig.app.json"
+ },
+ {
+ "path": "./tsconfig.vitest.json"
+ }
+ ]
+}
diff --git a/playground/typescript-jsx-router-vitest/tsconfig.node.json b/playground/typescript-jsx-router-vitest/tsconfig.node.json
new file mode 100644
index 000000000..f09406303
--- /dev/null
+++ b/playground/typescript-jsx-router-vitest/tsconfig.node.json
@@ -0,0 +1,19 @@
+{
+ "extends": "@tsconfig/node20/tsconfig.json",
+ "include": [
+ "vite.config.*",
+ "vitest.config.*",
+ "cypress.config.*",
+ "nightwatch.conf.*",
+ "playwright.config.*"
+ ],
+ "compilerOptions": {
+ "composite": true,
+ "noEmit": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
+
+ "module": "ESNext",
+ "moduleResolution": "Bundler",
+ "types": ["node"]
+ }
+}
diff --git a/playground/typescript-jsx-router-vitest/tsconfig.vitest.json b/playground/typescript-jsx-router-vitest/tsconfig.vitest.json
new file mode 100644
index 000000000..571995d11
--- /dev/null
+++ b/playground/typescript-jsx-router-vitest/tsconfig.vitest.json
@@ -0,0 +1,11 @@
+{
+ "extends": "./tsconfig.app.json",
+ "exclude": [],
+ "compilerOptions": {
+ "composite": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.vitest.tsbuildinfo",
+
+ "lib": [],
+ "types": ["node", "jsdom"]
+ }
+}
diff --git a/playground/typescript-jsx-router-vitest/vite.config.ts b/playground/typescript-jsx-router-vitest/vite.config.ts
new file mode 100644
index 000000000..36c618756
--- /dev/null
+++ b/playground/typescript-jsx-router-vitest/vite.config.ts
@@ -0,0 +1,18 @@
+import { fileURLToPath, URL } from 'node:url'
+
+import { defineConfig } from 'vite'
+import vue from '@vitejs/plugin-vue'
+import vueJsx from '@vitejs/plugin-vue-jsx'
+
+// https://vitejs.dev/config/
+export default defineConfig({
+ plugins: [
+ vue(),
+ vueJsx(),
+ ],
+ resolve: {
+ alias: {
+ '@': fileURLToPath(new URL('./src', import.meta.url))
+ }
+ }
+})
diff --git a/playground/typescript-jsx-router-vitest/vitest.config.ts b/playground/typescript-jsx-router-vitest/vitest.config.ts
new file mode 100644
index 000000000..10067d578
--- /dev/null
+++ b/playground/typescript-jsx-router-vitest/vitest.config.ts
@@ -0,0 +1,14 @@
+import { fileURLToPath } from 'node:url'
+import { mergeConfig, defineConfig, configDefaults } from 'vitest/config'
+import viteConfig from './vite.config'
+
+export default mergeConfig(
+ viteConfig,
+ defineConfig({
+ test: {
+ environment: 'jsdom',
+ exclude: [...configDefaults.exclude, 'e2e/*'],
+ root: fileURLToPath(new URL('./', import.meta.url))
+ }
+ })
+)
diff --git a/playground/typescript-jsx-router-with-tests/.gitignore b/playground/typescript-jsx-router-with-tests/.gitignore
new file mode 100644
index 000000000..8ee54e8d3
--- /dev/null
+++ b/playground/typescript-jsx-router-with-tests/.gitignore
@@ -0,0 +1,30 @@
+# 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/
+
+# Editor directories and files
+.vscode/*
+!.vscode/extensions.json
+.idea
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?
+
+*.tsbuildinfo
diff --git a/playground/typescript-jsx-router-with-tests/README.md b/playground/typescript-jsx-router-with-tests/README.md
new file mode 100644
index 000000000..f51d0abc6
--- /dev/null
+++ b/playground/typescript-jsx-router-with-tests/README.md
@@ -0,0 +1,62 @@
+# typescript-jsx-router-with-tests
+
+This template should help get you started developing with Vue 3 in Vite.
+
+## Recommended IDE Setup
+
+[VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur) + [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin).
+
+## Type Support for `.vue` Imports in TS
+
+TypeScript cannot handle type information for `.vue` imports by default, so we replace the `tsc` CLI with `vue-tsc` for type checking. In editors, we need [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin) to make the TypeScript language service aware of `.vue` types.
+
+If the standalone TypeScript plugin doesn't feel fast enough to you, Volar has also implemented a [Take Over Mode](https://github.com/johnsoncodehk/volar/discussions/471#discussioncomment-1361669) that is more performant. You can enable it by the following steps:
+
+1. Disable the built-in TypeScript Extension
+ 1) Run `Extensions: Show Built-in Extensions` from VSCode's command palette
+ 2) Find `TypeScript and JavaScript Language Features`, right click and select `Disable (Workspace)`
+2. Reload the VSCode window by running `Developer: Reload Window` from the command palette.
+
+## Customize configuration
+
+See [Vite Configuration Reference](https://vitejs.dev/config/).
+
+## Project Setup
+
+```sh
+pnpm install
+```
+
+### Compile and Hot-Reload for Development
+
+```sh
+pnpm dev
+```
+
+### Type-Check, Compile and Minify for Production
+
+```sh
+pnpm build
+```
+
+### Run Unit Tests with [Vitest](https://vitest.dev/)
+
+```sh
+pnpm test:unit
+```
+
+### Run End-to-End Tests with [Cypress](https://www.cypress.io/)
+
+```sh
+pnpm test:e2e:dev
+```
+
+This runs the end-to-end tests against the Vite development server.
+It is much faster than the production build.
+
+But it's still recommended to test the production build with `test:e2e` before deploying (e.g. in CI environments):
+
+```sh
+pnpm build
+pnpm test:e2e
+```
diff --git a/playground/typescript-jsx-router-with-tests/cypress.config.ts b/playground/typescript-jsx-router-with-tests/cypress.config.ts
new file mode 100644
index 000000000..0f66080fd
--- /dev/null
+++ b/playground/typescript-jsx-router-with-tests/cypress.config.ts
@@ -0,0 +1,8 @@
+import { defineConfig } from 'cypress'
+
+export default defineConfig({
+ e2e: {
+ specPattern: 'cypress/e2e/**/*.{cy,spec}.{js,jsx,ts,tsx}',
+ baseUrl: 'http://localhost:4173'
+ }
+})
diff --git a/playground/typescript-jsx-router-with-tests/cypress/e2e/example.cy.ts b/playground/typescript-jsx-router-with-tests/cypress/e2e/example.cy.ts
new file mode 100644
index 000000000..7554c35d8
--- /dev/null
+++ b/playground/typescript-jsx-router-with-tests/cypress/e2e/example.cy.ts
@@ -0,0 +1,8 @@
+// https://on.cypress.io/api
+
+describe('My First Test', () => {
+ it('visits the app root url', () => {
+ cy.visit('/')
+ cy.contains('h1', 'You did it!')
+ })
+})
diff --git a/playground/typescript-jsx-router-with-tests/cypress/e2e/tsconfig.json b/playground/typescript-jsx-router-with-tests/cypress/e2e/tsconfig.json
new file mode 100644
index 000000000..37748feb7
--- /dev/null
+++ b/playground/typescript-jsx-router-with-tests/cypress/e2e/tsconfig.json
@@ -0,0 +1,10 @@
+{
+ "extends": "@vue/tsconfig/tsconfig.dom.json",
+ "include": ["./**/*", "../support/**/*"],
+ "compilerOptions": {
+ "isolatedModules": false,
+ "target": "es5",
+ "lib": ["es5", "dom"],
+ "types": ["cypress"]
+ }
+}
diff --git a/playground/typescript-jsx-router-with-tests/cypress/fixtures/example.json b/playground/typescript-jsx-router-with-tests/cypress/fixtures/example.json
new file mode 100644
index 000000000..02e425437
--- /dev/null
+++ b/playground/typescript-jsx-router-with-tests/cypress/fixtures/example.json
@@ -0,0 +1,5 @@
+{
+ "name": "Using fixtures to represent data",
+ "email": "hello@cypress.io",
+ "body": "Fixtures are a great way to mock data for responses to routes"
+}
diff --git a/playground/typescript-jsx-router-with-tests/cypress/support/commands.ts b/playground/typescript-jsx-router-with-tests/cypress/support/commands.ts
new file mode 100644
index 000000000..9b7bb8e25
--- /dev/null
+++ b/playground/typescript-jsx-router-with-tests/cypress/support/commands.ts
@@ -0,0 +1,39 @@
+///
+// ***********************************************
+// This example commands.ts shows you how to
+// create various custom commands and overwrite
+// existing commands.
+//
+// For more comprehensive examples of custom
+// commands please read more here:
+// https://on.cypress.io/custom-commands
+// ***********************************************
+//
+//
+// -- This is a parent command --
+// Cypress.Commands.add('login', (email, password) => { ... })
+//
+//
+// -- This is a child command --
+// Cypress.Commands.add('drag', { prevSubject: 'element'}, (subject, options) => { ... })
+//
+//
+// -- This is a dual command --
+// Cypress.Commands.add('dismiss', { prevSubject: 'optional'}, (subject, options) => { ... })
+//
+//
+// -- This will overwrite an existing command --
+// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... })
+//
+// declare global {
+// namespace Cypress {
+// interface Chainable {
+// login(email: string, password: string): Chainable
+// drag(subject: string, options?: Partial): Chainable
+// dismiss(subject: string, options?: Partial): Chainable
+// visit(originalFn: CommandOriginalFn, url: string, options: Partial): Chainable
+// }
+// }
+// }
+
+export {}
diff --git a/playground/typescript-jsx-router-with-tests/cypress/support/e2e.ts b/playground/typescript-jsx-router-with-tests/cypress/support/e2e.ts
new file mode 100644
index 000000000..d68db96df
--- /dev/null
+++ b/playground/typescript-jsx-router-with-tests/cypress/support/e2e.ts
@@ -0,0 +1,20 @@
+// ***********************************************************
+// This example support/index.js is processed and
+// loaded automatically before your test files.
+//
+// This is a great place to put global configuration and
+// behavior that modifies Cypress.
+//
+// You can change the location of this file or turn off
+// automatically serving support files with the
+// 'supportFile' configuration option.
+//
+// You can read more here:
+// https://on.cypress.io/configuration
+// ***********************************************************
+
+// Import commands.js using ES2015 syntax:
+import './commands'
+
+// Alternatively you can use CommonJS syntax:
+// require('./commands')
diff --git a/playground/typescript-jsx-router-with-tests/env.d.ts b/playground/typescript-jsx-router-with-tests/env.d.ts
new file mode 100644
index 000000000..11f02fe2a
--- /dev/null
+++ b/playground/typescript-jsx-router-with-tests/env.d.ts
@@ -0,0 +1 @@
+///
diff --git a/playground/typescript-jsx-router-with-tests/index.html b/playground/typescript-jsx-router-with-tests/index.html
new file mode 100644
index 000000000..a88854489
--- /dev/null
+++ b/playground/typescript-jsx-router-with-tests/index.html
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+ Vite App
+
+
+
+
+
+
diff --git a/playground/typescript-jsx-router-with-tests/package.json b/playground/typescript-jsx-router-with-tests/package.json
new file mode 100644
index 000000000..ece91193e
--- /dev/null
+++ b/playground/typescript-jsx-router-with-tests/package.json
@@ -0,0 +1,37 @@
+{
+ "name": "typescript-jsx-router-with-tests",
+ "version": "0.0.0",
+ "private": true,
+ "type": "module",
+ "scripts": {
+ "dev": "vite",
+ "build": "run-p type-check \"build-only {@}\" --",
+ "preview": "vite preview",
+ "test:unit": "vitest",
+ "test:e2e": "start-server-and-test preview http://localhost:4173 'cypress run --e2e'",
+ "test:e2e:dev": "start-server-and-test 'vite dev --port 4173' http://localhost:4173 'cypress open --e2e'",
+ "build-only": "vite build",
+ "type-check": "vue-tsc --build --force"
+ },
+ "dependencies": {
+ "vue": "^3.4.15",
+ "vue-router": "^4.2.5"
+ },
+ "devDependencies": {
+ "@tsconfig/node20": "^20.1.2",
+ "@types/jsdom": "^21.1.6",
+ "@types/node": "^20.11.16",
+ "@vitejs/plugin-vue": "^5.0.3",
+ "@vitejs/plugin-vue-jsx": "^3.1.0",
+ "@vue/test-utils": "^2.4.4",
+ "@vue/tsconfig": "^0.5.1",
+ "cypress": "^13.6.4",
+ "jsdom": "^24.0.0",
+ "npm-run-all2": "^6.1.2",
+ "start-server-and-test": "^2.0.3",
+ "typescript": "~5.3.0",
+ "vite": "^5.0.11",
+ "vitest": "^1.2.2",
+ "vue-tsc": "^1.8.27"
+ }
+}
diff --git a/playground/typescript-jsx-router-with-tests/public/favicon.ico b/playground/typescript-jsx-router-with-tests/public/favicon.ico
new file mode 100644
index 000000000..df36fcfb7
Binary files /dev/null and b/playground/typescript-jsx-router-with-tests/public/favicon.ico differ
diff --git a/playground/typescript-jsx-router-with-tests/src/App.vue b/playground/typescript-jsx-router-with-tests/src/App.vue
new file mode 100644
index 000000000..7905b0516
--- /dev/null
+++ b/playground/typescript-jsx-router-with-tests/src/App.vue
@@ -0,0 +1,85 @@
+
+
+
+
+
+
+
+ You’ve successfully created a project with
+ Vite +
+ Vue 3. What's next?
+
+
+
+
+
diff --git a/playground/typescript-jsx-router-with-tests/src/components/TheWelcome.vue b/playground/typescript-jsx-router-with-tests/src/components/TheWelcome.vue
new file mode 100644
index 000000000..49d8f7354
--- /dev/null
+++ b/playground/typescript-jsx-router-with-tests/src/components/TheWelcome.vue
@@ -0,0 +1,88 @@
+
+
+
+
+
+
+
+ Documentation
+
+ Vue’s
+ official documentation
+ provides you with all information you need to get started.
+
+
+
+
+
+
+ Tooling
+
+ This project is served and bundled with
+ Vite. The
+ recommended IDE setup is
+ VSCode +
+ Volar. If
+ you need to test your components and web pages, check out
+ Cypress and
+ Cypress Component Testing.
+
+
+
+ More instructions are available in README.md.
+
+
+
+
+
+
+ Ecosystem
+
+ Get official tools and libraries for your project:
+ Pinia,
+ Vue Router,
+ Vue Test Utils, and
+ Vue Dev Tools. If
+ you need more resources, we suggest paying
+ Awesome Vue
+ a visit.
+
+
+
+
+
+
+ Community
+
+ Got stuck? Ask your question on
+ Vue Land, our official
+ Discord server, or
+ StackOverflow. You should also subscribe to
+ our mailing list and follow
+ the official
+ @vuejs
+ twitter account for latest news in the Vue world.
+
+
+
+
+
+
+ Support Vue
+
+ As an independent project, Vue relies on community backing for its sustainability. You can help
+ us by
+ becoming a sponsor.
+
+
diff --git a/playground/typescript-jsx-router-with-tests/src/components/WelcomeItem.vue b/playground/typescript-jsx-router-with-tests/src/components/WelcomeItem.vue
new file mode 100644
index 000000000..6d7086aea
--- /dev/null
+++ b/playground/typescript-jsx-router-with-tests/src/components/WelcomeItem.vue
@@ -0,0 +1,87 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/playground/typescript-jsx-router-with-tests/src/components/__tests__/HelloWorld.spec.ts b/playground/typescript-jsx-router-with-tests/src/components/__tests__/HelloWorld.spec.ts
new file mode 100644
index 000000000..253320200
--- /dev/null
+++ b/playground/typescript-jsx-router-with-tests/src/components/__tests__/HelloWorld.spec.ts
@@ -0,0 +1,11 @@
+import { describe, it, expect } from 'vitest'
+
+import { mount } from '@vue/test-utils'
+import HelloWorld from '../HelloWorld.vue'
+
+describe('HelloWorld', () => {
+ it('renders properly', () => {
+ const wrapper = mount(HelloWorld, { props: { msg: 'Hello Vitest' } })
+ expect(wrapper.text()).toContain('Hello Vitest')
+ })
+})
diff --git a/playground/typescript-jsx-router-with-tests/src/components/icons/IconCommunity.vue b/playground/typescript-jsx-router-with-tests/src/components/icons/IconCommunity.vue
new file mode 100644
index 000000000..2dc8b0552
--- /dev/null
+++ b/playground/typescript-jsx-router-with-tests/src/components/icons/IconCommunity.vue
@@ -0,0 +1,7 @@
+
+
+
diff --git a/playground/typescript-jsx-router-with-tests/src/components/icons/IconDocumentation.vue b/playground/typescript-jsx-router-with-tests/src/components/icons/IconDocumentation.vue
new file mode 100644
index 000000000..6d4791cfb
--- /dev/null
+++ b/playground/typescript-jsx-router-with-tests/src/components/icons/IconDocumentation.vue
@@ -0,0 +1,7 @@
+
+
+
diff --git a/playground/typescript-jsx-router-with-tests/src/components/icons/IconEcosystem.vue b/playground/typescript-jsx-router-with-tests/src/components/icons/IconEcosystem.vue
new file mode 100644
index 000000000..c3a4f078c
--- /dev/null
+++ b/playground/typescript-jsx-router-with-tests/src/components/icons/IconEcosystem.vue
@@ -0,0 +1,7 @@
+
+
+
diff --git a/playground/typescript-jsx-router-with-tests/src/components/icons/IconSupport.vue b/playground/typescript-jsx-router-with-tests/src/components/icons/IconSupport.vue
new file mode 100644
index 000000000..7452834d3
--- /dev/null
+++ b/playground/typescript-jsx-router-with-tests/src/components/icons/IconSupport.vue
@@ -0,0 +1,7 @@
+
+
+
diff --git a/playground/typescript-jsx-router-with-tests/src/components/icons/IconTooling.vue b/playground/typescript-jsx-router-with-tests/src/components/icons/IconTooling.vue
new file mode 100644
index 000000000..660598d7c
--- /dev/null
+++ b/playground/typescript-jsx-router-with-tests/src/components/icons/IconTooling.vue
@@ -0,0 +1,19 @@
+
+
+
+
diff --git a/playground/typescript-jsx-router-with-tests/src/main.ts b/playground/typescript-jsx-router-with-tests/src/main.ts
new file mode 100644
index 000000000..5a5dbdba7
--- /dev/null
+++ b/playground/typescript-jsx-router-with-tests/src/main.ts
@@ -0,0 +1,11 @@
+import './assets/main.css'
+
+import { createApp } from 'vue'
+import App from './App.vue'
+import router from './router'
+
+const app = createApp(App)
+
+app.use(router)
+
+app.mount('#app')
diff --git a/playground/typescript-jsx-router-with-tests/src/router/index.ts b/playground/typescript-jsx-router-with-tests/src/router/index.ts
new file mode 100644
index 000000000..a49ae507f
--- /dev/null
+++ b/playground/typescript-jsx-router-with-tests/src/router/index.ts
@@ -0,0 +1,23 @@
+import { createRouter, createWebHistory } from 'vue-router'
+import HomeView from '../views/HomeView.vue'
+
+const router = createRouter({
+ history: createWebHistory(import.meta.env.BASE_URL),
+ routes: [
+ {
+ path: '/',
+ name: 'home',
+ component: HomeView
+ },
+ {
+ path: '/about',
+ name: 'about',
+ // route level code-splitting
+ // this generates a separate chunk (About.[hash].js) for this route
+ // which is lazy-loaded when the route is visited.
+ component: () => import('../views/AboutView.vue')
+ }
+ ]
+})
+
+export default router
diff --git a/playground/typescript-jsx-router-with-tests/src/views/AboutView.vue b/playground/typescript-jsx-router-with-tests/src/views/AboutView.vue
new file mode 100644
index 000000000..756ad2a17
--- /dev/null
+++ b/playground/typescript-jsx-router-with-tests/src/views/AboutView.vue
@@ -0,0 +1,15 @@
+
+
+
This is an about page
+
+
+
+
diff --git a/playground/typescript-jsx-router-with-tests/src/views/HomeView.vue b/playground/typescript-jsx-router-with-tests/src/views/HomeView.vue
new file mode 100644
index 000000000..d5c0217e4
--- /dev/null
+++ b/playground/typescript-jsx-router-with-tests/src/views/HomeView.vue
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
diff --git a/playground/typescript-jsx-router-with-tests/tsconfig.app.json b/playground/typescript-jsx-router-with-tests/tsconfig.app.json
new file mode 100644
index 000000000..e14c754d3
--- /dev/null
+++ b/playground/typescript-jsx-router-with-tests/tsconfig.app.json
@@ -0,0 +1,14 @@
+{
+ "extends": "@vue/tsconfig/tsconfig.dom.json",
+ "include": ["env.d.ts", "src/**/*", "src/**/*.vue"],
+ "exclude": ["src/**/__tests__/*"],
+ "compilerOptions": {
+ "composite": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
+
+ "baseUrl": ".",
+ "paths": {
+ "@/*": ["./src/*"]
+ }
+ }
+}
diff --git a/playground/typescript-jsx-router-with-tests/tsconfig.json b/playground/typescript-jsx-router-with-tests/tsconfig.json
new file mode 100644
index 000000000..5304731b8
--- /dev/null
+++ b/playground/typescript-jsx-router-with-tests/tsconfig.json
@@ -0,0 +1,17 @@
+{
+ "files": [],
+ "references": [
+ {
+ "path": "./tsconfig.node.json"
+ },
+ {
+ "path": "./tsconfig.app.json"
+ },
+ {
+ "path": "./tsconfig.vitest.json"
+ }
+ ],
+ "compilerOptions": {
+ "module": "NodeNext"
+ }
+}
diff --git a/playground/typescript-jsx-router-with-tests/tsconfig.node.json b/playground/typescript-jsx-router-with-tests/tsconfig.node.json
new file mode 100644
index 000000000..f09406303
--- /dev/null
+++ b/playground/typescript-jsx-router-with-tests/tsconfig.node.json
@@ -0,0 +1,19 @@
+{
+ "extends": "@tsconfig/node20/tsconfig.json",
+ "include": [
+ "vite.config.*",
+ "vitest.config.*",
+ "cypress.config.*",
+ "nightwatch.conf.*",
+ "playwright.config.*"
+ ],
+ "compilerOptions": {
+ "composite": true,
+ "noEmit": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
+
+ "module": "ESNext",
+ "moduleResolution": "Bundler",
+ "types": ["node"]
+ }
+}
diff --git a/playground/typescript-jsx-router-with-tests/tsconfig.vitest.json b/playground/typescript-jsx-router-with-tests/tsconfig.vitest.json
new file mode 100644
index 000000000..571995d11
--- /dev/null
+++ b/playground/typescript-jsx-router-with-tests/tsconfig.vitest.json
@@ -0,0 +1,11 @@
+{
+ "extends": "./tsconfig.app.json",
+ "exclude": [],
+ "compilerOptions": {
+ "composite": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.vitest.tsbuildinfo",
+
+ "lib": [],
+ "types": ["node", "jsdom"]
+ }
+}
diff --git a/playground/typescript-jsx-router-with-tests/vite.config.ts b/playground/typescript-jsx-router-with-tests/vite.config.ts
new file mode 100644
index 000000000..36c618756
--- /dev/null
+++ b/playground/typescript-jsx-router-with-tests/vite.config.ts
@@ -0,0 +1,18 @@
+import { fileURLToPath, URL } from 'node:url'
+
+import { defineConfig } from 'vite'
+import vue from '@vitejs/plugin-vue'
+import vueJsx from '@vitejs/plugin-vue-jsx'
+
+// https://vitejs.dev/config/
+export default defineConfig({
+ plugins: [
+ vue(),
+ vueJsx(),
+ ],
+ resolve: {
+ alias: {
+ '@': fileURLToPath(new URL('./src', import.meta.url))
+ }
+ }
+})
diff --git a/playground/typescript-jsx-router-with-tests/vitest.config.ts b/playground/typescript-jsx-router-with-tests/vitest.config.ts
new file mode 100644
index 000000000..10067d578
--- /dev/null
+++ b/playground/typescript-jsx-router-with-tests/vitest.config.ts
@@ -0,0 +1,14 @@
+import { fileURLToPath } from 'node:url'
+import { mergeConfig, defineConfig, configDefaults } from 'vitest/config'
+import viteConfig from './vite.config'
+
+export default mergeConfig(
+ viteConfig,
+ defineConfig({
+ test: {
+ environment: 'jsdom',
+ exclude: [...configDefaults.exclude, 'e2e/*'],
+ root: fileURLToPath(new URL('./', import.meta.url))
+ }
+ })
+)
diff --git a/playground/typescript-jsx-router/.gitignore b/playground/typescript-jsx-router/.gitignore
new file mode 100644
index 000000000..8ee54e8d3
--- /dev/null
+++ b/playground/typescript-jsx-router/.gitignore
@@ -0,0 +1,30 @@
+# 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/
+
+# Editor directories and files
+.vscode/*
+!.vscode/extensions.json
+.idea
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?
+
+*.tsbuildinfo
diff --git a/playground/typescript-jsx-router/README.md b/playground/typescript-jsx-router/README.md
new file mode 100644
index 000000000..1b2c57111
--- /dev/null
+++ b/playground/typescript-jsx-router/README.md
@@ -0,0 +1,40 @@
+# typescript-jsx-router
+
+This template should help get you started developing with Vue 3 in Vite.
+
+## Recommended IDE Setup
+
+[VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur) + [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin).
+
+## Type Support for `.vue` Imports in TS
+
+TypeScript cannot handle type information for `.vue` imports by default, so we replace the `tsc` CLI with `vue-tsc` for type checking. In editors, we need [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin) to make the TypeScript language service aware of `.vue` types.
+
+If the standalone TypeScript plugin doesn't feel fast enough to you, Volar has also implemented a [Take Over Mode](https://github.com/johnsoncodehk/volar/discussions/471#discussioncomment-1361669) that is more performant. You can enable it by the following steps:
+
+1. Disable the built-in TypeScript Extension
+ 1) Run `Extensions: Show Built-in Extensions` from VSCode's command palette
+ 2) Find `TypeScript and JavaScript Language Features`, right click and select `Disable (Workspace)`
+2. Reload the VSCode window by running `Developer: Reload Window` from the command palette.
+
+## Customize configuration
+
+See [Vite Configuration Reference](https://vitejs.dev/config/).
+
+## Project Setup
+
+```sh
+pnpm install
+```
+
+### Compile and Hot-Reload for Development
+
+```sh
+pnpm dev
+```
+
+### Type-Check, Compile and Minify for Production
+
+```sh
+pnpm build
+```
diff --git a/playground/typescript-jsx-router/env.d.ts b/playground/typescript-jsx-router/env.d.ts
new file mode 100644
index 000000000..11f02fe2a
--- /dev/null
+++ b/playground/typescript-jsx-router/env.d.ts
@@ -0,0 +1 @@
+///
diff --git a/playground/typescript-jsx-router/index.html b/playground/typescript-jsx-router/index.html
new file mode 100644
index 000000000..a88854489
--- /dev/null
+++ b/playground/typescript-jsx-router/index.html
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+ Vite App
+
+
+
+
+
+
diff --git a/playground/typescript-jsx-router/package.json b/playground/typescript-jsx-router/package.json
new file mode 100644
index 000000000..6b93101ae
--- /dev/null
+++ b/playground/typescript-jsx-router/package.json
@@ -0,0 +1,28 @@
+{
+ "name": "typescript-jsx-router",
+ "version": "0.0.0",
+ "private": true,
+ "type": "module",
+ "scripts": {
+ "dev": "vite",
+ "build": "run-p type-check \"build-only {@}\" --",
+ "preview": "vite preview",
+ "build-only": "vite build",
+ "type-check": "vue-tsc --build --force"
+ },
+ "dependencies": {
+ "vue": "^3.4.15",
+ "vue-router": "^4.2.5"
+ },
+ "devDependencies": {
+ "@tsconfig/node20": "^20.1.2",
+ "@types/node": "^20.11.16",
+ "@vitejs/plugin-vue": "^5.0.3",
+ "@vitejs/plugin-vue-jsx": "^3.1.0",
+ "@vue/tsconfig": "^0.5.1",
+ "npm-run-all2": "^6.1.2",
+ "typescript": "~5.3.0",
+ "vite": "^5.0.11",
+ "vue-tsc": "^1.8.27"
+ }
+}
diff --git a/playground/typescript-jsx-router/public/favicon.ico b/playground/typescript-jsx-router/public/favicon.ico
new file mode 100644
index 000000000..df36fcfb7
Binary files /dev/null and b/playground/typescript-jsx-router/public/favicon.ico differ
diff --git a/playground/typescript-jsx-router/src/App.vue b/playground/typescript-jsx-router/src/App.vue
new file mode 100644
index 000000000..7905b0516
--- /dev/null
+++ b/playground/typescript-jsx-router/src/App.vue
@@ -0,0 +1,85 @@
+
+
+
+
+
+
+
+ You’ve successfully created a project with
+ Vite +
+ Vue 3. What's next?
+
+
+
+
+
diff --git a/playground/typescript-jsx-router/src/components/TheWelcome.vue b/playground/typescript-jsx-router/src/components/TheWelcome.vue
new file mode 100644
index 000000000..49d8f7354
--- /dev/null
+++ b/playground/typescript-jsx-router/src/components/TheWelcome.vue
@@ -0,0 +1,88 @@
+
+
+
+
+
+
+
+ Documentation
+
+ Vue’s
+ official documentation
+ provides you with all information you need to get started.
+
+
+
+
+
+
+ Tooling
+
+ This project is served and bundled with
+ Vite. The
+ recommended IDE setup is
+ VSCode +
+ Volar. If
+ you need to test your components and web pages, check out
+ Cypress and
+ Cypress Component Testing.
+
+
+
+ More instructions are available in README.md.
+
+
+
+
+
+
+ Ecosystem
+
+ Get official tools and libraries for your project:
+ Pinia,
+ Vue Router,
+ Vue Test Utils, and
+ Vue Dev Tools. If
+ you need more resources, we suggest paying
+ Awesome Vue
+ a visit.
+
+
+
+
+
+
+ Community
+
+ Got stuck? Ask your question on
+ Vue Land, our official
+ Discord server, or
+ StackOverflow. You should also subscribe to
+ our mailing list and follow
+ the official
+ @vuejs
+ twitter account for latest news in the Vue world.
+
+
+
+
+
+
+ Support Vue
+
+ As an independent project, Vue relies on community backing for its sustainability. You can help
+ us by
+ becoming a sponsor.
+
+
diff --git a/playground/typescript-jsx-router/src/components/WelcomeItem.vue b/playground/typescript-jsx-router/src/components/WelcomeItem.vue
new file mode 100644
index 000000000..6d7086aea
--- /dev/null
+++ b/playground/typescript-jsx-router/src/components/WelcomeItem.vue
@@ -0,0 +1,87 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/playground/typescript-jsx-router/src/components/icons/IconCommunity.vue b/playground/typescript-jsx-router/src/components/icons/IconCommunity.vue
new file mode 100644
index 000000000..2dc8b0552
--- /dev/null
+++ b/playground/typescript-jsx-router/src/components/icons/IconCommunity.vue
@@ -0,0 +1,7 @@
+
+
+
diff --git a/playground/typescript-jsx-router/src/components/icons/IconDocumentation.vue b/playground/typescript-jsx-router/src/components/icons/IconDocumentation.vue
new file mode 100644
index 000000000..6d4791cfb
--- /dev/null
+++ b/playground/typescript-jsx-router/src/components/icons/IconDocumentation.vue
@@ -0,0 +1,7 @@
+
+
+
diff --git a/playground/typescript-jsx-router/src/components/icons/IconEcosystem.vue b/playground/typescript-jsx-router/src/components/icons/IconEcosystem.vue
new file mode 100644
index 000000000..c3a4f078c
--- /dev/null
+++ b/playground/typescript-jsx-router/src/components/icons/IconEcosystem.vue
@@ -0,0 +1,7 @@
+
+
+
diff --git a/playground/typescript-jsx-router/src/components/icons/IconSupport.vue b/playground/typescript-jsx-router/src/components/icons/IconSupport.vue
new file mode 100644
index 000000000..7452834d3
--- /dev/null
+++ b/playground/typescript-jsx-router/src/components/icons/IconSupport.vue
@@ -0,0 +1,7 @@
+
+
+
diff --git a/playground/typescript-jsx-router/src/components/icons/IconTooling.vue b/playground/typescript-jsx-router/src/components/icons/IconTooling.vue
new file mode 100644
index 000000000..660598d7c
--- /dev/null
+++ b/playground/typescript-jsx-router/src/components/icons/IconTooling.vue
@@ -0,0 +1,19 @@
+
+
+
+
diff --git a/playground/typescript-jsx-router/src/main.ts b/playground/typescript-jsx-router/src/main.ts
new file mode 100644
index 000000000..5a5dbdba7
--- /dev/null
+++ b/playground/typescript-jsx-router/src/main.ts
@@ -0,0 +1,11 @@
+import './assets/main.css'
+
+import { createApp } from 'vue'
+import App from './App.vue'
+import router from './router'
+
+const app = createApp(App)
+
+app.use(router)
+
+app.mount('#app')
diff --git a/playground/typescript-jsx-router/src/router/index.ts b/playground/typescript-jsx-router/src/router/index.ts
new file mode 100644
index 000000000..a49ae507f
--- /dev/null
+++ b/playground/typescript-jsx-router/src/router/index.ts
@@ -0,0 +1,23 @@
+import { createRouter, createWebHistory } from 'vue-router'
+import HomeView from '../views/HomeView.vue'
+
+const router = createRouter({
+ history: createWebHistory(import.meta.env.BASE_URL),
+ routes: [
+ {
+ path: '/',
+ name: 'home',
+ component: HomeView
+ },
+ {
+ path: '/about',
+ name: 'about',
+ // route level code-splitting
+ // this generates a separate chunk (About.[hash].js) for this route
+ // which is lazy-loaded when the route is visited.
+ component: () => import('../views/AboutView.vue')
+ }
+ ]
+})
+
+export default router
diff --git a/playground/typescript-jsx-router/src/views/AboutView.vue b/playground/typescript-jsx-router/src/views/AboutView.vue
new file mode 100644
index 000000000..756ad2a17
--- /dev/null
+++ b/playground/typescript-jsx-router/src/views/AboutView.vue
@@ -0,0 +1,15 @@
+
+
+
This is an about page
+
+
+
+
diff --git a/playground/typescript-jsx-router/src/views/HomeView.vue b/playground/typescript-jsx-router/src/views/HomeView.vue
new file mode 100644
index 000000000..d5c0217e4
--- /dev/null
+++ b/playground/typescript-jsx-router/src/views/HomeView.vue
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
diff --git a/playground/typescript-jsx-router/tsconfig.app.json b/playground/typescript-jsx-router/tsconfig.app.json
new file mode 100644
index 000000000..e14c754d3
--- /dev/null
+++ b/playground/typescript-jsx-router/tsconfig.app.json
@@ -0,0 +1,14 @@
+{
+ "extends": "@vue/tsconfig/tsconfig.dom.json",
+ "include": ["env.d.ts", "src/**/*", "src/**/*.vue"],
+ "exclude": ["src/**/__tests__/*"],
+ "compilerOptions": {
+ "composite": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
+
+ "baseUrl": ".",
+ "paths": {
+ "@/*": ["./src/*"]
+ }
+ }
+}
diff --git a/playground/typescript-jsx-router/tsconfig.json b/playground/typescript-jsx-router/tsconfig.json
new file mode 100644
index 000000000..66b5e5703
--- /dev/null
+++ b/playground/typescript-jsx-router/tsconfig.json
@@ -0,0 +1,11 @@
+{
+ "files": [],
+ "references": [
+ {
+ "path": "./tsconfig.node.json"
+ },
+ {
+ "path": "./tsconfig.app.json"
+ }
+ ]
+}
diff --git a/playground/typescript-jsx-router/tsconfig.node.json b/playground/typescript-jsx-router/tsconfig.node.json
new file mode 100644
index 000000000..f09406303
--- /dev/null
+++ b/playground/typescript-jsx-router/tsconfig.node.json
@@ -0,0 +1,19 @@
+{
+ "extends": "@tsconfig/node20/tsconfig.json",
+ "include": [
+ "vite.config.*",
+ "vitest.config.*",
+ "cypress.config.*",
+ "nightwatch.conf.*",
+ "playwright.config.*"
+ ],
+ "compilerOptions": {
+ "composite": true,
+ "noEmit": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
+
+ "module": "ESNext",
+ "moduleResolution": "Bundler",
+ "types": ["node"]
+ }
+}
diff --git a/playground/typescript-jsx-router/vite.config.ts b/playground/typescript-jsx-router/vite.config.ts
new file mode 100644
index 000000000..36c618756
--- /dev/null
+++ b/playground/typescript-jsx-router/vite.config.ts
@@ -0,0 +1,18 @@
+import { fileURLToPath, URL } from 'node:url'
+
+import { defineConfig } from 'vite'
+import vue from '@vitejs/plugin-vue'
+import vueJsx from '@vitejs/plugin-vue-jsx'
+
+// https://vitejs.dev/config/
+export default defineConfig({
+ plugins: [
+ vue(),
+ vueJsx(),
+ ],
+ resolve: {
+ alias: {
+ '@': fileURLToPath(new URL('./src', import.meta.url))
+ }
+ }
+})
diff --git a/playground/typescript-jsx-vitest-cypress/.gitignore b/playground/typescript-jsx-vitest-cypress/.gitignore
new file mode 100644
index 000000000..8ee54e8d3
--- /dev/null
+++ b/playground/typescript-jsx-vitest-cypress/.gitignore
@@ -0,0 +1,30 @@
+# 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/
+
+# Editor directories and files
+.vscode/*
+!.vscode/extensions.json
+.idea
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?
+
+*.tsbuildinfo
diff --git a/playground/typescript-jsx-vitest-cypress/README.md b/playground/typescript-jsx-vitest-cypress/README.md
new file mode 100644
index 000000000..69d98a5c1
--- /dev/null
+++ b/playground/typescript-jsx-vitest-cypress/README.md
@@ -0,0 +1,62 @@
+# typescript-jsx-vitest-cypress
+
+This template should help get you started developing with Vue 3 in Vite.
+
+## Recommended IDE Setup
+
+[VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur) + [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin).
+
+## Type Support for `.vue` Imports in TS
+
+TypeScript cannot handle type information for `.vue` imports by default, so we replace the `tsc` CLI with `vue-tsc` for type checking. In editors, we need [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin) to make the TypeScript language service aware of `.vue` types.
+
+If the standalone TypeScript plugin doesn't feel fast enough to you, Volar has also implemented a [Take Over Mode](https://github.com/johnsoncodehk/volar/discussions/471#discussioncomment-1361669) that is more performant. You can enable it by the following steps:
+
+1. Disable the built-in TypeScript Extension
+ 1) Run `Extensions: Show Built-in Extensions` from VSCode's command palette
+ 2) Find `TypeScript and JavaScript Language Features`, right click and select `Disable (Workspace)`
+2. Reload the VSCode window by running `Developer: Reload Window` from the command palette.
+
+## Customize configuration
+
+See [Vite Configuration Reference](https://vitejs.dev/config/).
+
+## Project Setup
+
+```sh
+pnpm install
+```
+
+### Compile and Hot-Reload for Development
+
+```sh
+pnpm dev
+```
+
+### Type-Check, Compile and Minify for Production
+
+```sh
+pnpm build
+```
+
+### Run Unit Tests with [Vitest](https://vitest.dev/)
+
+```sh
+pnpm test:unit
+```
+
+### Run End-to-End Tests with [Cypress](https://www.cypress.io/)
+
+```sh
+pnpm test:e2e:dev
+```
+
+This runs the end-to-end tests against the Vite development server.
+It is much faster than the production build.
+
+But it's still recommended to test the production build with `test:e2e` before deploying (e.g. in CI environments):
+
+```sh
+pnpm build
+pnpm test:e2e
+```
diff --git a/playground/typescript-jsx-vitest-cypress/cypress.config.ts b/playground/typescript-jsx-vitest-cypress/cypress.config.ts
new file mode 100644
index 000000000..0f66080fd
--- /dev/null
+++ b/playground/typescript-jsx-vitest-cypress/cypress.config.ts
@@ -0,0 +1,8 @@
+import { defineConfig } from 'cypress'
+
+export default defineConfig({
+ e2e: {
+ specPattern: 'cypress/e2e/**/*.{cy,spec}.{js,jsx,ts,tsx}',
+ baseUrl: 'http://localhost:4173'
+ }
+})
diff --git a/playground/typescript-jsx-vitest-cypress/cypress/e2e/example.cy.ts b/playground/typescript-jsx-vitest-cypress/cypress/e2e/example.cy.ts
new file mode 100644
index 000000000..7554c35d8
--- /dev/null
+++ b/playground/typescript-jsx-vitest-cypress/cypress/e2e/example.cy.ts
@@ -0,0 +1,8 @@
+// https://on.cypress.io/api
+
+describe('My First Test', () => {
+ it('visits the app root url', () => {
+ cy.visit('/')
+ cy.contains('h1', 'You did it!')
+ })
+})
diff --git a/playground/typescript-jsx-vitest-cypress/cypress/e2e/tsconfig.json b/playground/typescript-jsx-vitest-cypress/cypress/e2e/tsconfig.json
new file mode 100644
index 000000000..37748feb7
--- /dev/null
+++ b/playground/typescript-jsx-vitest-cypress/cypress/e2e/tsconfig.json
@@ -0,0 +1,10 @@
+{
+ "extends": "@vue/tsconfig/tsconfig.dom.json",
+ "include": ["./**/*", "../support/**/*"],
+ "compilerOptions": {
+ "isolatedModules": false,
+ "target": "es5",
+ "lib": ["es5", "dom"],
+ "types": ["cypress"]
+ }
+}
diff --git a/playground/typescript-jsx-vitest-cypress/cypress/fixtures/example.json b/playground/typescript-jsx-vitest-cypress/cypress/fixtures/example.json
new file mode 100644
index 000000000..02e425437
--- /dev/null
+++ b/playground/typescript-jsx-vitest-cypress/cypress/fixtures/example.json
@@ -0,0 +1,5 @@
+{
+ "name": "Using fixtures to represent data",
+ "email": "hello@cypress.io",
+ "body": "Fixtures are a great way to mock data for responses to routes"
+}
diff --git a/playground/typescript-jsx-vitest-cypress/cypress/support/commands.ts b/playground/typescript-jsx-vitest-cypress/cypress/support/commands.ts
new file mode 100644
index 000000000..9b7bb8e25
--- /dev/null
+++ b/playground/typescript-jsx-vitest-cypress/cypress/support/commands.ts
@@ -0,0 +1,39 @@
+///
+// ***********************************************
+// This example commands.ts shows you how to
+// create various custom commands and overwrite
+// existing commands.
+//
+// For more comprehensive examples of custom
+// commands please read more here:
+// https://on.cypress.io/custom-commands
+// ***********************************************
+//
+//
+// -- This is a parent command --
+// Cypress.Commands.add('login', (email, password) => { ... })
+//
+//
+// -- This is a child command --
+// Cypress.Commands.add('drag', { prevSubject: 'element'}, (subject, options) => { ... })
+//
+//
+// -- This is a dual command --
+// Cypress.Commands.add('dismiss', { prevSubject: 'optional'}, (subject, options) => { ... })
+//
+//
+// -- This will overwrite an existing command --
+// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... })
+//
+// declare global {
+// namespace Cypress {
+// interface Chainable {
+// login(email: string, password: string): Chainable
+// drag(subject: string, options?: Partial): Chainable
+// dismiss(subject: string, options?: Partial): Chainable
+// visit(originalFn: CommandOriginalFn, url: string, options: Partial): Chainable
+// }
+// }
+// }
+
+export {}
diff --git a/playground/typescript-jsx-vitest-cypress/cypress/support/e2e.ts b/playground/typescript-jsx-vitest-cypress/cypress/support/e2e.ts
new file mode 100644
index 000000000..d68db96df
--- /dev/null
+++ b/playground/typescript-jsx-vitest-cypress/cypress/support/e2e.ts
@@ -0,0 +1,20 @@
+// ***********************************************************
+// This example support/index.js is processed and
+// loaded automatically before your test files.
+//
+// This is a great place to put global configuration and
+// behavior that modifies Cypress.
+//
+// You can change the location of this file or turn off
+// automatically serving support files with the
+// 'supportFile' configuration option.
+//
+// You can read more here:
+// https://on.cypress.io/configuration
+// ***********************************************************
+
+// Import commands.js using ES2015 syntax:
+import './commands'
+
+// Alternatively you can use CommonJS syntax:
+// require('./commands')
diff --git a/playground/typescript-jsx-vitest-cypress/env.d.ts b/playground/typescript-jsx-vitest-cypress/env.d.ts
new file mode 100644
index 000000000..11f02fe2a
--- /dev/null
+++ b/playground/typescript-jsx-vitest-cypress/env.d.ts
@@ -0,0 +1 @@
+///
diff --git a/playground/typescript-jsx-vitest-cypress/index.html b/playground/typescript-jsx-vitest-cypress/index.html
new file mode 100644
index 000000000..a88854489
--- /dev/null
+++ b/playground/typescript-jsx-vitest-cypress/index.html
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+ Vite App
+
+
+
+
+
+
diff --git a/playground/typescript-jsx-vitest-cypress/package.json b/playground/typescript-jsx-vitest-cypress/package.json
new file mode 100644
index 000000000..effc00243
--- /dev/null
+++ b/playground/typescript-jsx-vitest-cypress/package.json
@@ -0,0 +1,36 @@
+{
+ "name": "typescript-jsx-vitest-cypress",
+ "version": "0.0.0",
+ "private": true,
+ "type": "module",
+ "scripts": {
+ "dev": "vite",
+ "build": "run-p type-check \"build-only {@}\" --",
+ "preview": "vite preview",
+ "test:unit": "vitest",
+ "test:e2e": "start-server-and-test preview http://localhost:4173 'cypress run --e2e'",
+ "test:e2e:dev": "start-server-and-test 'vite dev --port 4173' http://localhost:4173 'cypress open --e2e'",
+ "build-only": "vite build",
+ "type-check": "vue-tsc --build --force"
+ },
+ "dependencies": {
+ "vue": "^3.4.15"
+ },
+ "devDependencies": {
+ "@tsconfig/node20": "^20.1.2",
+ "@types/jsdom": "^21.1.6",
+ "@types/node": "^20.11.16",
+ "@vitejs/plugin-vue": "^5.0.3",
+ "@vitejs/plugin-vue-jsx": "^3.1.0",
+ "@vue/test-utils": "^2.4.4",
+ "@vue/tsconfig": "^0.5.1",
+ "cypress": "^13.6.4",
+ "jsdom": "^24.0.0",
+ "npm-run-all2": "^6.1.2",
+ "start-server-and-test": "^2.0.3",
+ "typescript": "~5.3.0",
+ "vite": "^5.0.11",
+ "vitest": "^1.2.2",
+ "vue-tsc": "^1.8.27"
+ }
+}
diff --git a/playground/typescript-jsx-vitest-cypress/public/favicon.ico b/playground/typescript-jsx-vitest-cypress/public/favicon.ico
new file mode 100644
index 000000000..df36fcfb7
Binary files /dev/null and b/playground/typescript-jsx-vitest-cypress/public/favicon.ico differ
diff --git a/playground/typescript-jsx-vitest-cypress/src/App.vue b/playground/typescript-jsx-vitest-cypress/src/App.vue
new file mode 100644
index 000000000..69f32f91f
--- /dev/null
+++ b/playground/typescript-jsx-vitest-cypress/src/App.vue
@@ -0,0 +1,10 @@
+
+ app
+
+
+
+
+
diff --git a/playground/typescript-jsx-vitest-cypress/src/assets/logo.svg b/playground/typescript-jsx-vitest-cypress/src/assets/logo.svg
new file mode 100644
index 000000000..756566035
--- /dev/null
+++ b/playground/typescript-jsx-vitest-cypress/src/assets/logo.svg
@@ -0,0 +1 @@
+
diff --git a/playground/typescript-jsx-vitest-cypress/src/assets/main.css b/playground/typescript-jsx-vitest-cypress/src/assets/main.css
new file mode 100644
index 000000000..5aadc6ceb
--- /dev/null
+++ b/playground/typescript-jsx-vitest-cypress/src/assets/main.css
@@ -0,0 +1,6 @@
+html, body, #app {
+ width: 100%;
+ height: 100%;
+ padding: 0;
+ margin: 0;
+}
diff --git a/playground/typescript-jsx-vitest-cypress/src/components/__tests__/HelloWorld.spec.ts b/playground/typescript-jsx-vitest-cypress/src/components/__tests__/HelloWorld.spec.ts
new file mode 100644
index 000000000..253320200
--- /dev/null
+++ b/playground/typescript-jsx-vitest-cypress/src/components/__tests__/HelloWorld.spec.ts
@@ -0,0 +1,11 @@
+import { describe, it, expect } from 'vitest'
+
+import { mount } from '@vue/test-utils'
+import HelloWorld from '../HelloWorld.vue'
+
+describe('HelloWorld', () => {
+ it('renders properly', () => {
+ const wrapper = mount(HelloWorld, { props: { msg: 'Hello Vitest' } })
+ expect(wrapper.text()).toContain('Hello Vitest')
+ })
+})
diff --git a/playground/typescript-jsx-vitest-cypress/src/main.ts b/playground/typescript-jsx-vitest-cypress/src/main.ts
new file mode 100644
index 000000000..0ac3a5ff0
--- /dev/null
+++ b/playground/typescript-jsx-vitest-cypress/src/main.ts
@@ -0,0 +1,6 @@
+import './assets/main.css'
+
+import { createApp } from 'vue'
+import App from './App.vue'
+
+createApp(App).mount('#app')
diff --git a/playground/typescript-jsx-vitest-cypress/tsconfig.app.json b/playground/typescript-jsx-vitest-cypress/tsconfig.app.json
new file mode 100644
index 000000000..e14c754d3
--- /dev/null
+++ b/playground/typescript-jsx-vitest-cypress/tsconfig.app.json
@@ -0,0 +1,14 @@
+{
+ "extends": "@vue/tsconfig/tsconfig.dom.json",
+ "include": ["env.d.ts", "src/**/*", "src/**/*.vue"],
+ "exclude": ["src/**/__tests__/*"],
+ "compilerOptions": {
+ "composite": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
+
+ "baseUrl": ".",
+ "paths": {
+ "@/*": ["./src/*"]
+ }
+ }
+}
diff --git a/playground/typescript-jsx-vitest-cypress/tsconfig.json b/playground/typescript-jsx-vitest-cypress/tsconfig.json
new file mode 100644
index 000000000..5304731b8
--- /dev/null
+++ b/playground/typescript-jsx-vitest-cypress/tsconfig.json
@@ -0,0 +1,17 @@
+{
+ "files": [],
+ "references": [
+ {
+ "path": "./tsconfig.node.json"
+ },
+ {
+ "path": "./tsconfig.app.json"
+ },
+ {
+ "path": "./tsconfig.vitest.json"
+ }
+ ],
+ "compilerOptions": {
+ "module": "NodeNext"
+ }
+}
diff --git a/playground/typescript-jsx-vitest-cypress/tsconfig.node.json b/playground/typescript-jsx-vitest-cypress/tsconfig.node.json
new file mode 100644
index 000000000..f09406303
--- /dev/null
+++ b/playground/typescript-jsx-vitest-cypress/tsconfig.node.json
@@ -0,0 +1,19 @@
+{
+ "extends": "@tsconfig/node20/tsconfig.json",
+ "include": [
+ "vite.config.*",
+ "vitest.config.*",
+ "cypress.config.*",
+ "nightwatch.conf.*",
+ "playwright.config.*"
+ ],
+ "compilerOptions": {
+ "composite": true,
+ "noEmit": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
+
+ "module": "ESNext",
+ "moduleResolution": "Bundler",
+ "types": ["node"]
+ }
+}
diff --git a/playground/typescript-jsx-vitest-cypress/tsconfig.vitest.json b/playground/typescript-jsx-vitest-cypress/tsconfig.vitest.json
new file mode 100644
index 000000000..571995d11
--- /dev/null
+++ b/playground/typescript-jsx-vitest-cypress/tsconfig.vitest.json
@@ -0,0 +1,11 @@
+{
+ "extends": "./tsconfig.app.json",
+ "exclude": [],
+ "compilerOptions": {
+ "composite": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.vitest.tsbuildinfo",
+
+ "lib": [],
+ "types": ["node", "jsdom"]
+ }
+}
diff --git a/playground/typescript-jsx-vitest-cypress/vite.config.ts b/playground/typescript-jsx-vitest-cypress/vite.config.ts
new file mode 100644
index 000000000..36c618756
--- /dev/null
+++ b/playground/typescript-jsx-vitest-cypress/vite.config.ts
@@ -0,0 +1,18 @@
+import { fileURLToPath, URL } from 'node:url'
+
+import { defineConfig } from 'vite'
+import vue from '@vitejs/plugin-vue'
+import vueJsx from '@vitejs/plugin-vue-jsx'
+
+// https://vitejs.dev/config/
+export default defineConfig({
+ plugins: [
+ vue(),
+ vueJsx(),
+ ],
+ resolve: {
+ alias: {
+ '@': fileURLToPath(new URL('./src', import.meta.url))
+ }
+ }
+})
diff --git a/playground/typescript-jsx-vitest-cypress/vitest.config.ts b/playground/typescript-jsx-vitest-cypress/vitest.config.ts
new file mode 100644
index 000000000..10067d578
--- /dev/null
+++ b/playground/typescript-jsx-vitest-cypress/vitest.config.ts
@@ -0,0 +1,14 @@
+import { fileURLToPath } from 'node:url'
+import { mergeConfig, defineConfig, configDefaults } from 'vitest/config'
+import viteConfig from './vite.config'
+
+export default mergeConfig(
+ viteConfig,
+ defineConfig({
+ test: {
+ environment: 'jsdom',
+ exclude: [...configDefaults.exclude, 'e2e/*'],
+ root: fileURLToPath(new URL('./', import.meta.url))
+ }
+ })
+)
diff --git a/playground/typescript-jsx-vitest-nightwatch/.gitignore b/playground/typescript-jsx-vitest-nightwatch/.gitignore
new file mode 100644
index 000000000..0b938f131
--- /dev/null
+++ b/playground/typescript-jsx-vitest-nightwatch/.gitignore
@@ -0,0 +1,33 @@
+# 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/
+
+# Editor directories and files
+.vscode/*
+!.vscode/extensions.json
+.idea
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?
+
+*.tsbuildinfo
+
+logs/
+tests_output/
diff --git a/playground/typescript-jsx-vitest-nightwatch/.vscode/extensions.json b/playground/typescript-jsx-vitest-nightwatch/.vscode/extensions.json
new file mode 100644
index 000000000..dd9668a5c
--- /dev/null
+++ b/playground/typescript-jsx-vitest-nightwatch/.vscode/extensions.json
@@ -0,0 +1,3 @@
+{
+ "recommendations": ["browserstackcom.nightwatch"]
+}
diff --git a/playground/typescript-jsx-vitest-nightwatch/README.md b/playground/typescript-jsx-vitest-nightwatch/README.md
new file mode 100644
index 000000000..c4dbab749
--- /dev/null
+++ b/playground/typescript-jsx-vitest-nightwatch/README.md
@@ -0,0 +1,69 @@
+# typescript-jsx-vitest-nightwatch
+
+This template should help get you started developing with Vue 3 in Vite.
+
+## Recommended IDE Setup
+
+[VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur) + [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin).
+
+## Type Support for `.vue` Imports in TS
+
+TypeScript cannot handle type information for `.vue` imports by default, so we replace the `tsc` CLI with `vue-tsc` for type checking. In editors, we need [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin) to make the TypeScript language service aware of `.vue` types.
+
+If the standalone TypeScript plugin doesn't feel fast enough to you, Volar has also implemented a [Take Over Mode](https://github.com/johnsoncodehk/volar/discussions/471#discussioncomment-1361669) that is more performant. You can enable it by the following steps:
+
+1. Disable the built-in TypeScript Extension
+ 1) Run `Extensions: Show Built-in Extensions` from VSCode's command palette
+ 2) Find `TypeScript and JavaScript Language Features`, right click and select `Disable (Workspace)`
+2. Reload the VSCode window by running `Developer: Reload Window` from the command palette.
+
+## Customize configuration
+
+See [Vite Configuration Reference](https://vitejs.dev/config/).
+
+## Project Setup
+
+```sh
+pnpm install
+```
+
+### Compile and Hot-Reload for Development
+
+```sh
+pnpm dev
+```
+
+### Type-Check, Compile and Minify for Production
+
+```sh
+pnpm build
+```
+
+### Run Unit Tests with [Vitest](https://vitest.dev/)
+
+```sh
+pnpm test:unit
+```
+
+### Run End-to-End Tests with [Nightwatch](https://nightwatchjs.org/)
+
+```sh
+# When using CI, the project must be built first.
+pnpm build
+
+# Runs the end-to-end tests
+pnpm test:e2e
+# Runs the tests only on Chrome
+pnpm test:e2e --env chrome
+# Runs the tests of a specific file
+pnpm test:e2e tests/e2e/example.ts
+# Runs the tests in debug mode
+pnpm test:e2e --debug
+```
+
+### Run Headed Component Tests with [Nightwatch Component Testing](https://nightwatchjs.org/guide/component-testing/introduction.html)
+
+```sh
+pnpm test:unit
+pnpm test:unit -- --headless # for headless testing
+```
diff --git a/playground/typescript-jsx-vitest-nightwatch/env.d.ts b/playground/typescript-jsx-vitest-nightwatch/env.d.ts
new file mode 100644
index 000000000..11f02fe2a
--- /dev/null
+++ b/playground/typescript-jsx-vitest-nightwatch/env.d.ts
@@ -0,0 +1 @@
+///
diff --git a/playground/typescript-jsx-vitest-nightwatch/index.html b/playground/typescript-jsx-vitest-nightwatch/index.html
new file mode 100644
index 000000000..a88854489
--- /dev/null
+++ b/playground/typescript-jsx-vitest-nightwatch/index.html
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+ Vite App
+
+
+
+
+
+
diff --git a/playground/typescript-jsx-vitest-nightwatch/nightwatch.conf.cjs b/playground/typescript-jsx-vitest-nightwatch/nightwatch.conf.cjs
new file mode 100644
index 000000000..542647e5e
--- /dev/null
+++ b/playground/typescript-jsx-vitest-nightwatch/nightwatch.conf.cjs
@@ -0,0 +1,153 @@
+//
+// Refer to the online docs for more details:
+// https://nightwatchjs.org/guide/configuration/nightwatch-configuration-file.html
+//
+// _ _ _ _ _ _ _
+// | \ | |(_) | | | | | | | |
+// | \| | _ __ _ | |__ | |_ __ __ __ _ | |_ ___ | |__
+// | . ` || | / _` || '_ \ | __|\ \ /\ / / / _` || __| / __|| '_ \
+// | |\ || || (_| || | | || |_ \ V V / | (_| || |_ | (__ | | | |
+// \_| \_/|_| \__, ||_| |_| \__| \_/\_/ \__,_| \__| \___||_| |_|
+// __/ |
+// |___/
+//
+
+module.exports = {
+ // An array of folders (excluding subfolders) where your tests are located;
+ // if this is not specified, the test source must be passed as the second argument to the test runner.
+ src_folders: [],
+
+ // See https://nightwatchjs.org/guide/concepts/page-object-model.html
+ page_objects_path: [],
+
+ // See https://nightwatchjs.org/guide/extending-nightwatch/adding-custom-commands.html
+ custom_commands_path: [],
+
+ // See https://nightwatchjs.org/guide/extending-nightwatch/adding-custom-assertions.html
+ custom_assertions_path: [],
+
+ // See https://nightwatchjs.org/guide/extending-nightwatch/adding-plugins.html
+ plugins: ['@nightwatch/vue'],
+
+ // See https://nightwatchjs.org/guide/concepts/test-globals.html#external-test-globals
+ globals_path: '',
+
+ vite_dev_server: {
+ start_vite: true,
+ port: process.env.CI ? 4173 : 5173
+ },
+
+ webdriver: {},
+
+ test_workers: {
+ enabled: true,
+ workers: 'auto'
+ },
+
+ test_settings: {
+ default: {
+ disable_error_log: false,
+ launch_url: `http://localhost:${process.env.CI ? '4173' : '5173'}`,
+
+ screenshots: {
+ enabled: false,
+ path: 'screens',
+ on_failure: true
+ },
+
+ desiredCapabilities: {
+ browserName: 'firefox'
+ },
+
+ webdriver: {
+ start_process: true,
+ server_path: ''
+ }
+ },
+
+ safari: {
+ desiredCapabilities: {
+ browserName: 'safari',
+ alwaysMatch: {
+ acceptInsecureCerts: false
+ }
+ },
+ webdriver: {
+ start_process: true,
+ server_path: ''
+ }
+ },
+
+ firefox: {
+ desiredCapabilities: {
+ browserName: 'firefox',
+ alwaysMatch: {
+ acceptInsecureCerts: true,
+ 'moz:firefoxOptions': {
+ args: [
+ // '-headless',
+ // '-verbose'
+ ]
+ }
+ }
+ },
+ webdriver: {
+ start_process: true,
+ server_path: '',
+ cli_args: [
+ // very verbose geckodriver logs
+ // '-vv'
+ ]
+ }
+ },
+
+ chrome: {
+ desiredCapabilities: {
+ browserName: 'chrome',
+ 'goog:chromeOptions': {
+ // More info on Chromedriver: https://sites.google.com/a/chromium.org/chromedriver/
+ //
+ // w3c:false tells Chromedriver to run using the legacy JSONWire protocol (not required in Chrome 78)
+ w3c: true,
+ args: [
+ //'--no-sandbox',
+ //'--ignore-certificate-errors',
+ //'--allow-insecure-localhost',
+ //'--headless'
+ ]
+ }
+ },
+
+ webdriver: {
+ start_process: true,
+ server_path: '',
+ cli_args: [
+ // --verbose
+ ]
+ }
+ },
+
+ edge: {
+ desiredCapabilities: {
+ browserName: 'MicrosoftEdge',
+ 'ms:edgeOptions': {
+ w3c: true,
+ // More info on EdgeDriver: https://docs.microsoft.com/en-us/microsoft-edge/webdriver-chromium/capabilities-edge-options
+ args: [
+ //'--headless'
+ ]
+ }
+ },
+
+ webdriver: {
+ start_process: true,
+ // Download msedgedriver from https://docs.microsoft.com/en-us/microsoft-edge/webdriver-chromium/
+ // and set the location below:
+ server_path: '',
+ cli_args: [
+ // --verbose
+ ]
+ }
+ }
+ }
+}
diff --git a/playground/typescript-jsx-vitest-nightwatch/nightwatch/nightwatch.d.ts b/playground/typescript-jsx-vitest-nightwatch/nightwatch/nightwatch.d.ts
new file mode 100644
index 000000000..616e63f9f
--- /dev/null
+++ b/playground/typescript-jsx-vitest-nightwatch/nightwatch/nightwatch.d.ts
@@ -0,0 +1,13 @@
+import { NightwatchCustomAssertions, NightwatchCustomCommands } from 'nightwatch'
+
+declare module 'nightwatch' {
+ interface NightwatchCustomAssertions {
+ // Add your custom assertions' types here
+ // elementHasCount: (selector: string, count: number) => NightwatchBrowser
+ }
+
+ interface NightwatchCustomCommands {
+ // Add your custom commands' types here
+ // strictClick: (selector: string) => NightwatchBrowser
+ }
+}
diff --git a/playground/typescript-jsx-vitest-nightwatch/nightwatch/tsconfig.json b/playground/typescript-jsx-vitest-nightwatch/nightwatch/tsconfig.json
new file mode 100644
index 000000000..8cd7ca1da
--- /dev/null
+++ b/playground/typescript-jsx-vitest-nightwatch/nightwatch/tsconfig.json
@@ -0,0 +1,20 @@
+{
+ "extends": "@tsconfig/node20/tsconfig.json",
+ "compilerOptions": {
+ "composite": true,
+ "noEmit": true,
+ "tsBuildInfoFile": "../node_modules/.tmp/tsconfig.nightwatch.tsbuildinfo",
+
+ "target": "ESNext",
+ "module": "commonjs",
+ "moduleResolution": "node",
+ "rootDir": "../",
+ "lib": ["ESNext", "dom"],
+ "types": ["nightwatch"]
+ },
+ "include": ["../node_modules/@nightwatch/**/*", "../src/components/**/*", "../tests/e2e/**/*"],
+ "ts-node": {
+ "transpileOnly": true
+ },
+ "files": ["nightwatch.d.ts"]
+}
diff --git a/playground/typescript-jsx-vitest-nightwatch/package.json b/playground/typescript-jsx-vitest-nightwatch/package.json
new file mode 100644
index 000000000..75d98022d
--- /dev/null
+++ b/playground/typescript-jsx-vitest-nightwatch/package.json
@@ -0,0 +1,39 @@
+{
+ "name": "typescript-jsx-vitest-nightwatch",
+ "version": "0.0.0",
+ "private": true,
+ "type": "module",
+ "scripts": {
+ "dev": "vite",
+ "build": "run-p type-check \"build-only {@}\" --",
+ "preview": "vite preview",
+ "test:unit": "vitest",
+ "test:e2e": "nightwatch tests/e2e/*",
+ "build-only": "vite build",
+ "type-check": "vue-tsc --build --force"
+ },
+ "dependencies": {
+ "vue": "^3.4.15"
+ },
+ "devDependencies": {
+ "@nightwatch/vue": "^3.1.0",
+ "@tsconfig/node20": "^20.1.2",
+ "@types/jsdom": "^21.1.6",
+ "@types/node": "^20.11.16",
+ "@vitejs/plugin-vue": "^5.0.3",
+ "@vitejs/plugin-vue-jsx": "^3.1.0",
+ "@vue/test-utils": "^2.4.4",
+ "@vue/tsconfig": "^0.5.1",
+ "chromedriver": "^121.0.0",
+ "geckodriver": "^4.3.2",
+ "jsdom": "^24.0.0",
+ "nightwatch": "^3.4.0",
+ "npm-run-all2": "^6.1.2",
+ "ts-node": "^10.9.2",
+ "typescript": "~5.3.0",
+ "vite": "^5.0.11",
+ "vite-plugin-nightwatch": "^0.4.6",
+ "vitest": "^1.2.2",
+ "vue-tsc": "^1.8.27"
+ }
+}
diff --git a/playground/typescript-jsx-vitest-nightwatch/public/favicon.ico b/playground/typescript-jsx-vitest-nightwatch/public/favicon.ico
new file mode 100644
index 000000000..df36fcfb7
Binary files /dev/null and b/playground/typescript-jsx-vitest-nightwatch/public/favicon.ico differ
diff --git a/playground/typescript-jsx-vitest-nightwatch/src/App.vue b/playground/typescript-jsx-vitest-nightwatch/src/App.vue
new file mode 100644
index 000000000..69f32f91f
--- /dev/null
+++ b/playground/typescript-jsx-vitest-nightwatch/src/App.vue
@@ -0,0 +1,10 @@
+
+ app
+
+
+
+
+
diff --git a/playground/typescript-jsx-vitest-nightwatch/src/assets/logo.svg b/playground/typescript-jsx-vitest-nightwatch/src/assets/logo.svg
new file mode 100644
index 000000000..756566035
--- /dev/null
+++ b/playground/typescript-jsx-vitest-nightwatch/src/assets/logo.svg
@@ -0,0 +1 @@
+
diff --git a/playground/typescript-jsx-vitest-nightwatch/src/assets/main.css b/playground/typescript-jsx-vitest-nightwatch/src/assets/main.css
new file mode 100644
index 000000000..5aadc6ceb
--- /dev/null
+++ b/playground/typescript-jsx-vitest-nightwatch/src/assets/main.css
@@ -0,0 +1,6 @@
+html, body, #app {
+ width: 100%;
+ height: 100%;
+ padding: 0;
+ margin: 0;
+}
diff --git a/playground/typescript-jsx-vitest-nightwatch/src/components/__tests__/HelloWorld.spec.ts b/playground/typescript-jsx-vitest-nightwatch/src/components/__tests__/HelloWorld.spec.ts
new file mode 100644
index 000000000..253320200
--- /dev/null
+++ b/playground/typescript-jsx-vitest-nightwatch/src/components/__tests__/HelloWorld.spec.ts
@@ -0,0 +1,11 @@
+import { describe, it, expect } from 'vitest'
+
+import { mount } from '@vue/test-utils'
+import HelloWorld from '../HelloWorld.vue'
+
+describe('HelloWorld', () => {
+ it('renders properly', () => {
+ const wrapper = mount(HelloWorld, { props: { msg: 'Hello Vitest' } })
+ expect(wrapper.text()).toContain('Hello Vitest')
+ })
+})
diff --git a/playground/typescript-jsx-vitest-nightwatch/src/main.ts b/playground/typescript-jsx-vitest-nightwatch/src/main.ts
new file mode 100644
index 000000000..0ac3a5ff0
--- /dev/null
+++ b/playground/typescript-jsx-vitest-nightwatch/src/main.ts
@@ -0,0 +1,6 @@
+import './assets/main.css'
+
+import { createApp } from 'vue'
+import App from './App.vue'
+
+createApp(App).mount('#app')
diff --git a/playground/typescript-jsx-vitest-nightwatch/tests/e2e/example.ts b/playground/typescript-jsx-vitest-nightwatch/tests/e2e/example.ts
new file mode 100644
index 000000000..43be3fce1
--- /dev/null
+++ b/playground/typescript-jsx-vitest-nightwatch/tests/e2e/example.ts
@@ -0,0 +1,11 @@
+describe('My First Test', function () {
+ before((browser) => {
+ browser.init()
+ })
+
+ it('visits the app root url', function () {
+ browser.assert.textContains('.green', 'You did it!')
+ })
+
+ after((browser) => browser.end())
+})
diff --git a/playground/typescript-jsx-vitest-nightwatch/tsconfig.app.json b/playground/typescript-jsx-vitest-nightwatch/tsconfig.app.json
new file mode 100644
index 000000000..e14c754d3
--- /dev/null
+++ b/playground/typescript-jsx-vitest-nightwatch/tsconfig.app.json
@@ -0,0 +1,14 @@
+{
+ "extends": "@vue/tsconfig/tsconfig.dom.json",
+ "include": ["env.d.ts", "src/**/*", "src/**/*.vue"],
+ "exclude": ["src/**/__tests__/*"],
+ "compilerOptions": {
+ "composite": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
+
+ "baseUrl": ".",
+ "paths": {
+ "@/*": ["./src/*"]
+ }
+ }
+}
diff --git a/playground/typescript-jsx-vitest-nightwatch/tsconfig.json b/playground/typescript-jsx-vitest-nightwatch/tsconfig.json
new file mode 100644
index 000000000..a5352e667
--- /dev/null
+++ b/playground/typescript-jsx-vitest-nightwatch/tsconfig.json
@@ -0,0 +1,17 @@
+{
+ "files": [],
+ "references": [
+ {
+ "path": "./tsconfig.node.json"
+ },
+ {
+ "path": "./tsconfig.app.json"
+ },
+ {
+ "path": "./tsconfig.vitest.json"
+ },
+ {
+ "path": "./nightwatch/tsconfig.json"
+ }
+ ]
+}
diff --git a/playground/typescript-jsx-vitest-nightwatch/tsconfig.node.json b/playground/typescript-jsx-vitest-nightwatch/tsconfig.node.json
new file mode 100644
index 000000000..f09406303
--- /dev/null
+++ b/playground/typescript-jsx-vitest-nightwatch/tsconfig.node.json
@@ -0,0 +1,19 @@
+{
+ "extends": "@tsconfig/node20/tsconfig.json",
+ "include": [
+ "vite.config.*",
+ "vitest.config.*",
+ "cypress.config.*",
+ "nightwatch.conf.*",
+ "playwright.config.*"
+ ],
+ "compilerOptions": {
+ "composite": true,
+ "noEmit": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
+
+ "module": "ESNext",
+ "moduleResolution": "Bundler",
+ "types": ["node"]
+ }
+}
diff --git a/playground/typescript-jsx-vitest-nightwatch/tsconfig.vitest.json b/playground/typescript-jsx-vitest-nightwatch/tsconfig.vitest.json
new file mode 100644
index 000000000..571995d11
--- /dev/null
+++ b/playground/typescript-jsx-vitest-nightwatch/tsconfig.vitest.json
@@ -0,0 +1,11 @@
+{
+ "extends": "./tsconfig.app.json",
+ "exclude": [],
+ "compilerOptions": {
+ "composite": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.vitest.tsbuildinfo",
+
+ "lib": [],
+ "types": ["node", "jsdom"]
+ }
+}
diff --git a/playground/typescript-jsx-vitest-nightwatch/vite.config.ts b/playground/typescript-jsx-vitest-nightwatch/vite.config.ts
new file mode 100644
index 000000000..3a6988230
--- /dev/null
+++ b/playground/typescript-jsx-vitest-nightwatch/vite.config.ts
@@ -0,0 +1,20 @@
+import { fileURLToPath, URL } from 'node:url'
+
+import { defineConfig } from 'vite'
+import vue from '@vitejs/plugin-vue'
+import vueJsx from '@vitejs/plugin-vue-jsx'
+import nightwatchPlugin from 'vite-plugin-nightwatch'
+
+// https://vitejs.dev/config/
+export default defineConfig({
+ plugins: [
+ vue(),
+ vueJsx(),
+ nightwatchPlugin(),
+ ],
+ resolve: {
+ alias: {
+ '@': fileURLToPath(new URL('./src', import.meta.url))
+ }
+ }
+})
diff --git a/playground/typescript-jsx-vitest-nightwatch/vitest.config.ts b/playground/typescript-jsx-vitest-nightwatch/vitest.config.ts
new file mode 100644
index 000000000..10067d578
--- /dev/null
+++ b/playground/typescript-jsx-vitest-nightwatch/vitest.config.ts
@@ -0,0 +1,14 @@
+import { fileURLToPath } from 'node:url'
+import { mergeConfig, defineConfig, configDefaults } from 'vitest/config'
+import viteConfig from './vite.config'
+
+export default mergeConfig(
+ viteConfig,
+ defineConfig({
+ test: {
+ environment: 'jsdom',
+ exclude: [...configDefaults.exclude, 'e2e/*'],
+ root: fileURLToPath(new URL('./', import.meta.url))
+ }
+ })
+)
diff --git a/playground/typescript-jsx-vitest-playwright/.gitignore b/playground/typescript-jsx-vitest-playwright/.gitignore
new file mode 100644
index 000000000..aef72d03c
--- /dev/null
+++ b/playground/typescript-jsx-vitest-playwright/.gitignore
@@ -0,0 +1,33 @@
+# 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/
+
+# Editor directories and files
+.vscode/*
+!.vscode/extensions.json
+.idea
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?
+
+*.tsbuildinfo
+
+test-results/
+playwright-report/
diff --git a/playground/typescript-jsx-vitest-playwright/.vscode/extensions.json b/playground/typescript-jsx-vitest-playwright/.vscode/extensions.json
new file mode 100644
index 000000000..7b3f8bdae
--- /dev/null
+++ b/playground/typescript-jsx-vitest-playwright/.vscode/extensions.json
@@ -0,0 +1,3 @@
+{
+ "recommendations": ["ms-playwright.playwright"]
+}
diff --git a/playground/typescript-jsx-vitest-playwright/README.md b/playground/typescript-jsx-vitest-playwright/README.md
new file mode 100644
index 000000000..94b71b51e
--- /dev/null
+++ b/playground/typescript-jsx-vitest-playwright/README.md
@@ -0,0 +1,65 @@
+# typescript-jsx-vitest-playwright
+
+This template should help get you started developing with Vue 3 in Vite.
+
+## Recommended IDE Setup
+
+[VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur) + [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin).
+
+## Type Support for `.vue` Imports in TS
+
+TypeScript cannot handle type information for `.vue` imports by default, so we replace the `tsc` CLI with `vue-tsc` for type checking. In editors, we need [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin) to make the TypeScript language service aware of `.vue` types.
+
+If the standalone TypeScript plugin doesn't feel fast enough to you, Volar has also implemented a [Take Over Mode](https://github.com/johnsoncodehk/volar/discussions/471#discussioncomment-1361669) that is more performant. You can enable it by the following steps:
+
+1. Disable the built-in TypeScript Extension
+ 1) Run `Extensions: Show Built-in Extensions` from VSCode's command palette
+ 2) Find `TypeScript and JavaScript Language Features`, right click and select `Disable (Workspace)`
+2. Reload the VSCode window by running `Developer: Reload Window` from the command palette.
+
+## Customize configuration
+
+See [Vite Configuration Reference](https://vitejs.dev/config/).
+
+## Project Setup
+
+```sh
+pnpm install
+```
+
+### Compile and Hot-Reload for Development
+
+```sh
+pnpm dev
+```
+
+### Type-Check, Compile and Minify for Production
+
+```sh
+pnpm build
+```
+
+### Run Unit Tests with [Vitest](https://vitest.dev/)
+
+```sh
+pnpm test:unit
+```
+
+### Run End-to-End Tests with [Playwright](https://playwright.dev)
+
+```sh
+# Install browsers for the first run
+npx playwright install
+
+# When testing on CI, must build the project first
+pnpm build
+
+# Runs the end-to-end tests
+pnpm test:e2e
+# Runs the tests only on Chromium
+pnpm test:e2e --project=chromium
+# Runs the tests of a specific file
+pnpm test:e2e tests/example.spec.ts
+# Runs the tests in debug mode
+pnpm test:e2e --debug
+```
diff --git a/playground/typescript-jsx-vitest-playwright/e2e/tsconfig.json b/playground/typescript-jsx-vitest-playwright/e2e/tsconfig.json
new file mode 100644
index 000000000..be3bbfc0e
--- /dev/null
+++ b/playground/typescript-jsx-vitest-playwright/e2e/tsconfig.json
@@ -0,0 +1,4 @@
+{
+ "extends": "@tsconfig/node20/tsconfig.json",
+ "include": ["./**/*"]
+}
diff --git a/playground/typescript-jsx-vitest-playwright/e2e/vue.spec.ts b/playground/typescript-jsx-vitest-playwright/e2e/vue.spec.ts
new file mode 100644
index 000000000..3e5a3d02d
--- /dev/null
+++ b/playground/typescript-jsx-vitest-playwright/e2e/vue.spec.ts
@@ -0,0 +1,8 @@
+import { test, expect } from '@playwright/test';
+
+// See here how to get started:
+// https://playwright.dev/docs/intro
+test('visits the app root url', async ({ page }) => {
+ await page.goto('/');
+ await expect(page.locator('div.greetings > h1')).toHaveText('You did it!');
+})
diff --git a/playground/typescript-jsx-vitest-playwright/env.d.ts b/playground/typescript-jsx-vitest-playwright/env.d.ts
new file mode 100644
index 000000000..11f02fe2a
--- /dev/null
+++ b/playground/typescript-jsx-vitest-playwright/env.d.ts
@@ -0,0 +1 @@
+///
diff --git a/playground/typescript-jsx-vitest-playwright/index.html b/playground/typescript-jsx-vitest-playwright/index.html
new file mode 100644
index 000000000..a88854489
--- /dev/null
+++ b/playground/typescript-jsx-vitest-playwright/index.html
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+ Vite App
+
+
+
+
+
+
diff --git a/playground/typescript-jsx-vitest-playwright/package.json b/playground/typescript-jsx-vitest-playwright/package.json
new file mode 100644
index 000000000..22cba2a5a
--- /dev/null
+++ b/playground/typescript-jsx-vitest-playwright/package.json
@@ -0,0 +1,34 @@
+{
+ "name": "typescript-jsx-vitest-playwright",
+ "version": "0.0.0",
+ "private": true,
+ "type": "module",
+ "scripts": {
+ "dev": "vite",
+ "build": "run-p type-check \"build-only {@}\" --",
+ "preview": "vite preview",
+ "test:unit": "vitest",
+ "test:e2e": "playwright test",
+ "build-only": "vite build",
+ "type-check": "vue-tsc --build --force"
+ },
+ "dependencies": {
+ "vue": "^3.4.15"
+ },
+ "devDependencies": {
+ "@playwright/test": "^1.41.2",
+ "@tsconfig/node20": "^20.1.2",
+ "@types/jsdom": "^21.1.6",
+ "@types/node": "^20.11.16",
+ "@vitejs/plugin-vue": "^5.0.3",
+ "@vitejs/plugin-vue-jsx": "^3.1.0",
+ "@vue/test-utils": "^2.4.4",
+ "@vue/tsconfig": "^0.5.1",
+ "jsdom": "^24.0.0",
+ "npm-run-all2": "^6.1.2",
+ "typescript": "~5.3.0",
+ "vite": "^5.0.11",
+ "vitest": "^1.2.2",
+ "vue-tsc": "^1.8.27"
+ }
+}
diff --git a/playground/typescript-jsx-vitest-playwright/playwright.config.ts b/playground/typescript-jsx-vitest-playwright/playwright.config.ts
new file mode 100644
index 000000000..92075cc1b
--- /dev/null
+++ b/playground/typescript-jsx-vitest-playwright/playwright.config.ts
@@ -0,0 +1,110 @@
+import process from 'node:process'
+import { defineConfig, devices } from '@playwright/test'
+
+/**
+ * Read environment variables from file.
+ * https://github.com/motdotla/dotenv
+ */
+// require('dotenv').config();
+
+/**
+ * See https://playwright.dev/docs/test-configuration.
+ */
+export default defineConfig({
+ testDir: './e2e',
+ /* Maximum time one test can run for. */
+ timeout: 30 * 1000,
+ expect: {
+ /**
+ * Maximum time expect() should wait for the condition to be met.
+ * For example in `await expect(locator).toHaveText();`
+ */
+ timeout: 5000
+ },
+ /* Fail the build on CI if you accidentally left test.only in the source code. */
+ forbidOnly: !!process.env.CI,
+ /* Retry on CI only */
+ retries: process.env.CI ? 2 : 0,
+ /* Opt out of parallel tests on CI. */
+ workers: process.env.CI ? 1 : undefined,
+ /* Reporter to use. See https://playwright.dev/docs/test-reporters */
+ reporter: 'html',
+ /* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
+ use: {
+ /* Maximum time each action such as `click()` can take. Defaults to 0 (no limit). */
+ actionTimeout: 0,
+ /* Base URL to use in actions like `await page.goto('/')`. */
+ baseURL: 'http://localhost:5173',
+
+ /* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
+ trace: 'on-first-retry',
+
+ /* Only on CI systems run the tests headless */
+ headless: !!process.env.CI
+ },
+
+ /* Configure projects for major browsers */
+ projects: [
+ {
+ name: 'chromium',
+ use: {
+ ...devices['Desktop Chrome']
+ }
+ },
+ {
+ name: 'firefox',
+ use: {
+ ...devices['Desktop Firefox']
+ }
+ },
+ {
+ name: 'webkit',
+ use: {
+ ...devices['Desktop Safari']
+ }
+ }
+
+ /* Test against mobile viewports. */
+ // {
+ // name: 'Mobile Chrome',
+ // use: {
+ // ...devices['Pixel 5'],
+ // },
+ // },
+ // {
+ // name: 'Mobile Safari',
+ // use: {
+ // ...devices['iPhone 12'],
+ // },
+ // },
+
+ /* Test against branded browsers. */
+ // {
+ // name: 'Microsoft Edge',
+ // use: {
+ // channel: 'msedge',
+ // },
+ // },
+ // {
+ // name: 'Google Chrome',
+ // use: {
+ // channel: 'chrome',
+ // },
+ // },
+ ],
+
+ /* Folder for test artifacts such as screenshots, videos, traces, etc. */
+ // outputDir: 'test-results/',
+
+ /* Run your local dev server before starting the tests */
+ webServer: {
+ /**
+ * Use the dev server by default for faster feedback loop.
+ * Use the preview server on CI for more realistic testing.
+ * Playwright will re-use the local server if there is already a dev-server running.
+ */
+ command: process.env.CI ? 'vite preview --port 5173' : 'vite dev',
+ port: 5173,
+ reuseExistingServer: !process.env.CI
+ }
+})
diff --git a/playground/typescript-jsx-vitest-playwright/public/favicon.ico b/playground/typescript-jsx-vitest-playwright/public/favicon.ico
new file mode 100644
index 000000000..df36fcfb7
Binary files /dev/null and b/playground/typescript-jsx-vitest-playwright/public/favicon.ico differ
diff --git a/playground/typescript-jsx-vitest-playwright/src/App.vue b/playground/typescript-jsx-vitest-playwright/src/App.vue
new file mode 100644
index 000000000..69f32f91f
--- /dev/null
+++ b/playground/typescript-jsx-vitest-playwright/src/App.vue
@@ -0,0 +1,10 @@
+
+ app
+
+
+
+
+
diff --git a/playground/typescript-jsx-vitest-playwright/src/assets/logo.svg b/playground/typescript-jsx-vitest-playwright/src/assets/logo.svg
new file mode 100644
index 000000000..756566035
--- /dev/null
+++ b/playground/typescript-jsx-vitest-playwright/src/assets/logo.svg
@@ -0,0 +1 @@
+
diff --git a/playground/typescript-jsx-vitest-playwright/src/assets/main.css b/playground/typescript-jsx-vitest-playwright/src/assets/main.css
new file mode 100644
index 000000000..5aadc6ceb
--- /dev/null
+++ b/playground/typescript-jsx-vitest-playwright/src/assets/main.css
@@ -0,0 +1,6 @@
+html, body, #app {
+ width: 100%;
+ height: 100%;
+ padding: 0;
+ margin: 0;
+}
diff --git a/playground/typescript-jsx-vitest-playwright/src/components/__tests__/HelloWorld.spec.ts b/playground/typescript-jsx-vitest-playwright/src/components/__tests__/HelloWorld.spec.ts
new file mode 100644
index 000000000..253320200
--- /dev/null
+++ b/playground/typescript-jsx-vitest-playwright/src/components/__tests__/HelloWorld.spec.ts
@@ -0,0 +1,11 @@
+import { describe, it, expect } from 'vitest'
+
+import { mount } from '@vue/test-utils'
+import HelloWorld from '../HelloWorld.vue'
+
+describe('HelloWorld', () => {
+ it('renders properly', () => {
+ const wrapper = mount(HelloWorld, { props: { msg: 'Hello Vitest' } })
+ expect(wrapper.text()).toContain('Hello Vitest')
+ })
+})
diff --git a/playground/typescript-jsx-vitest-playwright/src/main.ts b/playground/typescript-jsx-vitest-playwright/src/main.ts
new file mode 100644
index 000000000..0ac3a5ff0
--- /dev/null
+++ b/playground/typescript-jsx-vitest-playwright/src/main.ts
@@ -0,0 +1,6 @@
+import './assets/main.css'
+
+import { createApp } from 'vue'
+import App from './App.vue'
+
+createApp(App).mount('#app')
diff --git a/playground/typescript-jsx-vitest-playwright/tsconfig.app.json b/playground/typescript-jsx-vitest-playwright/tsconfig.app.json
new file mode 100644
index 000000000..e14c754d3
--- /dev/null
+++ b/playground/typescript-jsx-vitest-playwright/tsconfig.app.json
@@ -0,0 +1,14 @@
+{
+ "extends": "@vue/tsconfig/tsconfig.dom.json",
+ "include": ["env.d.ts", "src/**/*", "src/**/*.vue"],
+ "exclude": ["src/**/__tests__/*"],
+ "compilerOptions": {
+ "composite": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
+
+ "baseUrl": ".",
+ "paths": {
+ "@/*": ["./src/*"]
+ }
+ }
+}
diff --git a/playground/typescript-jsx-vitest-playwright/tsconfig.json b/playground/typescript-jsx-vitest-playwright/tsconfig.json
new file mode 100644
index 000000000..100cf6a8f
--- /dev/null
+++ b/playground/typescript-jsx-vitest-playwright/tsconfig.json
@@ -0,0 +1,14 @@
+{
+ "files": [],
+ "references": [
+ {
+ "path": "./tsconfig.node.json"
+ },
+ {
+ "path": "./tsconfig.app.json"
+ },
+ {
+ "path": "./tsconfig.vitest.json"
+ }
+ ]
+}
diff --git a/playground/typescript-jsx-vitest-playwright/tsconfig.node.json b/playground/typescript-jsx-vitest-playwright/tsconfig.node.json
new file mode 100644
index 000000000..f09406303
--- /dev/null
+++ b/playground/typescript-jsx-vitest-playwright/tsconfig.node.json
@@ -0,0 +1,19 @@
+{
+ "extends": "@tsconfig/node20/tsconfig.json",
+ "include": [
+ "vite.config.*",
+ "vitest.config.*",
+ "cypress.config.*",
+ "nightwatch.conf.*",
+ "playwright.config.*"
+ ],
+ "compilerOptions": {
+ "composite": true,
+ "noEmit": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
+
+ "module": "ESNext",
+ "moduleResolution": "Bundler",
+ "types": ["node"]
+ }
+}
diff --git a/playground/typescript-jsx-vitest-playwright/tsconfig.vitest.json b/playground/typescript-jsx-vitest-playwright/tsconfig.vitest.json
new file mode 100644
index 000000000..571995d11
--- /dev/null
+++ b/playground/typescript-jsx-vitest-playwright/tsconfig.vitest.json
@@ -0,0 +1,11 @@
+{
+ "extends": "./tsconfig.app.json",
+ "exclude": [],
+ "compilerOptions": {
+ "composite": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.vitest.tsbuildinfo",
+
+ "lib": [],
+ "types": ["node", "jsdom"]
+ }
+}
diff --git a/playground/typescript-jsx-vitest-playwright/vite.config.ts b/playground/typescript-jsx-vitest-playwright/vite.config.ts
new file mode 100644
index 000000000..36c618756
--- /dev/null
+++ b/playground/typescript-jsx-vitest-playwright/vite.config.ts
@@ -0,0 +1,18 @@
+import { fileURLToPath, URL } from 'node:url'
+
+import { defineConfig } from 'vite'
+import vue from '@vitejs/plugin-vue'
+import vueJsx from '@vitejs/plugin-vue-jsx'
+
+// https://vitejs.dev/config/
+export default defineConfig({
+ plugins: [
+ vue(),
+ vueJsx(),
+ ],
+ resolve: {
+ alias: {
+ '@': fileURLToPath(new URL('./src', import.meta.url))
+ }
+ }
+})
diff --git a/playground/typescript-jsx-vitest-playwright/vitest.config.ts b/playground/typescript-jsx-vitest-playwright/vitest.config.ts
new file mode 100644
index 000000000..10067d578
--- /dev/null
+++ b/playground/typescript-jsx-vitest-playwright/vitest.config.ts
@@ -0,0 +1,14 @@
+import { fileURLToPath } from 'node:url'
+import { mergeConfig, defineConfig, configDefaults } from 'vitest/config'
+import viteConfig from './vite.config'
+
+export default mergeConfig(
+ viteConfig,
+ defineConfig({
+ test: {
+ environment: 'jsdom',
+ exclude: [...configDefaults.exclude, 'e2e/*'],
+ root: fileURLToPath(new URL('./', import.meta.url))
+ }
+ })
+)
diff --git a/playground/typescript-jsx-vitest/.gitignore b/playground/typescript-jsx-vitest/.gitignore
new file mode 100644
index 000000000..8ee54e8d3
--- /dev/null
+++ b/playground/typescript-jsx-vitest/.gitignore
@@ -0,0 +1,30 @@
+# 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/
+
+# Editor directories and files
+.vscode/*
+!.vscode/extensions.json
+.idea
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?
+
+*.tsbuildinfo
diff --git a/playground/typescript-jsx-vitest/README.md b/playground/typescript-jsx-vitest/README.md
new file mode 100644
index 000000000..9c8e9f019
--- /dev/null
+++ b/playground/typescript-jsx-vitest/README.md
@@ -0,0 +1,46 @@
+# typescript-jsx-vitest
+
+This template should help get you started developing with Vue 3 in Vite.
+
+## Recommended IDE Setup
+
+[VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur) + [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin).
+
+## Type Support for `.vue` Imports in TS
+
+TypeScript cannot handle type information for `.vue` imports by default, so we replace the `tsc` CLI with `vue-tsc` for type checking. In editors, we need [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin) to make the TypeScript language service aware of `.vue` types.
+
+If the standalone TypeScript plugin doesn't feel fast enough to you, Volar has also implemented a [Take Over Mode](https://github.com/johnsoncodehk/volar/discussions/471#discussioncomment-1361669) that is more performant. You can enable it by the following steps:
+
+1. Disable the built-in TypeScript Extension
+ 1) Run `Extensions: Show Built-in Extensions` from VSCode's command palette
+ 2) Find `TypeScript and JavaScript Language Features`, right click and select `Disable (Workspace)`
+2. Reload the VSCode window by running `Developer: Reload Window` from the command palette.
+
+## Customize configuration
+
+See [Vite Configuration Reference](https://vitejs.dev/config/).
+
+## Project Setup
+
+```sh
+pnpm install
+```
+
+### Compile and Hot-Reload for Development
+
+```sh
+pnpm dev
+```
+
+### Type-Check, Compile and Minify for Production
+
+```sh
+pnpm build
+```
+
+### Run Unit Tests with [Vitest](https://vitest.dev/)
+
+```sh
+pnpm test:unit
+```
diff --git a/playground/typescript-jsx-vitest/env.d.ts b/playground/typescript-jsx-vitest/env.d.ts
new file mode 100644
index 000000000..11f02fe2a
--- /dev/null
+++ b/playground/typescript-jsx-vitest/env.d.ts
@@ -0,0 +1 @@
+///
diff --git a/playground/typescript-jsx-vitest/index.html b/playground/typescript-jsx-vitest/index.html
new file mode 100644
index 000000000..a88854489
--- /dev/null
+++ b/playground/typescript-jsx-vitest/index.html
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+ Vite App
+
+
+
+
+
+
diff --git a/playground/typescript-jsx-vitest/package.json b/playground/typescript-jsx-vitest/package.json
new file mode 100644
index 000000000..88cc6aa9c
--- /dev/null
+++ b/playground/typescript-jsx-vitest/package.json
@@ -0,0 +1,32 @@
+{
+ "name": "typescript-jsx-vitest",
+ "version": "0.0.0",
+ "private": true,
+ "type": "module",
+ "scripts": {
+ "dev": "vite",
+ "build": "run-p type-check \"build-only {@}\" --",
+ "preview": "vite preview",
+ "test:unit": "vitest",
+ "build-only": "vite build",
+ "type-check": "vue-tsc --build --force"
+ },
+ "dependencies": {
+ "vue": "^3.4.15"
+ },
+ "devDependencies": {
+ "@tsconfig/node20": "^20.1.2",
+ "@types/jsdom": "^21.1.6",
+ "@types/node": "^20.11.16",
+ "@vitejs/plugin-vue": "^5.0.3",
+ "@vitejs/plugin-vue-jsx": "^3.1.0",
+ "@vue/test-utils": "^2.4.4",
+ "@vue/tsconfig": "^0.5.1",
+ "jsdom": "^24.0.0",
+ "npm-run-all2": "^6.1.2",
+ "typescript": "~5.3.0",
+ "vite": "^5.0.11",
+ "vitest": "^1.2.2",
+ "vue-tsc": "^1.8.27"
+ }
+}
diff --git a/playground/typescript-jsx-vitest/public/favicon.ico b/playground/typescript-jsx-vitest/public/favicon.ico
new file mode 100644
index 000000000..df36fcfb7
Binary files /dev/null and b/playground/typescript-jsx-vitest/public/favicon.ico differ
diff --git a/playground/typescript-jsx-vitest/src/App.vue b/playground/typescript-jsx-vitest/src/App.vue
new file mode 100644
index 000000000..69f32f91f
--- /dev/null
+++ b/playground/typescript-jsx-vitest/src/App.vue
@@ -0,0 +1,10 @@
+
+ app
+
+
+
+
+
diff --git a/playground/typescript-jsx-vitest/src/assets/logo.svg b/playground/typescript-jsx-vitest/src/assets/logo.svg
new file mode 100644
index 000000000..756566035
--- /dev/null
+++ b/playground/typescript-jsx-vitest/src/assets/logo.svg
@@ -0,0 +1 @@
+
diff --git a/playground/typescript-jsx-vitest/src/assets/main.css b/playground/typescript-jsx-vitest/src/assets/main.css
new file mode 100644
index 000000000..5aadc6ceb
--- /dev/null
+++ b/playground/typescript-jsx-vitest/src/assets/main.css
@@ -0,0 +1,6 @@
+html, body, #app {
+ width: 100%;
+ height: 100%;
+ padding: 0;
+ margin: 0;
+}
diff --git a/playground/typescript-jsx-vitest/src/components/__tests__/HelloWorld.spec.ts b/playground/typescript-jsx-vitest/src/components/__tests__/HelloWorld.spec.ts
new file mode 100644
index 000000000..253320200
--- /dev/null
+++ b/playground/typescript-jsx-vitest/src/components/__tests__/HelloWorld.spec.ts
@@ -0,0 +1,11 @@
+import { describe, it, expect } from 'vitest'
+
+import { mount } from '@vue/test-utils'
+import HelloWorld from '../HelloWorld.vue'
+
+describe('HelloWorld', () => {
+ it('renders properly', () => {
+ const wrapper = mount(HelloWorld, { props: { msg: 'Hello Vitest' } })
+ expect(wrapper.text()).toContain('Hello Vitest')
+ })
+})
diff --git a/playground/typescript-jsx-vitest/src/main.ts b/playground/typescript-jsx-vitest/src/main.ts
new file mode 100644
index 000000000..0ac3a5ff0
--- /dev/null
+++ b/playground/typescript-jsx-vitest/src/main.ts
@@ -0,0 +1,6 @@
+import './assets/main.css'
+
+import { createApp } from 'vue'
+import App from './App.vue'
+
+createApp(App).mount('#app')
diff --git a/playground/typescript-jsx-vitest/tsconfig.app.json b/playground/typescript-jsx-vitest/tsconfig.app.json
new file mode 100644
index 000000000..e14c754d3
--- /dev/null
+++ b/playground/typescript-jsx-vitest/tsconfig.app.json
@@ -0,0 +1,14 @@
+{
+ "extends": "@vue/tsconfig/tsconfig.dom.json",
+ "include": ["env.d.ts", "src/**/*", "src/**/*.vue"],
+ "exclude": ["src/**/__tests__/*"],
+ "compilerOptions": {
+ "composite": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
+
+ "baseUrl": ".",
+ "paths": {
+ "@/*": ["./src/*"]
+ }
+ }
+}
diff --git a/playground/typescript-jsx-vitest/tsconfig.json b/playground/typescript-jsx-vitest/tsconfig.json
new file mode 100644
index 000000000..100cf6a8f
--- /dev/null
+++ b/playground/typescript-jsx-vitest/tsconfig.json
@@ -0,0 +1,14 @@
+{
+ "files": [],
+ "references": [
+ {
+ "path": "./tsconfig.node.json"
+ },
+ {
+ "path": "./tsconfig.app.json"
+ },
+ {
+ "path": "./tsconfig.vitest.json"
+ }
+ ]
+}
diff --git a/playground/typescript-jsx-vitest/tsconfig.node.json b/playground/typescript-jsx-vitest/tsconfig.node.json
new file mode 100644
index 000000000..f09406303
--- /dev/null
+++ b/playground/typescript-jsx-vitest/tsconfig.node.json
@@ -0,0 +1,19 @@
+{
+ "extends": "@tsconfig/node20/tsconfig.json",
+ "include": [
+ "vite.config.*",
+ "vitest.config.*",
+ "cypress.config.*",
+ "nightwatch.conf.*",
+ "playwright.config.*"
+ ],
+ "compilerOptions": {
+ "composite": true,
+ "noEmit": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
+
+ "module": "ESNext",
+ "moduleResolution": "Bundler",
+ "types": ["node"]
+ }
+}
diff --git a/playground/typescript-jsx-vitest/tsconfig.vitest.json b/playground/typescript-jsx-vitest/tsconfig.vitest.json
new file mode 100644
index 000000000..571995d11
--- /dev/null
+++ b/playground/typescript-jsx-vitest/tsconfig.vitest.json
@@ -0,0 +1,11 @@
+{
+ "extends": "./tsconfig.app.json",
+ "exclude": [],
+ "compilerOptions": {
+ "composite": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.vitest.tsbuildinfo",
+
+ "lib": [],
+ "types": ["node", "jsdom"]
+ }
+}
diff --git a/playground/typescript-jsx-vitest/vite.config.ts b/playground/typescript-jsx-vitest/vite.config.ts
new file mode 100644
index 000000000..36c618756
--- /dev/null
+++ b/playground/typescript-jsx-vitest/vite.config.ts
@@ -0,0 +1,18 @@
+import { fileURLToPath, URL } from 'node:url'
+
+import { defineConfig } from 'vite'
+import vue from '@vitejs/plugin-vue'
+import vueJsx from '@vitejs/plugin-vue-jsx'
+
+// https://vitejs.dev/config/
+export default defineConfig({
+ plugins: [
+ vue(),
+ vueJsx(),
+ ],
+ resolve: {
+ alias: {
+ '@': fileURLToPath(new URL('./src', import.meta.url))
+ }
+ }
+})
diff --git a/playground/typescript-jsx-vitest/vitest.config.ts b/playground/typescript-jsx-vitest/vitest.config.ts
new file mode 100644
index 000000000..10067d578
--- /dev/null
+++ b/playground/typescript-jsx-vitest/vitest.config.ts
@@ -0,0 +1,14 @@
+import { fileURLToPath } from 'node:url'
+import { mergeConfig, defineConfig, configDefaults } from 'vitest/config'
+import viteConfig from './vite.config'
+
+export default mergeConfig(
+ viteConfig,
+ defineConfig({
+ test: {
+ environment: 'jsdom',
+ exclude: [...configDefaults.exclude, 'e2e/*'],
+ root: fileURLToPath(new URL('./', import.meta.url))
+ }
+ })
+)
diff --git a/playground/typescript-jsx-with-tests/.gitignore b/playground/typescript-jsx-with-tests/.gitignore
new file mode 100644
index 000000000..8ee54e8d3
--- /dev/null
+++ b/playground/typescript-jsx-with-tests/.gitignore
@@ -0,0 +1,30 @@
+# 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/
+
+# Editor directories and files
+.vscode/*
+!.vscode/extensions.json
+.idea
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?
+
+*.tsbuildinfo
diff --git a/playground/typescript-jsx-with-tests/README.md b/playground/typescript-jsx-with-tests/README.md
new file mode 100644
index 000000000..efb96d69e
--- /dev/null
+++ b/playground/typescript-jsx-with-tests/README.md
@@ -0,0 +1,62 @@
+# typescript-jsx-with-tests
+
+This template should help get you started developing with Vue 3 in Vite.
+
+## Recommended IDE Setup
+
+[VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur) + [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin).
+
+## Type Support for `.vue` Imports in TS
+
+TypeScript cannot handle type information for `.vue` imports by default, so we replace the `tsc` CLI with `vue-tsc` for type checking. In editors, we need [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin) to make the TypeScript language service aware of `.vue` types.
+
+If the standalone TypeScript plugin doesn't feel fast enough to you, Volar has also implemented a [Take Over Mode](https://github.com/johnsoncodehk/volar/discussions/471#discussioncomment-1361669) that is more performant. You can enable it by the following steps:
+
+1. Disable the built-in TypeScript Extension
+ 1) Run `Extensions: Show Built-in Extensions` from VSCode's command palette
+ 2) Find `TypeScript and JavaScript Language Features`, right click and select `Disable (Workspace)`
+2. Reload the VSCode window by running `Developer: Reload Window` from the command palette.
+
+## Customize configuration
+
+See [Vite Configuration Reference](https://vitejs.dev/config/).
+
+## Project Setup
+
+```sh
+pnpm install
+```
+
+### Compile and Hot-Reload for Development
+
+```sh
+pnpm dev
+```
+
+### Type-Check, Compile and Minify for Production
+
+```sh
+pnpm build
+```
+
+### Run Unit Tests with [Vitest](https://vitest.dev/)
+
+```sh
+pnpm test:unit
+```
+
+### Run End-to-End Tests with [Cypress](https://www.cypress.io/)
+
+```sh
+pnpm test:e2e:dev
+```
+
+This runs the end-to-end tests against the Vite development server.
+It is much faster than the production build.
+
+But it's still recommended to test the production build with `test:e2e` before deploying (e.g. in CI environments):
+
+```sh
+pnpm build
+pnpm test:e2e
+```
diff --git a/playground/typescript-jsx-with-tests/cypress.config.ts b/playground/typescript-jsx-with-tests/cypress.config.ts
new file mode 100644
index 000000000..0f66080fd
--- /dev/null
+++ b/playground/typescript-jsx-with-tests/cypress.config.ts
@@ -0,0 +1,8 @@
+import { defineConfig } from 'cypress'
+
+export default defineConfig({
+ e2e: {
+ specPattern: 'cypress/e2e/**/*.{cy,spec}.{js,jsx,ts,tsx}',
+ baseUrl: 'http://localhost:4173'
+ }
+})
diff --git a/playground/typescript-jsx-with-tests/cypress/e2e/example.cy.ts b/playground/typescript-jsx-with-tests/cypress/e2e/example.cy.ts
new file mode 100644
index 000000000..7554c35d8
--- /dev/null
+++ b/playground/typescript-jsx-with-tests/cypress/e2e/example.cy.ts
@@ -0,0 +1,8 @@
+// https://on.cypress.io/api
+
+describe('My First Test', () => {
+ it('visits the app root url', () => {
+ cy.visit('/')
+ cy.contains('h1', 'You did it!')
+ })
+})
diff --git a/playground/typescript-jsx-with-tests/cypress/e2e/tsconfig.json b/playground/typescript-jsx-with-tests/cypress/e2e/tsconfig.json
new file mode 100644
index 000000000..37748feb7
--- /dev/null
+++ b/playground/typescript-jsx-with-tests/cypress/e2e/tsconfig.json
@@ -0,0 +1,10 @@
+{
+ "extends": "@vue/tsconfig/tsconfig.dom.json",
+ "include": ["./**/*", "../support/**/*"],
+ "compilerOptions": {
+ "isolatedModules": false,
+ "target": "es5",
+ "lib": ["es5", "dom"],
+ "types": ["cypress"]
+ }
+}
diff --git a/playground/typescript-jsx-with-tests/cypress/fixtures/example.json b/playground/typescript-jsx-with-tests/cypress/fixtures/example.json
new file mode 100644
index 000000000..02e425437
--- /dev/null
+++ b/playground/typescript-jsx-with-tests/cypress/fixtures/example.json
@@ -0,0 +1,5 @@
+{
+ "name": "Using fixtures to represent data",
+ "email": "hello@cypress.io",
+ "body": "Fixtures are a great way to mock data for responses to routes"
+}
diff --git a/playground/typescript-jsx-with-tests/cypress/support/commands.ts b/playground/typescript-jsx-with-tests/cypress/support/commands.ts
new file mode 100644
index 000000000..9b7bb8e25
--- /dev/null
+++ b/playground/typescript-jsx-with-tests/cypress/support/commands.ts
@@ -0,0 +1,39 @@
+///
+// ***********************************************
+// This example commands.ts shows you how to
+// create various custom commands and overwrite
+// existing commands.
+//
+// For more comprehensive examples of custom
+// commands please read more here:
+// https://on.cypress.io/custom-commands
+// ***********************************************
+//
+//
+// -- This is a parent command --
+// Cypress.Commands.add('login', (email, password) => { ... })
+//
+//
+// -- This is a child command --
+// Cypress.Commands.add('drag', { prevSubject: 'element'}, (subject, options) => { ... })
+//
+//
+// -- This is a dual command --
+// Cypress.Commands.add('dismiss', { prevSubject: 'optional'}, (subject, options) => { ... })
+//
+//
+// -- This will overwrite an existing command --
+// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... })
+//
+// declare global {
+// namespace Cypress {
+// interface Chainable {
+// login(email: string, password: string): Chainable
+// drag(subject: string, options?: Partial): Chainable
+// dismiss(subject: string, options?: Partial): Chainable
+// visit(originalFn: CommandOriginalFn, url: string, options: Partial): Chainable
+// }
+// }
+// }
+
+export {}
diff --git a/playground/typescript-jsx-with-tests/cypress/support/e2e.ts b/playground/typescript-jsx-with-tests/cypress/support/e2e.ts
new file mode 100644
index 000000000..d68db96df
--- /dev/null
+++ b/playground/typescript-jsx-with-tests/cypress/support/e2e.ts
@@ -0,0 +1,20 @@
+// ***********************************************************
+// This example support/index.js is processed and
+// loaded automatically before your test files.
+//
+// This is a great place to put global configuration and
+// behavior that modifies Cypress.
+//
+// You can change the location of this file or turn off
+// automatically serving support files with the
+// 'supportFile' configuration option.
+//
+// You can read more here:
+// https://on.cypress.io/configuration
+// ***********************************************************
+
+// Import commands.js using ES2015 syntax:
+import './commands'
+
+// Alternatively you can use CommonJS syntax:
+// require('./commands')
diff --git a/playground/typescript-jsx-with-tests/env.d.ts b/playground/typescript-jsx-with-tests/env.d.ts
new file mode 100644
index 000000000..11f02fe2a
--- /dev/null
+++ b/playground/typescript-jsx-with-tests/env.d.ts
@@ -0,0 +1 @@
+///
diff --git a/playground/typescript-jsx-with-tests/index.html b/playground/typescript-jsx-with-tests/index.html
new file mode 100644
index 000000000..a88854489
--- /dev/null
+++ b/playground/typescript-jsx-with-tests/index.html
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+ Vite App
+
+
+
+
+
+
diff --git a/playground/typescript-jsx-with-tests/package.json b/playground/typescript-jsx-with-tests/package.json
new file mode 100644
index 000000000..10095b811
--- /dev/null
+++ b/playground/typescript-jsx-with-tests/package.json
@@ -0,0 +1,36 @@
+{
+ "name": "typescript-jsx-with-tests",
+ "version": "0.0.0",
+ "private": true,
+ "type": "module",
+ "scripts": {
+ "dev": "vite",
+ "build": "run-p type-check \"build-only {@}\" --",
+ "preview": "vite preview",
+ "test:unit": "vitest",
+ "test:e2e": "start-server-and-test preview http://localhost:4173 'cypress run --e2e'",
+ "test:e2e:dev": "start-server-and-test 'vite dev --port 4173' http://localhost:4173 'cypress open --e2e'",
+ "build-only": "vite build",
+ "type-check": "vue-tsc --build --force"
+ },
+ "dependencies": {
+ "vue": "^3.4.15"
+ },
+ "devDependencies": {
+ "@tsconfig/node20": "^20.1.2",
+ "@types/jsdom": "^21.1.6",
+ "@types/node": "^20.11.16",
+ "@vitejs/plugin-vue": "^5.0.3",
+ "@vitejs/plugin-vue-jsx": "^3.1.0",
+ "@vue/test-utils": "^2.4.4",
+ "@vue/tsconfig": "^0.5.1",
+ "cypress": "^13.6.4",
+ "jsdom": "^24.0.0",
+ "npm-run-all2": "^6.1.2",
+ "start-server-and-test": "^2.0.3",
+ "typescript": "~5.3.0",
+ "vite": "^5.0.11",
+ "vitest": "^1.2.2",
+ "vue-tsc": "^1.8.27"
+ }
+}
diff --git a/playground/typescript-jsx-with-tests/public/favicon.ico b/playground/typescript-jsx-with-tests/public/favicon.ico
new file mode 100644
index 000000000..df36fcfb7
Binary files /dev/null and b/playground/typescript-jsx-with-tests/public/favicon.ico differ
diff --git a/playground/typescript-jsx-with-tests/src/App.vue b/playground/typescript-jsx-with-tests/src/App.vue
new file mode 100644
index 000000000..69f32f91f
--- /dev/null
+++ b/playground/typescript-jsx-with-tests/src/App.vue
@@ -0,0 +1,10 @@
+
+ app
+
+
+
+
+
diff --git a/playground/typescript-jsx-with-tests/src/assets/logo.svg b/playground/typescript-jsx-with-tests/src/assets/logo.svg
new file mode 100644
index 000000000..756566035
--- /dev/null
+++ b/playground/typescript-jsx-with-tests/src/assets/logo.svg
@@ -0,0 +1 @@
+
diff --git a/playground/typescript-jsx-with-tests/src/assets/main.css b/playground/typescript-jsx-with-tests/src/assets/main.css
new file mode 100644
index 000000000..5aadc6ceb
--- /dev/null
+++ b/playground/typescript-jsx-with-tests/src/assets/main.css
@@ -0,0 +1,6 @@
+html, body, #app {
+ width: 100%;
+ height: 100%;
+ padding: 0;
+ margin: 0;
+}
diff --git a/playground/typescript-jsx-with-tests/src/components/__tests__/HelloWorld.spec.ts b/playground/typescript-jsx-with-tests/src/components/__tests__/HelloWorld.spec.ts
new file mode 100644
index 000000000..253320200
--- /dev/null
+++ b/playground/typescript-jsx-with-tests/src/components/__tests__/HelloWorld.spec.ts
@@ -0,0 +1,11 @@
+import { describe, it, expect } from 'vitest'
+
+import { mount } from '@vue/test-utils'
+import HelloWorld from '../HelloWorld.vue'
+
+describe('HelloWorld', () => {
+ it('renders properly', () => {
+ const wrapper = mount(HelloWorld, { props: { msg: 'Hello Vitest' } })
+ expect(wrapper.text()).toContain('Hello Vitest')
+ })
+})
diff --git a/playground/typescript-jsx-with-tests/src/main.ts b/playground/typescript-jsx-with-tests/src/main.ts
new file mode 100644
index 000000000..0ac3a5ff0
--- /dev/null
+++ b/playground/typescript-jsx-with-tests/src/main.ts
@@ -0,0 +1,6 @@
+import './assets/main.css'
+
+import { createApp } from 'vue'
+import App from './App.vue'
+
+createApp(App).mount('#app')
diff --git a/playground/typescript-jsx-with-tests/tsconfig.app.json b/playground/typescript-jsx-with-tests/tsconfig.app.json
new file mode 100644
index 000000000..e14c754d3
--- /dev/null
+++ b/playground/typescript-jsx-with-tests/tsconfig.app.json
@@ -0,0 +1,14 @@
+{
+ "extends": "@vue/tsconfig/tsconfig.dom.json",
+ "include": ["env.d.ts", "src/**/*", "src/**/*.vue"],
+ "exclude": ["src/**/__tests__/*"],
+ "compilerOptions": {
+ "composite": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
+
+ "baseUrl": ".",
+ "paths": {
+ "@/*": ["./src/*"]
+ }
+ }
+}
diff --git a/playground/typescript-jsx-with-tests/tsconfig.json b/playground/typescript-jsx-with-tests/tsconfig.json
new file mode 100644
index 000000000..5304731b8
--- /dev/null
+++ b/playground/typescript-jsx-with-tests/tsconfig.json
@@ -0,0 +1,17 @@
+{
+ "files": [],
+ "references": [
+ {
+ "path": "./tsconfig.node.json"
+ },
+ {
+ "path": "./tsconfig.app.json"
+ },
+ {
+ "path": "./tsconfig.vitest.json"
+ }
+ ],
+ "compilerOptions": {
+ "module": "NodeNext"
+ }
+}
diff --git a/playground/typescript-jsx-with-tests/tsconfig.node.json b/playground/typescript-jsx-with-tests/tsconfig.node.json
new file mode 100644
index 000000000..f09406303
--- /dev/null
+++ b/playground/typescript-jsx-with-tests/tsconfig.node.json
@@ -0,0 +1,19 @@
+{
+ "extends": "@tsconfig/node20/tsconfig.json",
+ "include": [
+ "vite.config.*",
+ "vitest.config.*",
+ "cypress.config.*",
+ "nightwatch.conf.*",
+ "playwright.config.*"
+ ],
+ "compilerOptions": {
+ "composite": true,
+ "noEmit": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
+
+ "module": "ESNext",
+ "moduleResolution": "Bundler",
+ "types": ["node"]
+ }
+}
diff --git a/playground/typescript-jsx-with-tests/tsconfig.vitest.json b/playground/typescript-jsx-with-tests/tsconfig.vitest.json
new file mode 100644
index 000000000..571995d11
--- /dev/null
+++ b/playground/typescript-jsx-with-tests/tsconfig.vitest.json
@@ -0,0 +1,11 @@
+{
+ "extends": "./tsconfig.app.json",
+ "exclude": [],
+ "compilerOptions": {
+ "composite": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.vitest.tsbuildinfo",
+
+ "lib": [],
+ "types": ["node", "jsdom"]
+ }
+}
diff --git a/playground/typescript-jsx-with-tests/vite.config.ts b/playground/typescript-jsx-with-tests/vite.config.ts
new file mode 100644
index 000000000..36c618756
--- /dev/null
+++ b/playground/typescript-jsx-with-tests/vite.config.ts
@@ -0,0 +1,18 @@
+import { fileURLToPath, URL } from 'node:url'
+
+import { defineConfig } from 'vite'
+import vue from '@vitejs/plugin-vue'
+import vueJsx from '@vitejs/plugin-vue-jsx'
+
+// https://vitejs.dev/config/
+export default defineConfig({
+ plugins: [
+ vue(),
+ vueJsx(),
+ ],
+ resolve: {
+ alias: {
+ '@': fileURLToPath(new URL('./src', import.meta.url))
+ }
+ }
+})
diff --git a/playground/typescript-jsx-with-tests/vitest.config.ts b/playground/typescript-jsx-with-tests/vitest.config.ts
new file mode 100644
index 000000000..10067d578
--- /dev/null
+++ b/playground/typescript-jsx-with-tests/vitest.config.ts
@@ -0,0 +1,14 @@
+import { fileURLToPath } from 'node:url'
+import { mergeConfig, defineConfig, configDefaults } from 'vitest/config'
+import viteConfig from './vite.config'
+
+export default mergeConfig(
+ viteConfig,
+ defineConfig({
+ test: {
+ environment: 'jsdom',
+ exclude: [...configDefaults.exclude, 'e2e/*'],
+ root: fileURLToPath(new URL('./', import.meta.url))
+ }
+ })
+)
diff --git a/playground/typescript-jsx/.gitignore b/playground/typescript-jsx/.gitignore
new file mode 100644
index 000000000..8ee54e8d3
--- /dev/null
+++ b/playground/typescript-jsx/.gitignore
@@ -0,0 +1,30 @@
+# 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/
+
+# Editor directories and files
+.vscode/*
+!.vscode/extensions.json
+.idea
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?
+
+*.tsbuildinfo
diff --git a/playground/typescript-jsx/README.md b/playground/typescript-jsx/README.md
new file mode 100644
index 000000000..09436e2ea
--- /dev/null
+++ b/playground/typescript-jsx/README.md
@@ -0,0 +1,40 @@
+# typescript-jsx
+
+This template should help get you started developing with Vue 3 in Vite.
+
+## Recommended IDE Setup
+
+[VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur) + [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin).
+
+## Type Support for `.vue` Imports in TS
+
+TypeScript cannot handle type information for `.vue` imports by default, so we replace the `tsc` CLI with `vue-tsc` for type checking. In editors, we need [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin) to make the TypeScript language service aware of `.vue` types.
+
+If the standalone TypeScript plugin doesn't feel fast enough to you, Volar has also implemented a [Take Over Mode](https://github.com/johnsoncodehk/volar/discussions/471#discussioncomment-1361669) that is more performant. You can enable it by the following steps:
+
+1. Disable the built-in TypeScript Extension
+ 1) Run `Extensions: Show Built-in Extensions` from VSCode's command palette
+ 2) Find `TypeScript and JavaScript Language Features`, right click and select `Disable (Workspace)`
+2. Reload the VSCode window by running `Developer: Reload Window` from the command palette.
+
+## Customize configuration
+
+See [Vite Configuration Reference](https://vitejs.dev/config/).
+
+## Project Setup
+
+```sh
+pnpm install
+```
+
+### Compile and Hot-Reload for Development
+
+```sh
+pnpm dev
+```
+
+### Type-Check, Compile and Minify for Production
+
+```sh
+pnpm build
+```
diff --git a/playground/typescript-jsx/env.d.ts b/playground/typescript-jsx/env.d.ts
new file mode 100644
index 000000000..11f02fe2a
--- /dev/null
+++ b/playground/typescript-jsx/env.d.ts
@@ -0,0 +1 @@
+///
diff --git a/playground/typescript-jsx/index.html b/playground/typescript-jsx/index.html
new file mode 100644
index 000000000..a88854489
--- /dev/null
+++ b/playground/typescript-jsx/index.html
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+ Vite App
+
+
+
+
+
+
diff --git a/playground/typescript-jsx/package.json b/playground/typescript-jsx/package.json
new file mode 100644
index 000000000..1821c162d
--- /dev/null
+++ b/playground/typescript-jsx/package.json
@@ -0,0 +1,27 @@
+{
+ "name": "typescript-jsx",
+ "version": "0.0.0",
+ "private": true,
+ "type": "module",
+ "scripts": {
+ "dev": "vite",
+ "build": "run-p type-check \"build-only {@}\" --",
+ "preview": "vite preview",
+ "build-only": "vite build",
+ "type-check": "vue-tsc --build --force"
+ },
+ "dependencies": {
+ "vue": "^3.4.15"
+ },
+ "devDependencies": {
+ "@tsconfig/node20": "^20.1.2",
+ "@types/node": "^20.11.16",
+ "@vitejs/plugin-vue": "^5.0.3",
+ "@vitejs/plugin-vue-jsx": "^3.1.0",
+ "@vue/tsconfig": "^0.5.1",
+ "npm-run-all2": "^6.1.2",
+ "typescript": "~5.3.0",
+ "vite": "^5.0.11",
+ "vue-tsc": "^1.8.27"
+ }
+}
diff --git a/playground/typescript-jsx/public/favicon.ico b/playground/typescript-jsx/public/favicon.ico
new file mode 100644
index 000000000..df36fcfb7
Binary files /dev/null and b/playground/typescript-jsx/public/favicon.ico differ
diff --git a/playground/typescript-jsx/src/App.vue b/playground/typescript-jsx/src/App.vue
new file mode 100644
index 000000000..69f32f91f
--- /dev/null
+++ b/playground/typescript-jsx/src/App.vue
@@ -0,0 +1,10 @@
+
+ app
+
+
+
+
+
diff --git a/playground/typescript-jsx/src/assets/logo.svg b/playground/typescript-jsx/src/assets/logo.svg
new file mode 100644
index 000000000..756566035
--- /dev/null
+++ b/playground/typescript-jsx/src/assets/logo.svg
@@ -0,0 +1 @@
+
diff --git a/playground/typescript-jsx/src/assets/main.css b/playground/typescript-jsx/src/assets/main.css
new file mode 100644
index 000000000..5aadc6ceb
--- /dev/null
+++ b/playground/typescript-jsx/src/assets/main.css
@@ -0,0 +1,6 @@
+html, body, #app {
+ width: 100%;
+ height: 100%;
+ padding: 0;
+ margin: 0;
+}
diff --git a/playground/typescript-jsx/src/main.ts b/playground/typescript-jsx/src/main.ts
new file mode 100644
index 000000000..0ac3a5ff0
--- /dev/null
+++ b/playground/typescript-jsx/src/main.ts
@@ -0,0 +1,6 @@
+import './assets/main.css'
+
+import { createApp } from 'vue'
+import App from './App.vue'
+
+createApp(App).mount('#app')
diff --git a/playground/typescript-jsx/tsconfig.app.json b/playground/typescript-jsx/tsconfig.app.json
new file mode 100644
index 000000000..e14c754d3
--- /dev/null
+++ b/playground/typescript-jsx/tsconfig.app.json
@@ -0,0 +1,14 @@
+{
+ "extends": "@vue/tsconfig/tsconfig.dom.json",
+ "include": ["env.d.ts", "src/**/*", "src/**/*.vue"],
+ "exclude": ["src/**/__tests__/*"],
+ "compilerOptions": {
+ "composite": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
+
+ "baseUrl": ".",
+ "paths": {
+ "@/*": ["./src/*"]
+ }
+ }
+}
diff --git a/playground/typescript-jsx/tsconfig.json b/playground/typescript-jsx/tsconfig.json
new file mode 100644
index 000000000..66b5e5703
--- /dev/null
+++ b/playground/typescript-jsx/tsconfig.json
@@ -0,0 +1,11 @@
+{
+ "files": [],
+ "references": [
+ {
+ "path": "./tsconfig.node.json"
+ },
+ {
+ "path": "./tsconfig.app.json"
+ }
+ ]
+}
diff --git a/playground/typescript-jsx/tsconfig.node.json b/playground/typescript-jsx/tsconfig.node.json
new file mode 100644
index 000000000..f09406303
--- /dev/null
+++ b/playground/typescript-jsx/tsconfig.node.json
@@ -0,0 +1,19 @@
+{
+ "extends": "@tsconfig/node20/tsconfig.json",
+ "include": [
+ "vite.config.*",
+ "vitest.config.*",
+ "cypress.config.*",
+ "nightwatch.conf.*",
+ "playwright.config.*"
+ ],
+ "compilerOptions": {
+ "composite": true,
+ "noEmit": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
+
+ "module": "ESNext",
+ "moduleResolution": "Bundler",
+ "types": ["node"]
+ }
+}
diff --git a/playground/typescript-jsx/vite.config.ts b/playground/typescript-jsx/vite.config.ts
new file mode 100644
index 000000000..36c618756
--- /dev/null
+++ b/playground/typescript-jsx/vite.config.ts
@@ -0,0 +1,18 @@
+import { fileURLToPath, URL } from 'node:url'
+
+import { defineConfig } from 'vite'
+import vue from '@vitejs/plugin-vue'
+import vueJsx from '@vitejs/plugin-vue-jsx'
+
+// https://vitejs.dev/config/
+export default defineConfig({
+ plugins: [
+ vue(),
+ vueJsx(),
+ ],
+ resolve: {
+ alias: {
+ '@': fileURLToPath(new URL('./src', import.meta.url))
+ }
+ }
+})
diff --git a/playground/typescript-nightwatch/.gitignore b/playground/typescript-nightwatch/.gitignore
new file mode 100644
index 000000000..0b938f131
--- /dev/null
+++ b/playground/typescript-nightwatch/.gitignore
@@ -0,0 +1,33 @@
+# 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/
+
+# Editor directories and files
+.vscode/*
+!.vscode/extensions.json
+.idea
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?
+
+*.tsbuildinfo
+
+logs/
+tests_output/
diff --git a/playground/typescript-nightwatch/.vscode/extensions.json b/playground/typescript-nightwatch/.vscode/extensions.json
new file mode 100644
index 000000000..dd9668a5c
--- /dev/null
+++ b/playground/typescript-nightwatch/.vscode/extensions.json
@@ -0,0 +1,3 @@
+{
+ "recommendations": ["browserstackcom.nightwatch"]
+}
diff --git a/playground/typescript-nightwatch/README.md b/playground/typescript-nightwatch/README.md
new file mode 100644
index 000000000..e9ca024d3
--- /dev/null
+++ b/playground/typescript-nightwatch/README.md
@@ -0,0 +1,63 @@
+# typescript-nightwatch
+
+This template should help get you started developing with Vue 3 in Vite.
+
+## Recommended IDE Setup
+
+[VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur) + [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin).
+
+## Type Support for `.vue` Imports in TS
+
+TypeScript cannot handle type information for `.vue` imports by default, so we replace the `tsc` CLI with `vue-tsc` for type checking. In editors, we need [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin) to make the TypeScript language service aware of `.vue` types.
+
+If the standalone TypeScript plugin doesn't feel fast enough to you, Volar has also implemented a [Take Over Mode](https://github.com/johnsoncodehk/volar/discussions/471#discussioncomment-1361669) that is more performant. You can enable it by the following steps:
+
+1. Disable the built-in TypeScript Extension
+ 1) Run `Extensions: Show Built-in Extensions` from VSCode's command palette
+ 2) Find `TypeScript and JavaScript Language Features`, right click and select `Disable (Workspace)`
+2. Reload the VSCode window by running `Developer: Reload Window` from the command palette.
+
+## Customize configuration
+
+See [Vite Configuration Reference](https://vitejs.dev/config/).
+
+## Project Setup
+
+```sh
+pnpm install
+```
+
+### Compile and Hot-Reload for Development
+
+```sh
+pnpm dev
+```
+
+### Type-Check, Compile and Minify for Production
+
+```sh
+pnpm build
+```
+
+### Run End-to-End Tests with [Nightwatch](https://nightwatchjs.org/)
+
+```sh
+# When using CI, the project must be built first.
+pnpm build
+
+# Runs the end-to-end tests
+pnpm test:e2e
+# Runs the tests only on Chrome
+pnpm test:e2e --env chrome
+# Runs the tests of a specific file
+pnpm test:e2e tests/e2e/example.ts
+# Runs the tests in debug mode
+pnpm test:e2e --debug
+```
+
+### Run Headed Component Tests with [Nightwatch Component Testing](https://nightwatchjs.org/guide/component-testing/introduction.html)
+
+```sh
+pnpm test:unit
+pnpm test:unit -- --headless # for headless testing
+```
diff --git a/playground/typescript-nightwatch/env.d.ts b/playground/typescript-nightwatch/env.d.ts
new file mode 100644
index 000000000..11f02fe2a
--- /dev/null
+++ b/playground/typescript-nightwatch/env.d.ts
@@ -0,0 +1 @@
+///
diff --git a/playground/typescript-nightwatch/index.html b/playground/typescript-nightwatch/index.html
new file mode 100644
index 000000000..a88854489
--- /dev/null
+++ b/playground/typescript-nightwatch/index.html
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+ Vite App
+
+
+
+
+
+
diff --git a/playground/typescript-nightwatch/nightwatch.conf.cjs b/playground/typescript-nightwatch/nightwatch.conf.cjs
new file mode 100644
index 000000000..542647e5e
--- /dev/null
+++ b/playground/typescript-nightwatch/nightwatch.conf.cjs
@@ -0,0 +1,153 @@
+//
+// Refer to the online docs for more details:
+// https://nightwatchjs.org/guide/configuration/nightwatch-configuration-file.html
+//
+// _ _ _ _ _ _ _
+// | \ | |(_) | | | | | | | |
+// | \| | _ __ _ | |__ | |_ __ __ __ _ | |_ ___ | |__
+// | . ` || | / _` || '_ \ | __|\ \ /\ / / / _` || __| / __|| '_ \
+// | |\ || || (_| || | | || |_ \ V V / | (_| || |_ | (__ | | | |
+// \_| \_/|_| \__, ||_| |_| \__| \_/\_/ \__,_| \__| \___||_| |_|
+// __/ |
+// |___/
+//
+
+module.exports = {
+ // An array of folders (excluding subfolders) where your tests are located;
+ // if this is not specified, the test source must be passed as the second argument to the test runner.
+ src_folders: [],
+
+ // See https://nightwatchjs.org/guide/concepts/page-object-model.html
+ page_objects_path: [],
+
+ // See https://nightwatchjs.org/guide/extending-nightwatch/adding-custom-commands.html
+ custom_commands_path: [],
+
+ // See https://nightwatchjs.org/guide/extending-nightwatch/adding-custom-assertions.html
+ custom_assertions_path: [],
+
+ // See https://nightwatchjs.org/guide/extending-nightwatch/adding-plugins.html
+ plugins: ['@nightwatch/vue'],
+
+ // See https://nightwatchjs.org/guide/concepts/test-globals.html#external-test-globals
+ globals_path: '',
+
+ vite_dev_server: {
+ start_vite: true,
+ port: process.env.CI ? 4173 : 5173
+ },
+
+ webdriver: {},
+
+ test_workers: {
+ enabled: true,
+ workers: 'auto'
+ },
+
+ test_settings: {
+ default: {
+ disable_error_log: false,
+ launch_url: `http://localhost:${process.env.CI ? '4173' : '5173'}`,
+
+ screenshots: {
+ enabled: false,
+ path: 'screens',
+ on_failure: true
+ },
+
+ desiredCapabilities: {
+ browserName: 'firefox'
+ },
+
+ webdriver: {
+ start_process: true,
+ server_path: ''
+ }
+ },
+
+ safari: {
+ desiredCapabilities: {
+ browserName: 'safari',
+ alwaysMatch: {
+ acceptInsecureCerts: false
+ }
+ },
+ webdriver: {
+ start_process: true,
+ server_path: ''
+ }
+ },
+
+ firefox: {
+ desiredCapabilities: {
+ browserName: 'firefox',
+ alwaysMatch: {
+ acceptInsecureCerts: true,
+ 'moz:firefoxOptions': {
+ args: [
+ // '-headless',
+ // '-verbose'
+ ]
+ }
+ }
+ },
+ webdriver: {
+ start_process: true,
+ server_path: '',
+ cli_args: [
+ // very verbose geckodriver logs
+ // '-vv'
+ ]
+ }
+ },
+
+ chrome: {
+ desiredCapabilities: {
+ browserName: 'chrome',
+ 'goog:chromeOptions': {
+ // More info on Chromedriver: https://sites.google.com/a/chromium.org/chromedriver/
+ //
+ // w3c:false tells Chromedriver to run using the legacy JSONWire protocol (not required in Chrome 78)
+ w3c: true,
+ args: [
+ //'--no-sandbox',
+ //'--ignore-certificate-errors',
+ //'--allow-insecure-localhost',
+ //'--headless'
+ ]
+ }
+ },
+
+ webdriver: {
+ start_process: true,
+ server_path: '',
+ cli_args: [
+ // --verbose
+ ]
+ }
+ },
+
+ edge: {
+ desiredCapabilities: {
+ browserName: 'MicrosoftEdge',
+ 'ms:edgeOptions': {
+ w3c: true,
+ // More info on EdgeDriver: https://docs.microsoft.com/en-us/microsoft-edge/webdriver-chromium/capabilities-edge-options
+ args: [
+ //'--headless'
+ ]
+ }
+ },
+
+ webdriver: {
+ start_process: true,
+ // Download msedgedriver from https://docs.microsoft.com/en-us/microsoft-edge/webdriver-chromium/
+ // and set the location below:
+ server_path: '',
+ cli_args: [
+ // --verbose
+ ]
+ }
+ }
+ }
+}
diff --git a/playground/typescript-nightwatch/nightwatch/index.html b/playground/typescript-nightwatch/nightwatch/index.html
new file mode 100644
index 000000000..b7e1ec765
--- /dev/null
+++ b/playground/typescript-nightwatch/nightwatch/index.html
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
+ Vue Renderer
+
+
+
+
+
+
+
diff --git a/playground/typescript-nightwatch/nightwatch/nightwatch.d.ts b/playground/typescript-nightwatch/nightwatch/nightwatch.d.ts
new file mode 100644
index 000000000..616e63f9f
--- /dev/null
+++ b/playground/typescript-nightwatch/nightwatch/nightwatch.d.ts
@@ -0,0 +1,13 @@
+import { NightwatchCustomAssertions, NightwatchCustomCommands } from 'nightwatch'
+
+declare module 'nightwatch' {
+ interface NightwatchCustomAssertions {
+ // Add your custom assertions' types here
+ // elementHasCount: (selector: string, count: number) => NightwatchBrowser
+ }
+
+ interface NightwatchCustomCommands {
+ // Add your custom commands' types here
+ // strictClick: (selector: string) => NightwatchBrowser
+ }
+}
diff --git a/playground/typescript-nightwatch/nightwatch/tsconfig.json b/playground/typescript-nightwatch/nightwatch/tsconfig.json
new file mode 100644
index 000000000..8cd7ca1da
--- /dev/null
+++ b/playground/typescript-nightwatch/nightwatch/tsconfig.json
@@ -0,0 +1,20 @@
+{
+ "extends": "@tsconfig/node20/tsconfig.json",
+ "compilerOptions": {
+ "composite": true,
+ "noEmit": true,
+ "tsBuildInfoFile": "../node_modules/.tmp/tsconfig.nightwatch.tsbuildinfo",
+
+ "target": "ESNext",
+ "module": "commonjs",
+ "moduleResolution": "node",
+ "rootDir": "../",
+ "lib": ["ESNext", "dom"],
+ "types": ["nightwatch"]
+ },
+ "include": ["../node_modules/@nightwatch/**/*", "../src/components/**/*", "../tests/e2e/**/*"],
+ "ts-node": {
+ "transpileOnly": true
+ },
+ "files": ["nightwatch.d.ts"]
+}
diff --git a/playground/typescript-nightwatch/package.json b/playground/typescript-nightwatch/package.json
new file mode 100644
index 000000000..e67792604
--- /dev/null
+++ b/playground/typescript-nightwatch/package.json
@@ -0,0 +1,35 @@
+{
+ "name": "typescript-nightwatch",
+ "version": "0.0.0",
+ "private": true,
+ "type": "module",
+ "scripts": {
+ "dev": "vite",
+ "build": "run-p type-check \"build-only {@}\" --",
+ "preview": "vite preview",
+ "test:e2e": "nightwatch tests/e2e/*",
+ "test:unit": "nightwatch src/**/__tests__/*",
+ "build-only": "vite build",
+ "type-check": "vue-tsc --build --force"
+ },
+ "dependencies": {
+ "vue": "^3.4.15"
+ },
+ "devDependencies": {
+ "@nightwatch/vue": "^3.1.0",
+ "@tsconfig/node20": "^20.1.2",
+ "@types/node": "^20.11.16",
+ "@vitejs/plugin-vue": "^5.0.3",
+ "@vue/test-utils": "^2.4.4",
+ "@vue/tsconfig": "^0.5.1",
+ "chromedriver": "^121.0.0",
+ "geckodriver": "^4.3.2",
+ "nightwatch": "^3.4.0",
+ "npm-run-all2": "^6.1.2",
+ "ts-node": "^10.9.2",
+ "typescript": "~5.3.0",
+ "vite": "^5.0.11",
+ "vite-plugin-nightwatch": "^0.4.6",
+ "vue-tsc": "^1.8.27"
+ }
+}
diff --git a/playground/typescript-nightwatch/public/favicon.ico b/playground/typescript-nightwatch/public/favicon.ico
new file mode 100644
index 000000000..df36fcfb7
Binary files /dev/null and b/playground/typescript-nightwatch/public/favicon.ico differ
diff --git a/playground/typescript-nightwatch/src/App.vue b/playground/typescript-nightwatch/src/App.vue
new file mode 100644
index 000000000..69f32f91f
--- /dev/null
+++ b/playground/typescript-nightwatch/src/App.vue
@@ -0,0 +1,10 @@
+
+ app
+
+
+
+
+
diff --git a/playground/typescript-nightwatch/src/assets/logo.svg b/playground/typescript-nightwatch/src/assets/logo.svg
new file mode 100644
index 000000000..756566035
--- /dev/null
+++ b/playground/typescript-nightwatch/src/assets/logo.svg
@@ -0,0 +1 @@
+
diff --git a/playground/typescript-nightwatch/src/assets/main.css b/playground/typescript-nightwatch/src/assets/main.css
new file mode 100644
index 000000000..5aadc6ceb
--- /dev/null
+++ b/playground/typescript-nightwatch/src/assets/main.css
@@ -0,0 +1,6 @@
+html, body, #app {
+ width: 100%;
+ height: 100%;
+ padding: 0;
+ margin: 0;
+}
diff --git a/playground/typescript-nightwatch/src/components/__tests__/HelloWorld.spec.ts b/playground/typescript-nightwatch/src/components/__tests__/HelloWorld.spec.ts
new file mode 100644
index 000000000..810641e6e
--- /dev/null
+++ b/playground/typescript-nightwatch/src/components/__tests__/HelloWorld.spec.ts
@@ -0,0 +1,14 @@
+describe('Hello World', function () {
+ before((browser) => {
+ browser.init()
+ })
+
+ it('renders properly', async function () {
+ const welcomeComponent = await browser.mountComponent('/src/components/HelloWorld.vue', {props: {msg: 'Hello Nightwatch'}});
+
+ browser.expect.element(welcomeComponent).to.be.present;
+ browser.expect.element('h1').text.to.contain('Hello Nightwatch');
+ })
+
+ after((browser) => browser.end())
+})
diff --git a/playground/typescript-nightwatch/src/main.ts b/playground/typescript-nightwatch/src/main.ts
new file mode 100644
index 000000000..0ac3a5ff0
--- /dev/null
+++ b/playground/typescript-nightwatch/src/main.ts
@@ -0,0 +1,6 @@
+import './assets/main.css'
+
+import { createApp } from 'vue'
+import App from './App.vue'
+
+createApp(App).mount('#app')
diff --git a/playground/typescript-nightwatch/tests/e2e/example.ts b/playground/typescript-nightwatch/tests/e2e/example.ts
new file mode 100644
index 000000000..43be3fce1
--- /dev/null
+++ b/playground/typescript-nightwatch/tests/e2e/example.ts
@@ -0,0 +1,11 @@
+describe('My First Test', function () {
+ before((browser) => {
+ browser.init()
+ })
+
+ it('visits the app root url', function () {
+ browser.assert.textContains('.green', 'You did it!')
+ })
+
+ after((browser) => browser.end())
+})
diff --git a/playground/typescript-nightwatch/tsconfig.app.json b/playground/typescript-nightwatch/tsconfig.app.json
new file mode 100644
index 000000000..e14c754d3
--- /dev/null
+++ b/playground/typescript-nightwatch/tsconfig.app.json
@@ -0,0 +1,14 @@
+{
+ "extends": "@vue/tsconfig/tsconfig.dom.json",
+ "include": ["env.d.ts", "src/**/*", "src/**/*.vue"],
+ "exclude": ["src/**/__tests__/*"],
+ "compilerOptions": {
+ "composite": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
+
+ "baseUrl": ".",
+ "paths": {
+ "@/*": ["./src/*"]
+ }
+ }
+}
diff --git a/playground/typescript-nightwatch/tsconfig.json b/playground/typescript-nightwatch/tsconfig.json
new file mode 100644
index 000000000..5c385ae2c
--- /dev/null
+++ b/playground/typescript-nightwatch/tsconfig.json
@@ -0,0 +1,14 @@
+{
+ "files": [],
+ "references": [
+ {
+ "path": "./tsconfig.node.json"
+ },
+ {
+ "path": "./tsconfig.app.json"
+ },
+ {
+ "path": "./nightwatch/tsconfig.json"
+ }
+ ]
+}
diff --git a/playground/typescript-nightwatch/tsconfig.node.json b/playground/typescript-nightwatch/tsconfig.node.json
new file mode 100644
index 000000000..f09406303
--- /dev/null
+++ b/playground/typescript-nightwatch/tsconfig.node.json
@@ -0,0 +1,19 @@
+{
+ "extends": "@tsconfig/node20/tsconfig.json",
+ "include": [
+ "vite.config.*",
+ "vitest.config.*",
+ "cypress.config.*",
+ "nightwatch.conf.*",
+ "playwright.config.*"
+ ],
+ "compilerOptions": {
+ "composite": true,
+ "noEmit": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
+
+ "module": "ESNext",
+ "moduleResolution": "Bundler",
+ "types": ["node"]
+ }
+}
diff --git a/playground/typescript-nightwatch/vite.config.ts b/playground/typescript-nightwatch/vite.config.ts
new file mode 100644
index 000000000..fd83c5b21
--- /dev/null
+++ b/playground/typescript-nightwatch/vite.config.ts
@@ -0,0 +1,20 @@
+import { fileURLToPath, URL } from 'node:url'
+
+import { defineConfig } from 'vite'
+import vue from '@vitejs/plugin-vue'
+import nightwatchPlugin from 'vite-plugin-nightwatch'
+
+// https://vitejs.dev/config/
+export default defineConfig({
+ plugins: [
+ vue(),
+ nightwatchPlugin({
+ renderPage: './nightwatch/index.html'
+ }),
+ ],
+ resolve: {
+ alias: {
+ '@': fileURLToPath(new URL('./src', import.meta.url))
+ }
+ }
+})
diff --git a/playground/typescript-pinia-cypress/.gitignore b/playground/typescript-pinia-cypress/.gitignore
new file mode 100644
index 000000000..8ee54e8d3
--- /dev/null
+++ b/playground/typescript-pinia-cypress/.gitignore
@@ -0,0 +1,30 @@
+# 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/
+
+# Editor directories and files
+.vscode/*
+!.vscode/extensions.json
+.idea
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?
+
+*.tsbuildinfo
diff --git a/playground/typescript-pinia-cypress/README.md b/playground/typescript-pinia-cypress/README.md
new file mode 100644
index 000000000..e0d8690a5
--- /dev/null
+++ b/playground/typescript-pinia-cypress/README.md
@@ -0,0 +1,62 @@
+# typescript-pinia-cypress
+
+This template should help get you started developing with Vue 3 in Vite.
+
+## Recommended IDE Setup
+
+[VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur) + [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin).
+
+## Type Support for `.vue` Imports in TS
+
+TypeScript cannot handle type information for `.vue` imports by default, so we replace the `tsc` CLI with `vue-tsc` for type checking. In editors, we need [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin) to make the TypeScript language service aware of `.vue` types.
+
+If the standalone TypeScript plugin doesn't feel fast enough to you, Volar has also implemented a [Take Over Mode](https://github.com/johnsoncodehk/volar/discussions/471#discussioncomment-1361669) that is more performant. You can enable it by the following steps:
+
+1. Disable the built-in TypeScript Extension
+ 1) Run `Extensions: Show Built-in Extensions` from VSCode's command palette
+ 2) Find `TypeScript and JavaScript Language Features`, right click and select `Disable (Workspace)`
+2. Reload the VSCode window by running `Developer: Reload Window` from the command palette.
+
+## Customize configuration
+
+See [Vite Configuration Reference](https://vitejs.dev/config/).
+
+## Project Setup
+
+```sh
+pnpm install
+```
+
+### Compile and Hot-Reload for Development
+
+```sh
+pnpm dev
+```
+
+### Type-Check, Compile and Minify for Production
+
+```sh
+pnpm build
+```
+
+### Run Headed Component Tests with [Cypress Component Testing](https://on.cypress.io/component)
+
+```sh
+pnpm test:unit:dev # or `pnpm test:unit` for headless testing
+```
+
+### Run End-to-End Tests with [Cypress](https://www.cypress.io/)
+
+```sh
+pnpm test:e2e:dev
+```
+
+This runs the end-to-end tests against the Vite development server.
+It is much faster than the production build.
+
+But it's still recommended to test the production build with `test:e2e` before deploying (e.g. in CI environments):
+
+```sh
+pnpm build
+pnpm test:e2e
+```
diff --git a/playground/typescript-pinia-cypress/cypress.config.ts b/playground/typescript-pinia-cypress/cypress.config.ts
new file mode 100644
index 000000000..c8fac1298
--- /dev/null
+++ b/playground/typescript-pinia-cypress/cypress.config.ts
@@ -0,0 +1,15 @@
+import { defineConfig } from 'cypress'
+
+export default defineConfig({
+ e2e: {
+ specPattern: 'cypress/e2e/**/*.{cy,spec}.{js,jsx,ts,tsx}',
+ baseUrl: 'http://localhost:4173'
+ },
+ component: {
+ specPattern: 'src/**/__tests__/*.{cy,spec}.{js,ts,jsx,tsx}',
+ devServer: {
+ framework: 'vue',
+ bundler: 'vite'
+ }
+ }
+})
diff --git a/playground/typescript-pinia-cypress/cypress/e2e/example.cy.ts b/playground/typescript-pinia-cypress/cypress/e2e/example.cy.ts
new file mode 100644
index 000000000..7554c35d8
--- /dev/null
+++ b/playground/typescript-pinia-cypress/cypress/e2e/example.cy.ts
@@ -0,0 +1,8 @@
+// https://on.cypress.io/api
+
+describe('My First Test', () => {
+ it('visits the app root url', () => {
+ cy.visit('/')
+ cy.contains('h1', 'You did it!')
+ })
+})
diff --git a/playground/typescript-pinia-cypress/cypress/e2e/tsconfig.json b/playground/typescript-pinia-cypress/cypress/e2e/tsconfig.json
new file mode 100644
index 000000000..37748feb7
--- /dev/null
+++ b/playground/typescript-pinia-cypress/cypress/e2e/tsconfig.json
@@ -0,0 +1,10 @@
+{
+ "extends": "@vue/tsconfig/tsconfig.dom.json",
+ "include": ["./**/*", "../support/**/*"],
+ "compilerOptions": {
+ "isolatedModules": false,
+ "target": "es5",
+ "lib": ["es5", "dom"],
+ "types": ["cypress"]
+ }
+}
diff --git a/playground/typescript-pinia-cypress/cypress/fixtures/example.json b/playground/typescript-pinia-cypress/cypress/fixtures/example.json
new file mode 100644
index 000000000..02e425437
--- /dev/null
+++ b/playground/typescript-pinia-cypress/cypress/fixtures/example.json
@@ -0,0 +1,5 @@
+{
+ "name": "Using fixtures to represent data",
+ "email": "hello@cypress.io",
+ "body": "Fixtures are a great way to mock data for responses to routes"
+}
diff --git a/playground/typescript-pinia-cypress/cypress/support/commands.ts b/playground/typescript-pinia-cypress/cypress/support/commands.ts
new file mode 100644
index 000000000..9b7bb8e25
--- /dev/null
+++ b/playground/typescript-pinia-cypress/cypress/support/commands.ts
@@ -0,0 +1,39 @@
+///
+// ***********************************************
+// This example commands.ts shows you how to
+// create various custom commands and overwrite
+// existing commands.
+//
+// For more comprehensive examples of custom
+// commands please read more here:
+// https://on.cypress.io/custom-commands
+// ***********************************************
+//
+//
+// -- This is a parent command --
+// Cypress.Commands.add('login', (email, password) => { ... })
+//
+//
+// -- This is a child command --
+// Cypress.Commands.add('drag', { prevSubject: 'element'}, (subject, options) => { ... })
+//
+//
+// -- This is a dual command --
+// Cypress.Commands.add('dismiss', { prevSubject: 'optional'}, (subject, options) => { ... })
+//
+//
+// -- This will overwrite an existing command --
+// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... })
+//
+// declare global {
+// namespace Cypress {
+// interface Chainable {
+// login(email: string, password: string): Chainable
+// drag(subject: string, options?: Partial): Chainable
+// dismiss(subject: string, options?: Partial): Chainable
+// visit(originalFn: CommandOriginalFn, url: string, options: Partial): Chainable
+// }
+// }
+// }
+
+export {}
diff --git a/playground/typescript-pinia-cypress/cypress/support/component-index.html b/playground/typescript-pinia-cypress/cypress/support/component-index.html
new file mode 100644
index 000000000..5f9622ae2
--- /dev/null
+++ b/playground/typescript-pinia-cypress/cypress/support/component-index.html
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+ Components App
+
+
+
+
+
diff --git a/playground/typescript-pinia-cypress/cypress/support/component.ts b/playground/typescript-pinia-cypress/cypress/support/component.ts
new file mode 100644
index 000000000..04e4c352b
--- /dev/null
+++ b/playground/typescript-pinia-cypress/cypress/support/component.ts
@@ -0,0 +1,43 @@
+// ***********************************************************
+// This example support/component.ts is processed and
+// loaded automatically before your test files.
+//
+// This is a great place to put global configuration and
+// behavior that modifies Cypress.
+//
+// You can change the location of this file or turn off
+// automatically serving support files with the
+// 'supportFile' configuration option.
+//
+// You can read more here:
+// https://on.cypress.io/configuration
+// ***********************************************************
+
+// Import commands.js using ES2015 syntax:
+import './commands'
+
+// Alternatively you can use CommonJS syntax:
+// require('./commands')
+
+// Import global styles
+import '@/assets/main.css'
+
+import { mount } from 'cypress/vue'
+
+// Augment the Cypress namespace to include type definitions for
+// your custom command.
+// Alternatively, can be defined in cypress/support/component.d.ts
+// with a at the top of your spec.
+/* eslint-disable @typescript-eslint/no-namespace */
+declare global {
+ namespace Cypress {
+ interface Chainable {
+ mount: typeof mount
+ }
+ }
+}
+
+Cypress.Commands.add('mount', mount)
+
+// Example use:
+// cy.mount(MyComponent)
diff --git a/playground/typescript-pinia-cypress/cypress/support/e2e.ts b/playground/typescript-pinia-cypress/cypress/support/e2e.ts
new file mode 100644
index 000000000..d68db96df
--- /dev/null
+++ b/playground/typescript-pinia-cypress/cypress/support/e2e.ts
@@ -0,0 +1,20 @@
+// ***********************************************************
+// This example support/index.js is processed and
+// loaded automatically before your test files.
+//
+// This is a great place to put global configuration and
+// behavior that modifies Cypress.
+//
+// You can change the location of this file or turn off
+// automatically serving support files with the
+// 'supportFile' configuration option.
+//
+// You can read more here:
+// https://on.cypress.io/configuration
+// ***********************************************************
+
+// Import commands.js using ES2015 syntax:
+import './commands'
+
+// Alternatively you can use CommonJS syntax:
+// require('./commands')
diff --git a/playground/typescript-pinia-cypress/env.d.ts b/playground/typescript-pinia-cypress/env.d.ts
new file mode 100644
index 000000000..11f02fe2a
--- /dev/null
+++ b/playground/typescript-pinia-cypress/env.d.ts
@@ -0,0 +1 @@
+///
diff --git a/playground/typescript-pinia-cypress/index.html b/playground/typescript-pinia-cypress/index.html
new file mode 100644
index 000000000..a88854489
--- /dev/null
+++ b/playground/typescript-pinia-cypress/index.html
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+ Vite App
+
+
+
+
+
+
diff --git a/playground/typescript-pinia-cypress/package.json b/playground/typescript-pinia-cypress/package.json
new file mode 100644
index 000000000..bd188ba76
--- /dev/null
+++ b/playground/typescript-pinia-cypress/package.json
@@ -0,0 +1,33 @@
+{
+ "name": "typescript-pinia-cypress",
+ "version": "0.0.0",
+ "private": true,
+ "type": "module",
+ "scripts": {
+ "dev": "vite",
+ "build": "run-p type-check \"build-only {@}\" --",
+ "preview": "vite preview",
+ "test:e2e": "start-server-and-test preview http://localhost:4173 'cypress run --e2e'",
+ "test:e2e:dev": "start-server-and-test 'vite dev --port 4173' http://localhost:4173 'cypress open --e2e'",
+ "test:unit": "cypress run --component",
+ "test:unit:dev": "cypress open --component",
+ "build-only": "vite build",
+ "type-check": "vue-tsc --build --force"
+ },
+ "dependencies": {
+ "pinia": "^2.1.7",
+ "vue": "^3.4.15"
+ },
+ "devDependencies": {
+ "@tsconfig/node20": "^20.1.2",
+ "@types/node": "^20.11.16",
+ "@vitejs/plugin-vue": "^5.0.3",
+ "@vue/tsconfig": "^0.5.1",
+ "cypress": "^13.6.4",
+ "npm-run-all2": "^6.1.2",
+ "start-server-and-test": "^2.0.3",
+ "typescript": "~5.3.0",
+ "vite": "^5.0.11",
+ "vue-tsc": "^1.8.27"
+ }
+}
diff --git a/playground/typescript-pinia-cypress/public/favicon.ico b/playground/typescript-pinia-cypress/public/favicon.ico
new file mode 100644
index 000000000..df36fcfb7
Binary files /dev/null and b/playground/typescript-pinia-cypress/public/favicon.ico differ
diff --git a/playground/typescript-pinia-cypress/src/App.vue b/playground/typescript-pinia-cypress/src/App.vue
new file mode 100644
index 000000000..69f32f91f
--- /dev/null
+++ b/playground/typescript-pinia-cypress/src/App.vue
@@ -0,0 +1,10 @@
+
+ app
+
+
+
+
+
diff --git a/playground/typescript-pinia-cypress/src/assets/logo.svg b/playground/typescript-pinia-cypress/src/assets/logo.svg
new file mode 100644
index 000000000..756566035
--- /dev/null
+++ b/playground/typescript-pinia-cypress/src/assets/logo.svg
@@ -0,0 +1 @@
+
diff --git a/playground/typescript-pinia-cypress/src/assets/main.css b/playground/typescript-pinia-cypress/src/assets/main.css
new file mode 100644
index 000000000..5aadc6ceb
--- /dev/null
+++ b/playground/typescript-pinia-cypress/src/assets/main.css
@@ -0,0 +1,6 @@
+html, body, #app {
+ width: 100%;
+ height: 100%;
+ padding: 0;
+ margin: 0;
+}
diff --git a/playground/typescript-pinia-cypress/src/components/__tests__/HelloWorld.cy.ts b/playground/typescript-pinia-cypress/src/components/__tests__/HelloWorld.cy.ts
new file mode 100644
index 000000000..535a0e51c
--- /dev/null
+++ b/playground/typescript-pinia-cypress/src/components/__tests__/HelloWorld.cy.ts
@@ -0,0 +1,12 @@
+import HelloWorld from '../HelloWorld.vue'
+
+describe('HelloWorld', () => {
+ it('playground', () => {
+ cy.mount(HelloWorld, { props: { msg: 'Hello Cypress' } })
+ })
+
+ it('renders properly', () => {
+ cy.mount(HelloWorld, { props: { msg: 'Hello Cypress' } })
+ cy.get('h1').should('contain', 'Hello Cypress')
+ })
+})
diff --git a/playground/typescript-pinia-cypress/src/main.ts b/playground/typescript-pinia-cypress/src/main.ts
new file mode 100644
index 000000000..48dad4313
--- /dev/null
+++ b/playground/typescript-pinia-cypress/src/main.ts
@@ -0,0 +1,11 @@
+import './assets/main.css'
+
+import { createApp } from 'vue'
+import { createPinia } from 'pinia'
+import App from './App.vue'
+
+const app = createApp(App)
+
+app.use(createPinia())
+
+app.mount('#app')
diff --git a/playground/typescript-pinia-cypress/src/stores/counter.ts b/playground/typescript-pinia-cypress/src/stores/counter.ts
new file mode 100644
index 000000000..b6757ba57
--- /dev/null
+++ b/playground/typescript-pinia-cypress/src/stores/counter.ts
@@ -0,0 +1,12 @@
+import { ref, computed } from 'vue'
+import { defineStore } from 'pinia'
+
+export const useCounterStore = defineStore('counter', () => {
+ const count = ref(0)
+ const doubleCount = computed(() => count.value * 2)
+ function increment() {
+ count.value++
+ }
+
+ return { count, doubleCount, increment }
+})
diff --git a/playground/typescript-pinia-cypress/tsconfig.app.json b/playground/typescript-pinia-cypress/tsconfig.app.json
new file mode 100644
index 000000000..e14c754d3
--- /dev/null
+++ b/playground/typescript-pinia-cypress/tsconfig.app.json
@@ -0,0 +1,14 @@
+{
+ "extends": "@vue/tsconfig/tsconfig.dom.json",
+ "include": ["env.d.ts", "src/**/*", "src/**/*.vue"],
+ "exclude": ["src/**/__tests__/*"],
+ "compilerOptions": {
+ "composite": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
+
+ "baseUrl": ".",
+ "paths": {
+ "@/*": ["./src/*"]
+ }
+ }
+}
diff --git a/playground/typescript-pinia-cypress/tsconfig.cypress-ct.json b/playground/typescript-pinia-cypress/tsconfig.cypress-ct.json
new file mode 100644
index 000000000..12833b275
--- /dev/null
+++ b/playground/typescript-pinia-cypress/tsconfig.cypress-ct.json
@@ -0,0 +1,15 @@
+{
+ "extends": "./tsconfig.app.json",
+ "include": [
+ "env.d.ts",
+ "src/**/*",
+ "src/**/*.vue",
+ "cypress/support/component.*",
+ "cypress/support/commands.ts"
+ ],
+ "exclude": [],
+ "compilerOptions": {
+ "composite": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.cypress-ct.tsbuildinfo"
+ }
+}
diff --git a/playground/typescript-pinia-cypress/tsconfig.json b/playground/typescript-pinia-cypress/tsconfig.json
new file mode 100644
index 000000000..d3b6c3172
--- /dev/null
+++ b/playground/typescript-pinia-cypress/tsconfig.json
@@ -0,0 +1,17 @@
+{
+ "files": [],
+ "references": [
+ {
+ "path": "./tsconfig.node.json"
+ },
+ {
+ "path": "./tsconfig.app.json"
+ },
+ {
+ "path": "./tsconfig.cypress-ct.json"
+ }
+ ],
+ "compilerOptions": {
+ "module": "NodeNext"
+ }
+}
diff --git a/playground/typescript-pinia-cypress/tsconfig.node.json b/playground/typescript-pinia-cypress/tsconfig.node.json
new file mode 100644
index 000000000..f09406303
--- /dev/null
+++ b/playground/typescript-pinia-cypress/tsconfig.node.json
@@ -0,0 +1,19 @@
+{
+ "extends": "@tsconfig/node20/tsconfig.json",
+ "include": [
+ "vite.config.*",
+ "vitest.config.*",
+ "cypress.config.*",
+ "nightwatch.conf.*",
+ "playwright.config.*"
+ ],
+ "compilerOptions": {
+ "composite": true,
+ "noEmit": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
+
+ "module": "ESNext",
+ "moduleResolution": "Bundler",
+ "types": ["node"]
+ }
+}
diff --git a/playground/typescript-pinia-cypress/vite.config.ts b/playground/typescript-pinia-cypress/vite.config.ts
new file mode 100644
index 000000000..5c45e1d9b
--- /dev/null
+++ b/playground/typescript-pinia-cypress/vite.config.ts
@@ -0,0 +1,16 @@
+import { fileURLToPath, URL } from 'node:url'
+
+import { defineConfig } from 'vite'
+import vue from '@vitejs/plugin-vue'
+
+// https://vitejs.dev/config/
+export default defineConfig({
+ plugins: [
+ vue(),
+ ],
+ resolve: {
+ alias: {
+ '@': fileURLToPath(new URL('./src', import.meta.url))
+ }
+ }
+})
diff --git a/playground/typescript-pinia-nightwatch/.gitignore b/playground/typescript-pinia-nightwatch/.gitignore
new file mode 100644
index 000000000..0b938f131
--- /dev/null
+++ b/playground/typescript-pinia-nightwatch/.gitignore
@@ -0,0 +1,33 @@
+# 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/
+
+# Editor directories and files
+.vscode/*
+!.vscode/extensions.json
+.idea
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?
+
+*.tsbuildinfo
+
+logs/
+tests_output/
diff --git a/playground/typescript-pinia-nightwatch/.vscode/extensions.json b/playground/typescript-pinia-nightwatch/.vscode/extensions.json
new file mode 100644
index 000000000..dd9668a5c
--- /dev/null
+++ b/playground/typescript-pinia-nightwatch/.vscode/extensions.json
@@ -0,0 +1,3 @@
+{
+ "recommendations": ["browserstackcom.nightwatch"]
+}
diff --git a/playground/typescript-pinia-nightwatch/README.md b/playground/typescript-pinia-nightwatch/README.md
new file mode 100644
index 000000000..8f6468d6b
--- /dev/null
+++ b/playground/typescript-pinia-nightwatch/README.md
@@ -0,0 +1,63 @@
+# typescript-pinia-nightwatch
+
+This template should help get you started developing with Vue 3 in Vite.
+
+## Recommended IDE Setup
+
+[VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur) + [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin).
+
+## Type Support for `.vue` Imports in TS
+
+TypeScript cannot handle type information for `.vue` imports by default, so we replace the `tsc` CLI with `vue-tsc` for type checking. In editors, we need [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin) to make the TypeScript language service aware of `.vue` types.
+
+If the standalone TypeScript plugin doesn't feel fast enough to you, Volar has also implemented a [Take Over Mode](https://github.com/johnsoncodehk/volar/discussions/471#discussioncomment-1361669) that is more performant. You can enable it by the following steps:
+
+1. Disable the built-in TypeScript Extension
+ 1) Run `Extensions: Show Built-in Extensions` from VSCode's command palette
+ 2) Find `TypeScript and JavaScript Language Features`, right click and select `Disable (Workspace)`
+2. Reload the VSCode window by running `Developer: Reload Window` from the command palette.
+
+## Customize configuration
+
+See [Vite Configuration Reference](https://vitejs.dev/config/).
+
+## Project Setup
+
+```sh
+pnpm install
+```
+
+### Compile and Hot-Reload for Development
+
+```sh
+pnpm dev
+```
+
+### Type-Check, Compile and Minify for Production
+
+```sh
+pnpm build
+```
+
+### Run End-to-End Tests with [Nightwatch](https://nightwatchjs.org/)
+
+```sh
+# When using CI, the project must be built first.
+pnpm build
+
+# Runs the end-to-end tests
+pnpm test:e2e
+# Runs the tests only on Chrome
+pnpm test:e2e --env chrome
+# Runs the tests of a specific file
+pnpm test:e2e tests/e2e/example.ts
+# Runs the tests in debug mode
+pnpm test:e2e --debug
+```
+
+### Run Headed Component Tests with [Nightwatch Component Testing](https://nightwatchjs.org/guide/component-testing/introduction.html)
+
+```sh
+pnpm test:unit
+pnpm test:unit -- --headless # for headless testing
+```
diff --git a/playground/typescript-pinia-nightwatch/env.d.ts b/playground/typescript-pinia-nightwatch/env.d.ts
new file mode 100644
index 000000000..11f02fe2a
--- /dev/null
+++ b/playground/typescript-pinia-nightwatch/env.d.ts
@@ -0,0 +1 @@
+///
diff --git a/playground/typescript-pinia-nightwatch/index.html b/playground/typescript-pinia-nightwatch/index.html
new file mode 100644
index 000000000..a88854489
--- /dev/null
+++ b/playground/typescript-pinia-nightwatch/index.html
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+ Vite App
+
+
+
+
+
+
diff --git a/playground/typescript-pinia-nightwatch/nightwatch.conf.cjs b/playground/typescript-pinia-nightwatch/nightwatch.conf.cjs
new file mode 100644
index 000000000..542647e5e
--- /dev/null
+++ b/playground/typescript-pinia-nightwatch/nightwatch.conf.cjs
@@ -0,0 +1,153 @@
+//
+// Refer to the online docs for more details:
+// https://nightwatchjs.org/guide/configuration/nightwatch-configuration-file.html
+//
+// _ _ _ _ _ _ _
+// | \ | |(_) | | | | | | | |
+// | \| | _ __ _ | |__ | |_ __ __ __ _ | |_ ___ | |__
+// | . ` || | / _` || '_ \ | __|\ \ /\ / / / _` || __| / __|| '_ \
+// | |\ || || (_| || | | || |_ \ V V / | (_| || |_ | (__ | | | |
+// \_| \_/|_| \__, ||_| |_| \__| \_/\_/ \__,_| \__| \___||_| |_|
+// __/ |
+// |___/
+//
+
+module.exports = {
+ // An array of folders (excluding subfolders) where your tests are located;
+ // if this is not specified, the test source must be passed as the second argument to the test runner.
+ src_folders: [],
+
+ // See https://nightwatchjs.org/guide/concepts/page-object-model.html
+ page_objects_path: [],
+
+ // See https://nightwatchjs.org/guide/extending-nightwatch/adding-custom-commands.html
+ custom_commands_path: [],
+
+ // See https://nightwatchjs.org/guide/extending-nightwatch/adding-custom-assertions.html
+ custom_assertions_path: [],
+
+ // See https://nightwatchjs.org/guide/extending-nightwatch/adding-plugins.html
+ plugins: ['@nightwatch/vue'],
+
+ // See https://nightwatchjs.org/guide/concepts/test-globals.html#external-test-globals
+ globals_path: '',
+
+ vite_dev_server: {
+ start_vite: true,
+ port: process.env.CI ? 4173 : 5173
+ },
+
+ webdriver: {},
+
+ test_workers: {
+ enabled: true,
+ workers: 'auto'
+ },
+
+ test_settings: {
+ default: {
+ disable_error_log: false,
+ launch_url: `http://localhost:${process.env.CI ? '4173' : '5173'}`,
+
+ screenshots: {
+ enabled: false,
+ path: 'screens',
+ on_failure: true
+ },
+
+ desiredCapabilities: {
+ browserName: 'firefox'
+ },
+
+ webdriver: {
+ start_process: true,
+ server_path: ''
+ }
+ },
+
+ safari: {
+ desiredCapabilities: {
+ browserName: 'safari',
+ alwaysMatch: {
+ acceptInsecureCerts: false
+ }
+ },
+ webdriver: {
+ start_process: true,
+ server_path: ''
+ }
+ },
+
+ firefox: {
+ desiredCapabilities: {
+ browserName: 'firefox',
+ alwaysMatch: {
+ acceptInsecureCerts: true,
+ 'moz:firefoxOptions': {
+ args: [
+ // '-headless',
+ // '-verbose'
+ ]
+ }
+ }
+ },
+ webdriver: {
+ start_process: true,
+ server_path: '',
+ cli_args: [
+ // very verbose geckodriver logs
+ // '-vv'
+ ]
+ }
+ },
+
+ chrome: {
+ desiredCapabilities: {
+ browserName: 'chrome',
+ 'goog:chromeOptions': {
+ // More info on Chromedriver: https://sites.google.com/a/chromium.org/chromedriver/
+ //
+ // w3c:false tells Chromedriver to run using the legacy JSONWire protocol (not required in Chrome 78)
+ w3c: true,
+ args: [
+ //'--no-sandbox',
+ //'--ignore-certificate-errors',
+ //'--allow-insecure-localhost',
+ //'--headless'
+ ]
+ }
+ },
+
+ webdriver: {
+ start_process: true,
+ server_path: '',
+ cli_args: [
+ // --verbose
+ ]
+ }
+ },
+
+ edge: {
+ desiredCapabilities: {
+ browserName: 'MicrosoftEdge',
+ 'ms:edgeOptions': {
+ w3c: true,
+ // More info on EdgeDriver: https://docs.microsoft.com/en-us/microsoft-edge/webdriver-chromium/capabilities-edge-options
+ args: [
+ //'--headless'
+ ]
+ }
+ },
+
+ webdriver: {
+ start_process: true,
+ // Download msedgedriver from https://docs.microsoft.com/en-us/microsoft-edge/webdriver-chromium/
+ // and set the location below:
+ server_path: '',
+ cli_args: [
+ // --verbose
+ ]
+ }
+ }
+ }
+}
diff --git a/playground/typescript-pinia-nightwatch/nightwatch/index.html b/playground/typescript-pinia-nightwatch/nightwatch/index.html
new file mode 100644
index 000000000..b7e1ec765
--- /dev/null
+++ b/playground/typescript-pinia-nightwatch/nightwatch/index.html
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
+ Vue Renderer
+
+
+
+
+
+
+
diff --git a/playground/typescript-pinia-nightwatch/nightwatch/nightwatch.d.ts b/playground/typescript-pinia-nightwatch/nightwatch/nightwatch.d.ts
new file mode 100644
index 000000000..616e63f9f
--- /dev/null
+++ b/playground/typescript-pinia-nightwatch/nightwatch/nightwatch.d.ts
@@ -0,0 +1,13 @@
+import { NightwatchCustomAssertions, NightwatchCustomCommands } from 'nightwatch'
+
+declare module 'nightwatch' {
+ interface NightwatchCustomAssertions {
+ // Add your custom assertions' types here
+ // elementHasCount: (selector: string, count: number) => NightwatchBrowser
+ }
+
+ interface NightwatchCustomCommands {
+ // Add your custom commands' types here
+ // strictClick: (selector: string) => NightwatchBrowser
+ }
+}
diff --git a/playground/typescript-pinia-nightwatch/nightwatch/tsconfig.json b/playground/typescript-pinia-nightwatch/nightwatch/tsconfig.json
new file mode 100644
index 000000000..8cd7ca1da
--- /dev/null
+++ b/playground/typescript-pinia-nightwatch/nightwatch/tsconfig.json
@@ -0,0 +1,20 @@
+{
+ "extends": "@tsconfig/node20/tsconfig.json",
+ "compilerOptions": {
+ "composite": true,
+ "noEmit": true,
+ "tsBuildInfoFile": "../node_modules/.tmp/tsconfig.nightwatch.tsbuildinfo",
+
+ "target": "ESNext",
+ "module": "commonjs",
+ "moduleResolution": "node",
+ "rootDir": "../",
+ "lib": ["ESNext", "dom"],
+ "types": ["nightwatch"]
+ },
+ "include": ["../node_modules/@nightwatch/**/*", "../src/components/**/*", "../tests/e2e/**/*"],
+ "ts-node": {
+ "transpileOnly": true
+ },
+ "files": ["nightwatch.d.ts"]
+}
diff --git a/playground/typescript-pinia-nightwatch/package.json b/playground/typescript-pinia-nightwatch/package.json
new file mode 100644
index 000000000..edc96c89e
--- /dev/null
+++ b/playground/typescript-pinia-nightwatch/package.json
@@ -0,0 +1,36 @@
+{
+ "name": "typescript-pinia-nightwatch",
+ "version": "0.0.0",
+ "private": true,
+ "type": "module",
+ "scripts": {
+ "dev": "vite",
+ "build": "run-p type-check \"build-only {@}\" --",
+ "preview": "vite preview",
+ "test:e2e": "nightwatch tests/e2e/*",
+ "test:unit": "nightwatch src/**/__tests__/*",
+ "build-only": "vite build",
+ "type-check": "vue-tsc --build --force"
+ },
+ "dependencies": {
+ "pinia": "^2.1.7",
+ "vue": "^3.4.15"
+ },
+ "devDependencies": {
+ "@nightwatch/vue": "^3.1.0",
+ "@tsconfig/node20": "^20.1.2",
+ "@types/node": "^20.11.16",
+ "@vitejs/plugin-vue": "^5.0.3",
+ "@vue/test-utils": "^2.4.4",
+ "@vue/tsconfig": "^0.5.1",
+ "chromedriver": "^121.0.0",
+ "geckodriver": "^4.3.2",
+ "nightwatch": "^3.4.0",
+ "npm-run-all2": "^6.1.2",
+ "ts-node": "^10.9.2",
+ "typescript": "~5.3.0",
+ "vite": "^5.0.11",
+ "vite-plugin-nightwatch": "^0.4.6",
+ "vue-tsc": "^1.8.27"
+ }
+}
diff --git a/playground/typescript-pinia-nightwatch/public/favicon.ico b/playground/typescript-pinia-nightwatch/public/favicon.ico
new file mode 100644
index 000000000..df36fcfb7
Binary files /dev/null and b/playground/typescript-pinia-nightwatch/public/favicon.ico differ
diff --git a/playground/typescript-pinia-nightwatch/src/App.vue b/playground/typescript-pinia-nightwatch/src/App.vue
new file mode 100644
index 000000000..69f32f91f
--- /dev/null
+++ b/playground/typescript-pinia-nightwatch/src/App.vue
@@ -0,0 +1,10 @@
+
+ app
+
+
+
+
+
diff --git a/playground/typescript-pinia-nightwatch/src/assets/logo.svg b/playground/typescript-pinia-nightwatch/src/assets/logo.svg
new file mode 100644
index 000000000..756566035
--- /dev/null
+++ b/playground/typescript-pinia-nightwatch/src/assets/logo.svg
@@ -0,0 +1 @@
+
diff --git a/playground/typescript-pinia-nightwatch/src/assets/main.css b/playground/typescript-pinia-nightwatch/src/assets/main.css
new file mode 100644
index 000000000..5aadc6ceb
--- /dev/null
+++ b/playground/typescript-pinia-nightwatch/src/assets/main.css
@@ -0,0 +1,6 @@
+html, body, #app {
+ width: 100%;
+ height: 100%;
+ padding: 0;
+ margin: 0;
+}
diff --git a/playground/typescript-pinia-nightwatch/src/components/__tests__/HelloWorld.spec.ts b/playground/typescript-pinia-nightwatch/src/components/__tests__/HelloWorld.spec.ts
new file mode 100644
index 000000000..810641e6e
--- /dev/null
+++ b/playground/typescript-pinia-nightwatch/src/components/__tests__/HelloWorld.spec.ts
@@ -0,0 +1,14 @@
+describe('Hello World', function () {
+ before((browser) => {
+ browser.init()
+ })
+
+ it('renders properly', async function () {
+ const welcomeComponent = await browser.mountComponent('/src/components/HelloWorld.vue', {props: {msg: 'Hello Nightwatch'}});
+
+ browser.expect.element(welcomeComponent).to.be.present;
+ browser.expect.element('h1').text.to.contain('Hello Nightwatch');
+ })
+
+ after((browser) => browser.end())
+})
diff --git a/playground/typescript-pinia-nightwatch/src/main.ts b/playground/typescript-pinia-nightwatch/src/main.ts
new file mode 100644
index 000000000..48dad4313
--- /dev/null
+++ b/playground/typescript-pinia-nightwatch/src/main.ts
@@ -0,0 +1,11 @@
+import './assets/main.css'
+
+import { createApp } from 'vue'
+import { createPinia } from 'pinia'
+import App from './App.vue'
+
+const app = createApp(App)
+
+app.use(createPinia())
+
+app.mount('#app')
diff --git a/playground/typescript-pinia-nightwatch/src/stores/counter.ts b/playground/typescript-pinia-nightwatch/src/stores/counter.ts
new file mode 100644
index 000000000..b6757ba57
--- /dev/null
+++ b/playground/typescript-pinia-nightwatch/src/stores/counter.ts
@@ -0,0 +1,12 @@
+import { ref, computed } from 'vue'
+import { defineStore } from 'pinia'
+
+export const useCounterStore = defineStore('counter', () => {
+ const count = ref(0)
+ const doubleCount = computed(() => count.value * 2)
+ function increment() {
+ count.value++
+ }
+
+ return { count, doubleCount, increment }
+})
diff --git a/playground/typescript-pinia-nightwatch/tests/e2e/example.ts b/playground/typescript-pinia-nightwatch/tests/e2e/example.ts
new file mode 100644
index 000000000..43be3fce1
--- /dev/null
+++ b/playground/typescript-pinia-nightwatch/tests/e2e/example.ts
@@ -0,0 +1,11 @@
+describe('My First Test', function () {
+ before((browser) => {
+ browser.init()
+ })
+
+ it('visits the app root url', function () {
+ browser.assert.textContains('.green', 'You did it!')
+ })
+
+ after((browser) => browser.end())
+})
diff --git a/playground/typescript-pinia-nightwatch/tsconfig.app.json b/playground/typescript-pinia-nightwatch/tsconfig.app.json
new file mode 100644
index 000000000..e14c754d3
--- /dev/null
+++ b/playground/typescript-pinia-nightwatch/tsconfig.app.json
@@ -0,0 +1,14 @@
+{
+ "extends": "@vue/tsconfig/tsconfig.dom.json",
+ "include": ["env.d.ts", "src/**/*", "src/**/*.vue"],
+ "exclude": ["src/**/__tests__/*"],
+ "compilerOptions": {
+ "composite": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
+
+ "baseUrl": ".",
+ "paths": {
+ "@/*": ["./src/*"]
+ }
+ }
+}
diff --git a/playground/typescript-pinia-nightwatch/tsconfig.json b/playground/typescript-pinia-nightwatch/tsconfig.json
new file mode 100644
index 000000000..5c385ae2c
--- /dev/null
+++ b/playground/typescript-pinia-nightwatch/tsconfig.json
@@ -0,0 +1,14 @@
+{
+ "files": [],
+ "references": [
+ {
+ "path": "./tsconfig.node.json"
+ },
+ {
+ "path": "./tsconfig.app.json"
+ },
+ {
+ "path": "./nightwatch/tsconfig.json"
+ }
+ ]
+}
diff --git a/playground/typescript-pinia-nightwatch/tsconfig.node.json b/playground/typescript-pinia-nightwatch/tsconfig.node.json
new file mode 100644
index 000000000..f09406303
--- /dev/null
+++ b/playground/typescript-pinia-nightwatch/tsconfig.node.json
@@ -0,0 +1,19 @@
+{
+ "extends": "@tsconfig/node20/tsconfig.json",
+ "include": [
+ "vite.config.*",
+ "vitest.config.*",
+ "cypress.config.*",
+ "nightwatch.conf.*",
+ "playwright.config.*"
+ ],
+ "compilerOptions": {
+ "composite": true,
+ "noEmit": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
+
+ "module": "ESNext",
+ "moduleResolution": "Bundler",
+ "types": ["node"]
+ }
+}
diff --git a/playground/typescript-pinia-nightwatch/vite.config.ts b/playground/typescript-pinia-nightwatch/vite.config.ts
new file mode 100644
index 000000000..fd83c5b21
--- /dev/null
+++ b/playground/typescript-pinia-nightwatch/vite.config.ts
@@ -0,0 +1,20 @@
+import { fileURLToPath, URL } from 'node:url'
+
+import { defineConfig } from 'vite'
+import vue from '@vitejs/plugin-vue'
+import nightwatchPlugin from 'vite-plugin-nightwatch'
+
+// https://vitejs.dev/config/
+export default defineConfig({
+ plugins: [
+ vue(),
+ nightwatchPlugin({
+ renderPage: './nightwatch/index.html'
+ }),
+ ],
+ resolve: {
+ alias: {
+ '@': fileURLToPath(new URL('./src', import.meta.url))
+ }
+ }
+})
diff --git a/playground/typescript-pinia-playwright/.gitignore b/playground/typescript-pinia-playwright/.gitignore
new file mode 100644
index 000000000..aef72d03c
--- /dev/null
+++ b/playground/typescript-pinia-playwright/.gitignore
@@ -0,0 +1,33 @@
+# 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/
+
+# Editor directories and files
+.vscode/*
+!.vscode/extensions.json
+.idea
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?
+
+*.tsbuildinfo
+
+test-results/
+playwright-report/
diff --git a/playground/typescript-pinia-playwright/.vscode/extensions.json b/playground/typescript-pinia-playwright/.vscode/extensions.json
new file mode 100644
index 000000000..7b3f8bdae
--- /dev/null
+++ b/playground/typescript-pinia-playwright/.vscode/extensions.json
@@ -0,0 +1,3 @@
+{
+ "recommendations": ["ms-playwright.playwright"]
+}
diff --git a/playground/typescript-pinia-playwright/README.md b/playground/typescript-pinia-playwright/README.md
new file mode 100644
index 000000000..36afc2db8
--- /dev/null
+++ b/playground/typescript-pinia-playwright/README.md
@@ -0,0 +1,59 @@
+# typescript-pinia-playwright
+
+This template should help get you started developing with Vue 3 in Vite.
+
+## Recommended IDE Setup
+
+[VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur) + [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin).
+
+## Type Support for `.vue` Imports in TS
+
+TypeScript cannot handle type information for `.vue` imports by default, so we replace the `tsc` CLI with `vue-tsc` for type checking. In editors, we need [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin) to make the TypeScript language service aware of `.vue` types.
+
+If the standalone TypeScript plugin doesn't feel fast enough to you, Volar has also implemented a [Take Over Mode](https://github.com/johnsoncodehk/volar/discussions/471#discussioncomment-1361669) that is more performant. You can enable it by the following steps:
+
+1. Disable the built-in TypeScript Extension
+ 1) Run `Extensions: Show Built-in Extensions` from VSCode's command palette
+ 2) Find `TypeScript and JavaScript Language Features`, right click and select `Disable (Workspace)`
+2. Reload the VSCode window by running `Developer: Reload Window` from the command palette.
+
+## Customize configuration
+
+See [Vite Configuration Reference](https://vitejs.dev/config/).
+
+## Project Setup
+
+```sh
+pnpm install
+```
+
+### Compile and Hot-Reload for Development
+
+```sh
+pnpm dev
+```
+
+### Type-Check, Compile and Minify for Production
+
+```sh
+pnpm build
+```
+
+### Run End-to-End Tests with [Playwright](https://playwright.dev)
+
+```sh
+# Install browsers for the first run
+npx playwright install
+
+# When testing on CI, must build the project first
+pnpm build
+
+# Runs the end-to-end tests
+pnpm test:e2e
+# Runs the tests only on Chromium
+pnpm test:e2e --project=chromium
+# Runs the tests of a specific file
+pnpm test:e2e tests/example.spec.ts
+# Runs the tests in debug mode
+pnpm test:e2e --debug
+```
diff --git a/playground/typescript-pinia-playwright/e2e/tsconfig.json b/playground/typescript-pinia-playwright/e2e/tsconfig.json
new file mode 100644
index 000000000..be3bbfc0e
--- /dev/null
+++ b/playground/typescript-pinia-playwright/e2e/tsconfig.json
@@ -0,0 +1,4 @@
+{
+ "extends": "@tsconfig/node20/tsconfig.json",
+ "include": ["./**/*"]
+}
diff --git a/playground/typescript-pinia-playwright/e2e/vue.spec.ts b/playground/typescript-pinia-playwright/e2e/vue.spec.ts
new file mode 100644
index 000000000..3e5a3d02d
--- /dev/null
+++ b/playground/typescript-pinia-playwright/e2e/vue.spec.ts
@@ -0,0 +1,8 @@
+import { test, expect } from '@playwright/test';
+
+// See here how to get started:
+// https://playwright.dev/docs/intro
+test('visits the app root url', async ({ page }) => {
+ await page.goto('/');
+ await expect(page.locator('div.greetings > h1')).toHaveText('You did it!');
+})
diff --git a/playground/typescript-pinia-playwright/env.d.ts b/playground/typescript-pinia-playwright/env.d.ts
new file mode 100644
index 000000000..11f02fe2a
--- /dev/null
+++ b/playground/typescript-pinia-playwright/env.d.ts
@@ -0,0 +1 @@
+///
diff --git a/playground/typescript-pinia-playwright/index.html b/playground/typescript-pinia-playwright/index.html
new file mode 100644
index 000000000..a88854489
--- /dev/null
+++ b/playground/typescript-pinia-playwright/index.html
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+ Vite App
+
+
+
+
+
+
diff --git a/playground/typescript-pinia-playwright/package.json b/playground/typescript-pinia-playwright/package.json
new file mode 100644
index 000000000..a02715868
--- /dev/null
+++ b/playground/typescript-pinia-playwright/package.json
@@ -0,0 +1,29 @@
+{
+ "name": "typescript-pinia-playwright",
+ "version": "0.0.0",
+ "private": true,
+ "type": "module",
+ "scripts": {
+ "dev": "vite",
+ "build": "run-p type-check \"build-only {@}\" --",
+ "preview": "vite preview",
+ "test:e2e": "playwright test",
+ "build-only": "vite build",
+ "type-check": "vue-tsc --build --force"
+ },
+ "dependencies": {
+ "pinia": "^2.1.7",
+ "vue": "^3.4.15"
+ },
+ "devDependencies": {
+ "@playwright/test": "^1.41.2",
+ "@tsconfig/node20": "^20.1.2",
+ "@types/node": "^20.11.16",
+ "@vitejs/plugin-vue": "^5.0.3",
+ "@vue/tsconfig": "^0.5.1",
+ "npm-run-all2": "^6.1.2",
+ "typescript": "~5.3.0",
+ "vite": "^5.0.11",
+ "vue-tsc": "^1.8.27"
+ }
+}
diff --git a/playground/typescript-pinia-playwright/playwright.config.ts b/playground/typescript-pinia-playwright/playwright.config.ts
new file mode 100644
index 000000000..92075cc1b
--- /dev/null
+++ b/playground/typescript-pinia-playwright/playwright.config.ts
@@ -0,0 +1,110 @@
+import process from 'node:process'
+import { defineConfig, devices } from '@playwright/test'
+
+/**
+ * Read environment variables from file.
+ * https://github.com/motdotla/dotenv
+ */
+// require('dotenv').config();
+
+/**
+ * See https://playwright.dev/docs/test-configuration.
+ */
+export default defineConfig({
+ testDir: './e2e',
+ /* Maximum time one test can run for. */
+ timeout: 30 * 1000,
+ expect: {
+ /**
+ * Maximum time expect() should wait for the condition to be met.
+ * For example in `await expect(locator).toHaveText();`
+ */
+ timeout: 5000
+ },
+ /* Fail the build on CI if you accidentally left test.only in the source code. */
+ forbidOnly: !!process.env.CI,
+ /* Retry on CI only */
+ retries: process.env.CI ? 2 : 0,
+ /* Opt out of parallel tests on CI. */
+ workers: process.env.CI ? 1 : undefined,
+ /* Reporter to use. See https://playwright.dev/docs/test-reporters */
+ reporter: 'html',
+ /* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
+ use: {
+ /* Maximum time each action such as `click()` can take. Defaults to 0 (no limit). */
+ actionTimeout: 0,
+ /* Base URL to use in actions like `await page.goto('/')`. */
+ baseURL: 'http://localhost:5173',
+
+ /* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
+ trace: 'on-first-retry',
+
+ /* Only on CI systems run the tests headless */
+ headless: !!process.env.CI
+ },
+
+ /* Configure projects for major browsers */
+ projects: [
+ {
+ name: 'chromium',
+ use: {
+ ...devices['Desktop Chrome']
+ }
+ },
+ {
+ name: 'firefox',
+ use: {
+ ...devices['Desktop Firefox']
+ }
+ },
+ {
+ name: 'webkit',
+ use: {
+ ...devices['Desktop Safari']
+ }
+ }
+
+ /* Test against mobile viewports. */
+ // {
+ // name: 'Mobile Chrome',
+ // use: {
+ // ...devices['Pixel 5'],
+ // },
+ // },
+ // {
+ // name: 'Mobile Safari',
+ // use: {
+ // ...devices['iPhone 12'],
+ // },
+ // },
+
+ /* Test against branded browsers. */
+ // {
+ // name: 'Microsoft Edge',
+ // use: {
+ // channel: 'msedge',
+ // },
+ // },
+ // {
+ // name: 'Google Chrome',
+ // use: {
+ // channel: 'chrome',
+ // },
+ // },
+ ],
+
+ /* Folder for test artifacts such as screenshots, videos, traces, etc. */
+ // outputDir: 'test-results/',
+
+ /* Run your local dev server before starting the tests */
+ webServer: {
+ /**
+ * Use the dev server by default for faster feedback loop.
+ * Use the preview server on CI for more realistic testing.
+ * Playwright will re-use the local server if there is already a dev-server running.
+ */
+ command: process.env.CI ? 'vite preview --port 5173' : 'vite dev',
+ port: 5173,
+ reuseExistingServer: !process.env.CI
+ }
+})
diff --git a/playground/typescript-pinia-playwright/public/favicon.ico b/playground/typescript-pinia-playwright/public/favicon.ico
new file mode 100644
index 000000000..df36fcfb7
Binary files /dev/null and b/playground/typescript-pinia-playwright/public/favicon.ico differ
diff --git a/playground/typescript-pinia-playwright/src/App.vue b/playground/typescript-pinia-playwright/src/App.vue
new file mode 100644
index 000000000..69f32f91f
--- /dev/null
+++ b/playground/typescript-pinia-playwright/src/App.vue
@@ -0,0 +1,10 @@
+
+ app
+
+
+
+
+
diff --git a/playground/typescript-pinia-playwright/src/assets/logo.svg b/playground/typescript-pinia-playwright/src/assets/logo.svg
new file mode 100644
index 000000000..756566035
--- /dev/null
+++ b/playground/typescript-pinia-playwright/src/assets/logo.svg
@@ -0,0 +1 @@
+
diff --git a/playground/typescript-pinia-playwright/src/assets/main.css b/playground/typescript-pinia-playwright/src/assets/main.css
new file mode 100644
index 000000000..5aadc6ceb
--- /dev/null
+++ b/playground/typescript-pinia-playwright/src/assets/main.css
@@ -0,0 +1,6 @@
+html, body, #app {
+ width: 100%;
+ height: 100%;
+ padding: 0;
+ margin: 0;
+}
diff --git a/playground/typescript-pinia-playwright/src/main.ts b/playground/typescript-pinia-playwright/src/main.ts
new file mode 100644
index 000000000..48dad4313
--- /dev/null
+++ b/playground/typescript-pinia-playwright/src/main.ts
@@ -0,0 +1,11 @@
+import './assets/main.css'
+
+import { createApp } from 'vue'
+import { createPinia } from 'pinia'
+import App from './App.vue'
+
+const app = createApp(App)
+
+app.use(createPinia())
+
+app.mount('#app')
diff --git a/playground/typescript-pinia-playwright/src/stores/counter.ts b/playground/typescript-pinia-playwright/src/stores/counter.ts
new file mode 100644
index 000000000..b6757ba57
--- /dev/null
+++ b/playground/typescript-pinia-playwright/src/stores/counter.ts
@@ -0,0 +1,12 @@
+import { ref, computed } from 'vue'
+import { defineStore } from 'pinia'
+
+export const useCounterStore = defineStore('counter', () => {
+ const count = ref(0)
+ const doubleCount = computed(() => count.value * 2)
+ function increment() {
+ count.value++
+ }
+
+ return { count, doubleCount, increment }
+})
diff --git a/playground/typescript-pinia-playwright/tsconfig.app.json b/playground/typescript-pinia-playwright/tsconfig.app.json
new file mode 100644
index 000000000..e14c754d3
--- /dev/null
+++ b/playground/typescript-pinia-playwright/tsconfig.app.json
@@ -0,0 +1,14 @@
+{
+ "extends": "@vue/tsconfig/tsconfig.dom.json",
+ "include": ["env.d.ts", "src/**/*", "src/**/*.vue"],
+ "exclude": ["src/**/__tests__/*"],
+ "compilerOptions": {
+ "composite": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
+
+ "baseUrl": ".",
+ "paths": {
+ "@/*": ["./src/*"]
+ }
+ }
+}
diff --git a/playground/typescript-pinia-playwright/tsconfig.json b/playground/typescript-pinia-playwright/tsconfig.json
new file mode 100644
index 000000000..66b5e5703
--- /dev/null
+++ b/playground/typescript-pinia-playwright/tsconfig.json
@@ -0,0 +1,11 @@
+{
+ "files": [],
+ "references": [
+ {
+ "path": "./tsconfig.node.json"
+ },
+ {
+ "path": "./tsconfig.app.json"
+ }
+ ]
+}
diff --git a/playground/typescript-pinia-playwright/tsconfig.node.json b/playground/typescript-pinia-playwright/tsconfig.node.json
new file mode 100644
index 000000000..f09406303
--- /dev/null
+++ b/playground/typescript-pinia-playwright/tsconfig.node.json
@@ -0,0 +1,19 @@
+{
+ "extends": "@tsconfig/node20/tsconfig.json",
+ "include": [
+ "vite.config.*",
+ "vitest.config.*",
+ "cypress.config.*",
+ "nightwatch.conf.*",
+ "playwright.config.*"
+ ],
+ "compilerOptions": {
+ "composite": true,
+ "noEmit": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
+
+ "module": "ESNext",
+ "moduleResolution": "Bundler",
+ "types": ["node"]
+ }
+}
diff --git a/playground/typescript-pinia-playwright/vite.config.ts b/playground/typescript-pinia-playwright/vite.config.ts
new file mode 100644
index 000000000..5c45e1d9b
--- /dev/null
+++ b/playground/typescript-pinia-playwright/vite.config.ts
@@ -0,0 +1,16 @@
+import { fileURLToPath, URL } from 'node:url'
+
+import { defineConfig } from 'vite'
+import vue from '@vitejs/plugin-vue'
+
+// https://vitejs.dev/config/
+export default defineConfig({
+ plugins: [
+ vue(),
+ ],
+ resolve: {
+ alias: {
+ '@': fileURLToPath(new URL('./src', import.meta.url))
+ }
+ }
+})
diff --git a/playground/typescript-pinia-vitest-cypress/.gitignore b/playground/typescript-pinia-vitest-cypress/.gitignore
new file mode 100644
index 000000000..8ee54e8d3
--- /dev/null
+++ b/playground/typescript-pinia-vitest-cypress/.gitignore
@@ -0,0 +1,30 @@
+# 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/
+
+# Editor directories and files
+.vscode/*
+!.vscode/extensions.json
+.idea
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?
+
+*.tsbuildinfo
diff --git a/playground/typescript-pinia-vitest-cypress/README.md b/playground/typescript-pinia-vitest-cypress/README.md
new file mode 100644
index 000000000..0fede194f
--- /dev/null
+++ b/playground/typescript-pinia-vitest-cypress/README.md
@@ -0,0 +1,62 @@
+# typescript-pinia-vitest-cypress
+
+This template should help get you started developing with Vue 3 in Vite.
+
+## Recommended IDE Setup
+
+[VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur) + [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin).
+
+## Type Support for `.vue` Imports in TS
+
+TypeScript cannot handle type information for `.vue` imports by default, so we replace the `tsc` CLI with `vue-tsc` for type checking. In editors, we need [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin) to make the TypeScript language service aware of `.vue` types.
+
+If the standalone TypeScript plugin doesn't feel fast enough to you, Volar has also implemented a [Take Over Mode](https://github.com/johnsoncodehk/volar/discussions/471#discussioncomment-1361669) that is more performant. You can enable it by the following steps:
+
+1. Disable the built-in TypeScript Extension
+ 1) Run `Extensions: Show Built-in Extensions` from VSCode's command palette
+ 2) Find `TypeScript and JavaScript Language Features`, right click and select `Disable (Workspace)`
+2. Reload the VSCode window by running `Developer: Reload Window` from the command palette.
+
+## Customize configuration
+
+See [Vite Configuration Reference](https://vitejs.dev/config/).
+
+## Project Setup
+
+```sh
+pnpm install
+```
+
+### Compile and Hot-Reload for Development
+
+```sh
+pnpm dev
+```
+
+### Type-Check, Compile and Minify for Production
+
+```sh
+pnpm build
+```
+
+### Run Unit Tests with [Vitest](https://vitest.dev/)
+
+```sh
+pnpm test:unit
+```
+
+### Run End-to-End Tests with [Cypress](https://www.cypress.io/)
+
+```sh
+pnpm test:e2e:dev
+```
+
+This runs the end-to-end tests against the Vite development server.
+It is much faster than the production build.
+
+But it's still recommended to test the production build with `test:e2e` before deploying (e.g. in CI environments):
+
+```sh
+pnpm build
+pnpm test:e2e
+```
diff --git a/playground/typescript-pinia-vitest-cypress/cypress.config.ts b/playground/typescript-pinia-vitest-cypress/cypress.config.ts
new file mode 100644
index 000000000..0f66080fd
--- /dev/null
+++ b/playground/typescript-pinia-vitest-cypress/cypress.config.ts
@@ -0,0 +1,8 @@
+import { defineConfig } from 'cypress'
+
+export default defineConfig({
+ e2e: {
+ specPattern: 'cypress/e2e/**/*.{cy,spec}.{js,jsx,ts,tsx}',
+ baseUrl: 'http://localhost:4173'
+ }
+})
diff --git a/playground/typescript-pinia-vitest-cypress/cypress/e2e/example.cy.ts b/playground/typescript-pinia-vitest-cypress/cypress/e2e/example.cy.ts
new file mode 100644
index 000000000..7554c35d8
--- /dev/null
+++ b/playground/typescript-pinia-vitest-cypress/cypress/e2e/example.cy.ts
@@ -0,0 +1,8 @@
+// https://on.cypress.io/api
+
+describe('My First Test', () => {
+ it('visits the app root url', () => {
+ cy.visit('/')
+ cy.contains('h1', 'You did it!')
+ })
+})
diff --git a/playground/typescript-pinia-vitest-cypress/cypress/e2e/tsconfig.json b/playground/typescript-pinia-vitest-cypress/cypress/e2e/tsconfig.json
new file mode 100644
index 000000000..37748feb7
--- /dev/null
+++ b/playground/typescript-pinia-vitest-cypress/cypress/e2e/tsconfig.json
@@ -0,0 +1,10 @@
+{
+ "extends": "@vue/tsconfig/tsconfig.dom.json",
+ "include": ["./**/*", "../support/**/*"],
+ "compilerOptions": {
+ "isolatedModules": false,
+ "target": "es5",
+ "lib": ["es5", "dom"],
+ "types": ["cypress"]
+ }
+}
diff --git a/playground/typescript-pinia-vitest-cypress/cypress/fixtures/example.json b/playground/typescript-pinia-vitest-cypress/cypress/fixtures/example.json
new file mode 100644
index 000000000..02e425437
--- /dev/null
+++ b/playground/typescript-pinia-vitest-cypress/cypress/fixtures/example.json
@@ -0,0 +1,5 @@
+{
+ "name": "Using fixtures to represent data",
+ "email": "hello@cypress.io",
+ "body": "Fixtures are a great way to mock data for responses to routes"
+}
diff --git a/playground/typescript-pinia-vitest-cypress/cypress/support/commands.ts b/playground/typescript-pinia-vitest-cypress/cypress/support/commands.ts
new file mode 100644
index 000000000..9b7bb8e25
--- /dev/null
+++ b/playground/typescript-pinia-vitest-cypress/cypress/support/commands.ts
@@ -0,0 +1,39 @@
+///
+// ***********************************************
+// This example commands.ts shows you how to
+// create various custom commands and overwrite
+// existing commands.
+//
+// For more comprehensive examples of custom
+// commands please read more here:
+// https://on.cypress.io/custom-commands
+// ***********************************************
+//
+//
+// -- This is a parent command --
+// Cypress.Commands.add('login', (email, password) => { ... })
+//
+//
+// -- This is a child command --
+// Cypress.Commands.add('drag', { prevSubject: 'element'}, (subject, options) => { ... })
+//
+//
+// -- This is a dual command --
+// Cypress.Commands.add('dismiss', { prevSubject: 'optional'}, (subject, options) => { ... })
+//
+//
+// -- This will overwrite an existing command --
+// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... })
+//
+// declare global {
+// namespace Cypress {
+// interface Chainable {
+// login(email: string, password: string): Chainable
+// drag(subject: string, options?: Partial): Chainable
+// dismiss(subject: string, options?: Partial): Chainable
+// visit(originalFn: CommandOriginalFn, url: string, options: Partial): Chainable
+// }
+// }
+// }
+
+export {}
diff --git a/playground/typescript-pinia-vitest-cypress/cypress/support/e2e.ts b/playground/typescript-pinia-vitest-cypress/cypress/support/e2e.ts
new file mode 100644
index 000000000..d68db96df
--- /dev/null
+++ b/playground/typescript-pinia-vitest-cypress/cypress/support/e2e.ts
@@ -0,0 +1,20 @@
+// ***********************************************************
+// This example support/index.js is processed and
+// loaded automatically before your test files.
+//
+// This is a great place to put global configuration and
+// behavior that modifies Cypress.
+//
+// You can change the location of this file or turn off
+// automatically serving support files with the
+// 'supportFile' configuration option.
+//
+// You can read more here:
+// https://on.cypress.io/configuration
+// ***********************************************************
+
+// Import commands.js using ES2015 syntax:
+import './commands'
+
+// Alternatively you can use CommonJS syntax:
+// require('./commands')
diff --git a/playground/typescript-pinia-vitest-cypress/env.d.ts b/playground/typescript-pinia-vitest-cypress/env.d.ts
new file mode 100644
index 000000000..11f02fe2a
--- /dev/null
+++ b/playground/typescript-pinia-vitest-cypress/env.d.ts
@@ -0,0 +1 @@
+///
diff --git a/playground/typescript-pinia-vitest-cypress/index.html b/playground/typescript-pinia-vitest-cypress/index.html
new file mode 100644
index 000000000..a88854489
--- /dev/null
+++ b/playground/typescript-pinia-vitest-cypress/index.html
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+ Vite App
+
+
+
+
+
+
diff --git a/playground/typescript-pinia-vitest-cypress/package.json b/playground/typescript-pinia-vitest-cypress/package.json
new file mode 100644
index 000000000..cd128b695
--- /dev/null
+++ b/playground/typescript-pinia-vitest-cypress/package.json
@@ -0,0 +1,36 @@
+{
+ "name": "typescript-pinia-vitest-cypress",
+ "version": "0.0.0",
+ "private": true,
+ "type": "module",
+ "scripts": {
+ "dev": "vite",
+ "build": "run-p type-check \"build-only {@}\" --",
+ "preview": "vite preview",
+ "test:unit": "vitest",
+ "test:e2e": "start-server-and-test preview http://localhost:4173 'cypress run --e2e'",
+ "test:e2e:dev": "start-server-and-test 'vite dev --port 4173' http://localhost:4173 'cypress open --e2e'",
+ "build-only": "vite build",
+ "type-check": "vue-tsc --build --force"
+ },
+ "dependencies": {
+ "pinia": "^2.1.7",
+ "vue": "^3.4.15"
+ },
+ "devDependencies": {
+ "@tsconfig/node20": "^20.1.2",
+ "@types/jsdom": "^21.1.6",
+ "@types/node": "^20.11.16",
+ "@vitejs/plugin-vue": "^5.0.3",
+ "@vue/test-utils": "^2.4.4",
+ "@vue/tsconfig": "^0.5.1",
+ "cypress": "^13.6.4",
+ "jsdom": "^24.0.0",
+ "npm-run-all2": "^6.1.2",
+ "start-server-and-test": "^2.0.3",
+ "typescript": "~5.3.0",
+ "vite": "^5.0.11",
+ "vitest": "^1.2.2",
+ "vue-tsc": "^1.8.27"
+ }
+}
diff --git a/playground/typescript-pinia-vitest-cypress/public/favicon.ico b/playground/typescript-pinia-vitest-cypress/public/favicon.ico
new file mode 100644
index 000000000..df36fcfb7
Binary files /dev/null and b/playground/typescript-pinia-vitest-cypress/public/favicon.ico differ
diff --git a/playground/typescript-pinia-vitest-cypress/src/App.vue b/playground/typescript-pinia-vitest-cypress/src/App.vue
new file mode 100644
index 000000000..69f32f91f
--- /dev/null
+++ b/playground/typescript-pinia-vitest-cypress/src/App.vue
@@ -0,0 +1,10 @@
+
+ app
+
+
+
+
+
diff --git a/playground/typescript-pinia-vitest-cypress/src/assets/logo.svg b/playground/typescript-pinia-vitest-cypress/src/assets/logo.svg
new file mode 100644
index 000000000..756566035
--- /dev/null
+++ b/playground/typescript-pinia-vitest-cypress/src/assets/logo.svg
@@ -0,0 +1 @@
+
diff --git a/playground/typescript-pinia-vitest-cypress/src/assets/main.css b/playground/typescript-pinia-vitest-cypress/src/assets/main.css
new file mode 100644
index 000000000..5aadc6ceb
--- /dev/null
+++ b/playground/typescript-pinia-vitest-cypress/src/assets/main.css
@@ -0,0 +1,6 @@
+html, body, #app {
+ width: 100%;
+ height: 100%;
+ padding: 0;
+ margin: 0;
+}
diff --git a/playground/typescript-pinia-vitest-cypress/src/components/__tests__/HelloWorld.spec.ts b/playground/typescript-pinia-vitest-cypress/src/components/__tests__/HelloWorld.spec.ts
new file mode 100644
index 000000000..253320200
--- /dev/null
+++ b/playground/typescript-pinia-vitest-cypress/src/components/__tests__/HelloWorld.spec.ts
@@ -0,0 +1,11 @@
+import { describe, it, expect } from 'vitest'
+
+import { mount } from '@vue/test-utils'
+import HelloWorld from '../HelloWorld.vue'
+
+describe('HelloWorld', () => {
+ it('renders properly', () => {
+ const wrapper = mount(HelloWorld, { props: { msg: 'Hello Vitest' } })
+ expect(wrapper.text()).toContain('Hello Vitest')
+ })
+})
diff --git a/playground/typescript-pinia-vitest-cypress/src/main.ts b/playground/typescript-pinia-vitest-cypress/src/main.ts
new file mode 100644
index 000000000..48dad4313
--- /dev/null
+++ b/playground/typescript-pinia-vitest-cypress/src/main.ts
@@ -0,0 +1,11 @@
+import './assets/main.css'
+
+import { createApp } from 'vue'
+import { createPinia } from 'pinia'
+import App from './App.vue'
+
+const app = createApp(App)
+
+app.use(createPinia())
+
+app.mount('#app')
diff --git a/playground/typescript-pinia-vitest-cypress/src/stores/counter.ts b/playground/typescript-pinia-vitest-cypress/src/stores/counter.ts
new file mode 100644
index 000000000..b6757ba57
--- /dev/null
+++ b/playground/typescript-pinia-vitest-cypress/src/stores/counter.ts
@@ -0,0 +1,12 @@
+import { ref, computed } from 'vue'
+import { defineStore } from 'pinia'
+
+export const useCounterStore = defineStore('counter', () => {
+ const count = ref(0)
+ const doubleCount = computed(() => count.value * 2)
+ function increment() {
+ count.value++
+ }
+
+ return { count, doubleCount, increment }
+})
diff --git a/playground/typescript-pinia-vitest-cypress/tsconfig.app.json b/playground/typescript-pinia-vitest-cypress/tsconfig.app.json
new file mode 100644
index 000000000..e14c754d3
--- /dev/null
+++ b/playground/typescript-pinia-vitest-cypress/tsconfig.app.json
@@ -0,0 +1,14 @@
+{
+ "extends": "@vue/tsconfig/tsconfig.dom.json",
+ "include": ["env.d.ts", "src/**/*", "src/**/*.vue"],
+ "exclude": ["src/**/__tests__/*"],
+ "compilerOptions": {
+ "composite": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
+
+ "baseUrl": ".",
+ "paths": {
+ "@/*": ["./src/*"]
+ }
+ }
+}
diff --git a/playground/typescript-pinia-vitest-cypress/tsconfig.json b/playground/typescript-pinia-vitest-cypress/tsconfig.json
new file mode 100644
index 000000000..5304731b8
--- /dev/null
+++ b/playground/typescript-pinia-vitest-cypress/tsconfig.json
@@ -0,0 +1,17 @@
+{
+ "files": [],
+ "references": [
+ {
+ "path": "./tsconfig.node.json"
+ },
+ {
+ "path": "./tsconfig.app.json"
+ },
+ {
+ "path": "./tsconfig.vitest.json"
+ }
+ ],
+ "compilerOptions": {
+ "module": "NodeNext"
+ }
+}
diff --git a/playground/typescript-pinia-vitest-cypress/tsconfig.node.json b/playground/typescript-pinia-vitest-cypress/tsconfig.node.json
new file mode 100644
index 000000000..f09406303
--- /dev/null
+++ b/playground/typescript-pinia-vitest-cypress/tsconfig.node.json
@@ -0,0 +1,19 @@
+{
+ "extends": "@tsconfig/node20/tsconfig.json",
+ "include": [
+ "vite.config.*",
+ "vitest.config.*",
+ "cypress.config.*",
+ "nightwatch.conf.*",
+ "playwright.config.*"
+ ],
+ "compilerOptions": {
+ "composite": true,
+ "noEmit": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
+
+ "module": "ESNext",
+ "moduleResolution": "Bundler",
+ "types": ["node"]
+ }
+}
diff --git a/playground/typescript-pinia-vitest-cypress/tsconfig.vitest.json b/playground/typescript-pinia-vitest-cypress/tsconfig.vitest.json
new file mode 100644
index 000000000..571995d11
--- /dev/null
+++ b/playground/typescript-pinia-vitest-cypress/tsconfig.vitest.json
@@ -0,0 +1,11 @@
+{
+ "extends": "./tsconfig.app.json",
+ "exclude": [],
+ "compilerOptions": {
+ "composite": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.vitest.tsbuildinfo",
+
+ "lib": [],
+ "types": ["node", "jsdom"]
+ }
+}
diff --git a/playground/typescript-pinia-vitest-cypress/vite.config.ts b/playground/typescript-pinia-vitest-cypress/vite.config.ts
new file mode 100644
index 000000000..5c45e1d9b
--- /dev/null
+++ b/playground/typescript-pinia-vitest-cypress/vite.config.ts
@@ -0,0 +1,16 @@
+import { fileURLToPath, URL } from 'node:url'
+
+import { defineConfig } from 'vite'
+import vue from '@vitejs/plugin-vue'
+
+// https://vitejs.dev/config/
+export default defineConfig({
+ plugins: [
+ vue(),
+ ],
+ resolve: {
+ alias: {
+ '@': fileURLToPath(new URL('./src', import.meta.url))
+ }
+ }
+})
diff --git a/playground/typescript-pinia-vitest-cypress/vitest.config.ts b/playground/typescript-pinia-vitest-cypress/vitest.config.ts
new file mode 100644
index 000000000..10067d578
--- /dev/null
+++ b/playground/typescript-pinia-vitest-cypress/vitest.config.ts
@@ -0,0 +1,14 @@
+import { fileURLToPath } from 'node:url'
+import { mergeConfig, defineConfig, configDefaults } from 'vitest/config'
+import viteConfig from './vite.config'
+
+export default mergeConfig(
+ viteConfig,
+ defineConfig({
+ test: {
+ environment: 'jsdom',
+ exclude: [...configDefaults.exclude, 'e2e/*'],
+ root: fileURLToPath(new URL('./', import.meta.url))
+ }
+ })
+)
diff --git a/playground/typescript-pinia-vitest-nightwatch/.gitignore b/playground/typescript-pinia-vitest-nightwatch/.gitignore
new file mode 100644
index 000000000..0b938f131
--- /dev/null
+++ b/playground/typescript-pinia-vitest-nightwatch/.gitignore
@@ -0,0 +1,33 @@
+# 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/
+
+# Editor directories and files
+.vscode/*
+!.vscode/extensions.json
+.idea
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?
+
+*.tsbuildinfo
+
+logs/
+tests_output/
diff --git a/playground/typescript-pinia-vitest-nightwatch/.vscode/extensions.json b/playground/typescript-pinia-vitest-nightwatch/.vscode/extensions.json
new file mode 100644
index 000000000..dd9668a5c
--- /dev/null
+++ b/playground/typescript-pinia-vitest-nightwatch/.vscode/extensions.json
@@ -0,0 +1,3 @@
+{
+ "recommendations": ["browserstackcom.nightwatch"]
+}
diff --git a/playground/typescript-pinia-vitest-nightwatch/README.md b/playground/typescript-pinia-vitest-nightwatch/README.md
new file mode 100644
index 000000000..70e40463e
--- /dev/null
+++ b/playground/typescript-pinia-vitest-nightwatch/README.md
@@ -0,0 +1,69 @@
+# typescript-pinia-vitest-nightwatch
+
+This template should help get you started developing with Vue 3 in Vite.
+
+## Recommended IDE Setup
+
+[VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur) + [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin).
+
+## Type Support for `.vue` Imports in TS
+
+TypeScript cannot handle type information for `.vue` imports by default, so we replace the `tsc` CLI with `vue-tsc` for type checking. In editors, we need [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin) to make the TypeScript language service aware of `.vue` types.
+
+If the standalone TypeScript plugin doesn't feel fast enough to you, Volar has also implemented a [Take Over Mode](https://github.com/johnsoncodehk/volar/discussions/471#discussioncomment-1361669) that is more performant. You can enable it by the following steps:
+
+1. Disable the built-in TypeScript Extension
+ 1) Run `Extensions: Show Built-in Extensions` from VSCode's command palette
+ 2) Find `TypeScript and JavaScript Language Features`, right click and select `Disable (Workspace)`
+2. Reload the VSCode window by running `Developer: Reload Window` from the command palette.
+
+## Customize configuration
+
+See [Vite Configuration Reference](https://vitejs.dev/config/).
+
+## Project Setup
+
+```sh
+pnpm install
+```
+
+### Compile and Hot-Reload for Development
+
+```sh
+pnpm dev
+```
+
+### Type-Check, Compile and Minify for Production
+
+```sh
+pnpm build
+```
+
+### Run Unit Tests with [Vitest](https://vitest.dev/)
+
+```sh
+pnpm test:unit
+```
+
+### Run End-to-End Tests with [Nightwatch](https://nightwatchjs.org/)
+
+```sh
+# When using CI, the project must be built first.
+pnpm build
+
+# Runs the end-to-end tests
+pnpm test:e2e
+# Runs the tests only on Chrome
+pnpm test:e2e --env chrome
+# Runs the tests of a specific file
+pnpm test:e2e tests/e2e/example.ts
+# Runs the tests in debug mode
+pnpm test:e2e --debug
+```
+
+### Run Headed Component Tests with [Nightwatch Component Testing](https://nightwatchjs.org/guide/component-testing/introduction.html)
+
+```sh
+pnpm test:unit
+pnpm test:unit -- --headless # for headless testing
+```
diff --git a/playground/typescript-pinia-vitest-nightwatch/env.d.ts b/playground/typescript-pinia-vitest-nightwatch/env.d.ts
new file mode 100644
index 000000000..11f02fe2a
--- /dev/null
+++ b/playground/typescript-pinia-vitest-nightwatch/env.d.ts
@@ -0,0 +1 @@
+///
diff --git a/playground/typescript-pinia-vitest-nightwatch/index.html b/playground/typescript-pinia-vitest-nightwatch/index.html
new file mode 100644
index 000000000..a88854489
--- /dev/null
+++ b/playground/typescript-pinia-vitest-nightwatch/index.html
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+ Vite App
+
+
+
+
+
+
diff --git a/playground/typescript-pinia-vitest-nightwatch/nightwatch.conf.cjs b/playground/typescript-pinia-vitest-nightwatch/nightwatch.conf.cjs
new file mode 100644
index 000000000..542647e5e
--- /dev/null
+++ b/playground/typescript-pinia-vitest-nightwatch/nightwatch.conf.cjs
@@ -0,0 +1,153 @@
+//
+// Refer to the online docs for more details:
+// https://nightwatchjs.org/guide/configuration/nightwatch-configuration-file.html
+//
+// _ _ _ _ _ _ _
+// | \ | |(_) | | | | | | | |
+// | \| | _ __ _ | |__ | |_ __ __ __ _ | |_ ___ | |__
+// | . ` || | / _` || '_ \ | __|\ \ /\ / / / _` || __| / __|| '_ \
+// | |\ || || (_| || | | || |_ \ V V / | (_| || |_ | (__ | | | |
+// \_| \_/|_| \__, ||_| |_| \__| \_/\_/ \__,_| \__| \___||_| |_|
+// __/ |
+// |___/
+//
+
+module.exports = {
+ // An array of folders (excluding subfolders) where your tests are located;
+ // if this is not specified, the test source must be passed as the second argument to the test runner.
+ src_folders: [],
+
+ // See https://nightwatchjs.org/guide/concepts/page-object-model.html
+ page_objects_path: [],
+
+ // See https://nightwatchjs.org/guide/extending-nightwatch/adding-custom-commands.html
+ custom_commands_path: [],
+
+ // See https://nightwatchjs.org/guide/extending-nightwatch/adding-custom-assertions.html
+ custom_assertions_path: [],
+
+ // See https://nightwatchjs.org/guide/extending-nightwatch/adding-plugins.html
+ plugins: ['@nightwatch/vue'],
+
+ // See https://nightwatchjs.org/guide/concepts/test-globals.html#external-test-globals
+ globals_path: '',
+
+ vite_dev_server: {
+ start_vite: true,
+ port: process.env.CI ? 4173 : 5173
+ },
+
+ webdriver: {},
+
+ test_workers: {
+ enabled: true,
+ workers: 'auto'
+ },
+
+ test_settings: {
+ default: {
+ disable_error_log: false,
+ launch_url: `http://localhost:${process.env.CI ? '4173' : '5173'}`,
+
+ screenshots: {
+ enabled: false,
+ path: 'screens',
+ on_failure: true
+ },
+
+ desiredCapabilities: {
+ browserName: 'firefox'
+ },
+
+ webdriver: {
+ start_process: true,
+ server_path: ''
+ }
+ },
+
+ safari: {
+ desiredCapabilities: {
+ browserName: 'safari',
+ alwaysMatch: {
+ acceptInsecureCerts: false
+ }
+ },
+ webdriver: {
+ start_process: true,
+ server_path: ''
+ }
+ },
+
+ firefox: {
+ desiredCapabilities: {
+ browserName: 'firefox',
+ alwaysMatch: {
+ acceptInsecureCerts: true,
+ 'moz:firefoxOptions': {
+ args: [
+ // '-headless',
+ // '-verbose'
+ ]
+ }
+ }
+ },
+ webdriver: {
+ start_process: true,
+ server_path: '',
+ cli_args: [
+ // very verbose geckodriver logs
+ // '-vv'
+ ]
+ }
+ },
+
+ chrome: {
+ desiredCapabilities: {
+ browserName: 'chrome',
+ 'goog:chromeOptions': {
+ // More info on Chromedriver: https://sites.google.com/a/chromium.org/chromedriver/
+ //
+ // w3c:false tells Chromedriver to run using the legacy JSONWire protocol (not required in Chrome 78)
+ w3c: true,
+ args: [
+ //'--no-sandbox',
+ //'--ignore-certificate-errors',
+ //'--allow-insecure-localhost',
+ //'--headless'
+ ]
+ }
+ },
+
+ webdriver: {
+ start_process: true,
+ server_path: '',
+ cli_args: [
+ // --verbose
+ ]
+ }
+ },
+
+ edge: {
+ desiredCapabilities: {
+ browserName: 'MicrosoftEdge',
+ 'ms:edgeOptions': {
+ w3c: true,
+ // More info on EdgeDriver: https://docs.microsoft.com/en-us/microsoft-edge/webdriver-chromium/capabilities-edge-options
+ args: [
+ //'--headless'
+ ]
+ }
+ },
+
+ webdriver: {
+ start_process: true,
+ // Download msedgedriver from https://docs.microsoft.com/en-us/microsoft-edge/webdriver-chromium/
+ // and set the location below:
+ server_path: '',
+ cli_args: [
+ // --verbose
+ ]
+ }
+ }
+ }
+}
diff --git a/playground/typescript-pinia-vitest-nightwatch/nightwatch/nightwatch.d.ts b/playground/typescript-pinia-vitest-nightwatch/nightwatch/nightwatch.d.ts
new file mode 100644
index 000000000..616e63f9f
--- /dev/null
+++ b/playground/typescript-pinia-vitest-nightwatch/nightwatch/nightwatch.d.ts
@@ -0,0 +1,13 @@
+import { NightwatchCustomAssertions, NightwatchCustomCommands } from 'nightwatch'
+
+declare module 'nightwatch' {
+ interface NightwatchCustomAssertions {
+ // Add your custom assertions' types here
+ // elementHasCount: (selector: string, count: number) => NightwatchBrowser
+ }
+
+ interface NightwatchCustomCommands {
+ // Add your custom commands' types here
+ // strictClick: (selector: string) => NightwatchBrowser
+ }
+}
diff --git a/playground/typescript-pinia-vitest-nightwatch/nightwatch/tsconfig.json b/playground/typescript-pinia-vitest-nightwatch/nightwatch/tsconfig.json
new file mode 100644
index 000000000..8cd7ca1da
--- /dev/null
+++ b/playground/typescript-pinia-vitest-nightwatch/nightwatch/tsconfig.json
@@ -0,0 +1,20 @@
+{
+ "extends": "@tsconfig/node20/tsconfig.json",
+ "compilerOptions": {
+ "composite": true,
+ "noEmit": true,
+ "tsBuildInfoFile": "../node_modules/.tmp/tsconfig.nightwatch.tsbuildinfo",
+
+ "target": "ESNext",
+ "module": "commonjs",
+ "moduleResolution": "node",
+ "rootDir": "../",
+ "lib": ["ESNext", "dom"],
+ "types": ["nightwatch"]
+ },
+ "include": ["../node_modules/@nightwatch/**/*", "../src/components/**/*", "../tests/e2e/**/*"],
+ "ts-node": {
+ "transpileOnly": true
+ },
+ "files": ["nightwatch.d.ts"]
+}
diff --git a/playground/typescript-pinia-vitest-nightwatch/package.json b/playground/typescript-pinia-vitest-nightwatch/package.json
new file mode 100644
index 000000000..a4884aad2
--- /dev/null
+++ b/playground/typescript-pinia-vitest-nightwatch/package.json
@@ -0,0 +1,39 @@
+{
+ "name": "typescript-pinia-vitest-nightwatch",
+ "version": "0.0.0",
+ "private": true,
+ "type": "module",
+ "scripts": {
+ "dev": "vite",
+ "build": "run-p type-check \"build-only {@}\" --",
+ "preview": "vite preview",
+ "test:unit": "vitest",
+ "test:e2e": "nightwatch tests/e2e/*",
+ "build-only": "vite build",
+ "type-check": "vue-tsc --build --force"
+ },
+ "dependencies": {
+ "pinia": "^2.1.7",
+ "vue": "^3.4.15"
+ },
+ "devDependencies": {
+ "@nightwatch/vue": "^3.1.0",
+ "@tsconfig/node20": "^20.1.2",
+ "@types/jsdom": "^21.1.6",
+ "@types/node": "^20.11.16",
+ "@vitejs/plugin-vue": "^5.0.3",
+ "@vue/test-utils": "^2.4.4",
+ "@vue/tsconfig": "^0.5.1",
+ "chromedriver": "^121.0.0",
+ "geckodriver": "^4.3.2",
+ "jsdom": "^24.0.0",
+ "nightwatch": "^3.4.0",
+ "npm-run-all2": "^6.1.2",
+ "ts-node": "^10.9.2",
+ "typescript": "~5.3.0",
+ "vite": "^5.0.11",
+ "vite-plugin-nightwatch": "^0.4.6",
+ "vitest": "^1.2.2",
+ "vue-tsc": "^1.8.27"
+ }
+}
diff --git a/playground/typescript-pinia-vitest-nightwatch/public/favicon.ico b/playground/typescript-pinia-vitest-nightwatch/public/favicon.ico
new file mode 100644
index 000000000..df36fcfb7
Binary files /dev/null and b/playground/typescript-pinia-vitest-nightwatch/public/favicon.ico differ
diff --git a/playground/typescript-pinia-vitest-nightwatch/src/App.vue b/playground/typescript-pinia-vitest-nightwatch/src/App.vue
new file mode 100644
index 000000000..69f32f91f
--- /dev/null
+++ b/playground/typescript-pinia-vitest-nightwatch/src/App.vue
@@ -0,0 +1,10 @@
+
+ app
+
+
+
+
+
diff --git a/playground/typescript-pinia-vitest-nightwatch/src/assets/logo.svg b/playground/typescript-pinia-vitest-nightwatch/src/assets/logo.svg
new file mode 100644
index 000000000..756566035
--- /dev/null
+++ b/playground/typescript-pinia-vitest-nightwatch/src/assets/logo.svg
@@ -0,0 +1 @@
+
diff --git a/playground/typescript-pinia-vitest-nightwatch/src/assets/main.css b/playground/typescript-pinia-vitest-nightwatch/src/assets/main.css
new file mode 100644
index 000000000..5aadc6ceb
--- /dev/null
+++ b/playground/typescript-pinia-vitest-nightwatch/src/assets/main.css
@@ -0,0 +1,6 @@
+html, body, #app {
+ width: 100%;
+ height: 100%;
+ padding: 0;
+ margin: 0;
+}
diff --git a/playground/typescript-pinia-vitest-nightwatch/src/components/__tests__/HelloWorld.spec.ts b/playground/typescript-pinia-vitest-nightwatch/src/components/__tests__/HelloWorld.spec.ts
new file mode 100644
index 000000000..253320200
--- /dev/null
+++ b/playground/typescript-pinia-vitest-nightwatch/src/components/__tests__/HelloWorld.spec.ts
@@ -0,0 +1,11 @@
+import { describe, it, expect } from 'vitest'
+
+import { mount } from '@vue/test-utils'
+import HelloWorld from '../HelloWorld.vue'
+
+describe('HelloWorld', () => {
+ it('renders properly', () => {
+ const wrapper = mount(HelloWorld, { props: { msg: 'Hello Vitest' } })
+ expect(wrapper.text()).toContain('Hello Vitest')
+ })
+})
diff --git a/playground/typescript-pinia-vitest-nightwatch/src/main.ts b/playground/typescript-pinia-vitest-nightwatch/src/main.ts
new file mode 100644
index 000000000..48dad4313
--- /dev/null
+++ b/playground/typescript-pinia-vitest-nightwatch/src/main.ts
@@ -0,0 +1,11 @@
+import './assets/main.css'
+
+import { createApp } from 'vue'
+import { createPinia } from 'pinia'
+import App from './App.vue'
+
+const app = createApp(App)
+
+app.use(createPinia())
+
+app.mount('#app')
diff --git a/playground/typescript-pinia-vitest-nightwatch/src/stores/counter.ts b/playground/typescript-pinia-vitest-nightwatch/src/stores/counter.ts
new file mode 100644
index 000000000..b6757ba57
--- /dev/null
+++ b/playground/typescript-pinia-vitest-nightwatch/src/stores/counter.ts
@@ -0,0 +1,12 @@
+import { ref, computed } from 'vue'
+import { defineStore } from 'pinia'
+
+export const useCounterStore = defineStore('counter', () => {
+ const count = ref(0)
+ const doubleCount = computed(() => count.value * 2)
+ function increment() {
+ count.value++
+ }
+
+ return { count, doubleCount, increment }
+})
diff --git a/playground/typescript-pinia-vitest-nightwatch/tests/e2e/example.ts b/playground/typescript-pinia-vitest-nightwatch/tests/e2e/example.ts
new file mode 100644
index 000000000..43be3fce1
--- /dev/null
+++ b/playground/typescript-pinia-vitest-nightwatch/tests/e2e/example.ts
@@ -0,0 +1,11 @@
+describe('My First Test', function () {
+ before((browser) => {
+ browser.init()
+ })
+
+ it('visits the app root url', function () {
+ browser.assert.textContains('.green', 'You did it!')
+ })
+
+ after((browser) => browser.end())
+})
diff --git a/playground/typescript-pinia-vitest-nightwatch/tsconfig.app.json b/playground/typescript-pinia-vitest-nightwatch/tsconfig.app.json
new file mode 100644
index 000000000..e14c754d3
--- /dev/null
+++ b/playground/typescript-pinia-vitest-nightwatch/tsconfig.app.json
@@ -0,0 +1,14 @@
+{
+ "extends": "@vue/tsconfig/tsconfig.dom.json",
+ "include": ["env.d.ts", "src/**/*", "src/**/*.vue"],
+ "exclude": ["src/**/__tests__/*"],
+ "compilerOptions": {
+ "composite": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
+
+ "baseUrl": ".",
+ "paths": {
+ "@/*": ["./src/*"]
+ }
+ }
+}
diff --git a/playground/typescript-pinia-vitest-nightwatch/tsconfig.json b/playground/typescript-pinia-vitest-nightwatch/tsconfig.json
new file mode 100644
index 000000000..a5352e667
--- /dev/null
+++ b/playground/typescript-pinia-vitest-nightwatch/tsconfig.json
@@ -0,0 +1,17 @@
+{
+ "files": [],
+ "references": [
+ {
+ "path": "./tsconfig.node.json"
+ },
+ {
+ "path": "./tsconfig.app.json"
+ },
+ {
+ "path": "./tsconfig.vitest.json"
+ },
+ {
+ "path": "./nightwatch/tsconfig.json"
+ }
+ ]
+}
diff --git a/playground/typescript-pinia-vitest-nightwatch/tsconfig.node.json b/playground/typescript-pinia-vitest-nightwatch/tsconfig.node.json
new file mode 100644
index 000000000..f09406303
--- /dev/null
+++ b/playground/typescript-pinia-vitest-nightwatch/tsconfig.node.json
@@ -0,0 +1,19 @@
+{
+ "extends": "@tsconfig/node20/tsconfig.json",
+ "include": [
+ "vite.config.*",
+ "vitest.config.*",
+ "cypress.config.*",
+ "nightwatch.conf.*",
+ "playwright.config.*"
+ ],
+ "compilerOptions": {
+ "composite": true,
+ "noEmit": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
+
+ "module": "ESNext",
+ "moduleResolution": "Bundler",
+ "types": ["node"]
+ }
+}
diff --git a/playground/typescript-pinia-vitest-nightwatch/tsconfig.vitest.json b/playground/typescript-pinia-vitest-nightwatch/tsconfig.vitest.json
new file mode 100644
index 000000000..571995d11
--- /dev/null
+++ b/playground/typescript-pinia-vitest-nightwatch/tsconfig.vitest.json
@@ -0,0 +1,11 @@
+{
+ "extends": "./tsconfig.app.json",
+ "exclude": [],
+ "compilerOptions": {
+ "composite": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.vitest.tsbuildinfo",
+
+ "lib": [],
+ "types": ["node", "jsdom"]
+ }
+}
diff --git a/playground/typescript-pinia-vitest-nightwatch/vite.config.ts b/playground/typescript-pinia-vitest-nightwatch/vite.config.ts
new file mode 100644
index 000000000..be3cb9c57
--- /dev/null
+++ b/playground/typescript-pinia-vitest-nightwatch/vite.config.ts
@@ -0,0 +1,18 @@
+import { fileURLToPath, URL } from 'node:url'
+
+import { defineConfig } from 'vite'
+import vue from '@vitejs/plugin-vue'
+import nightwatchPlugin from 'vite-plugin-nightwatch'
+
+// https://vitejs.dev/config/
+export default defineConfig({
+ plugins: [
+ vue(),
+ nightwatchPlugin(),
+ ],
+ resolve: {
+ alias: {
+ '@': fileURLToPath(new URL('./src', import.meta.url))
+ }
+ }
+})
diff --git a/playground/typescript-pinia-vitest-nightwatch/vitest.config.ts b/playground/typescript-pinia-vitest-nightwatch/vitest.config.ts
new file mode 100644
index 000000000..10067d578
--- /dev/null
+++ b/playground/typescript-pinia-vitest-nightwatch/vitest.config.ts
@@ -0,0 +1,14 @@
+import { fileURLToPath } from 'node:url'
+import { mergeConfig, defineConfig, configDefaults } from 'vitest/config'
+import viteConfig from './vite.config'
+
+export default mergeConfig(
+ viteConfig,
+ defineConfig({
+ test: {
+ environment: 'jsdom',
+ exclude: [...configDefaults.exclude, 'e2e/*'],
+ root: fileURLToPath(new URL('./', import.meta.url))
+ }
+ })
+)
diff --git a/playground/typescript-pinia-vitest-playwright/.gitignore b/playground/typescript-pinia-vitest-playwright/.gitignore
new file mode 100644
index 000000000..aef72d03c
--- /dev/null
+++ b/playground/typescript-pinia-vitest-playwright/.gitignore
@@ -0,0 +1,33 @@
+# 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/
+
+# Editor directories and files
+.vscode/*
+!.vscode/extensions.json
+.idea
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?
+
+*.tsbuildinfo
+
+test-results/
+playwright-report/
diff --git a/playground/typescript-pinia-vitest-playwright/.vscode/extensions.json b/playground/typescript-pinia-vitest-playwright/.vscode/extensions.json
new file mode 100644
index 000000000..7b3f8bdae
--- /dev/null
+++ b/playground/typescript-pinia-vitest-playwright/.vscode/extensions.json
@@ -0,0 +1,3 @@
+{
+ "recommendations": ["ms-playwright.playwright"]
+}
diff --git a/playground/typescript-pinia-vitest-playwright/README.md b/playground/typescript-pinia-vitest-playwright/README.md
new file mode 100644
index 000000000..5d406ee51
--- /dev/null
+++ b/playground/typescript-pinia-vitest-playwright/README.md
@@ -0,0 +1,65 @@
+# typescript-pinia-vitest-playwright
+
+This template should help get you started developing with Vue 3 in Vite.
+
+## Recommended IDE Setup
+
+[VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur) + [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin).
+
+## Type Support for `.vue` Imports in TS
+
+TypeScript cannot handle type information for `.vue` imports by default, so we replace the `tsc` CLI with `vue-tsc` for type checking. In editors, we need [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin) to make the TypeScript language service aware of `.vue` types.
+
+If the standalone TypeScript plugin doesn't feel fast enough to you, Volar has also implemented a [Take Over Mode](https://github.com/johnsoncodehk/volar/discussions/471#discussioncomment-1361669) that is more performant. You can enable it by the following steps:
+
+1. Disable the built-in TypeScript Extension
+ 1) Run `Extensions: Show Built-in Extensions` from VSCode's command palette
+ 2) Find `TypeScript and JavaScript Language Features`, right click and select `Disable (Workspace)`
+2. Reload the VSCode window by running `Developer: Reload Window` from the command palette.
+
+## Customize configuration
+
+See [Vite Configuration Reference](https://vitejs.dev/config/).
+
+## Project Setup
+
+```sh
+pnpm install
+```
+
+### Compile and Hot-Reload for Development
+
+```sh
+pnpm dev
+```
+
+### Type-Check, Compile and Minify for Production
+
+```sh
+pnpm build
+```
+
+### Run Unit Tests with [Vitest](https://vitest.dev/)
+
+```sh
+pnpm test:unit
+```
+
+### Run End-to-End Tests with [Playwright](https://playwright.dev)
+
+```sh
+# Install browsers for the first run
+npx playwright install
+
+# When testing on CI, must build the project first
+pnpm build
+
+# Runs the end-to-end tests
+pnpm test:e2e
+# Runs the tests only on Chromium
+pnpm test:e2e --project=chromium
+# Runs the tests of a specific file
+pnpm test:e2e tests/example.spec.ts
+# Runs the tests in debug mode
+pnpm test:e2e --debug
+```
diff --git a/playground/typescript-pinia-vitest-playwright/e2e/tsconfig.json b/playground/typescript-pinia-vitest-playwright/e2e/tsconfig.json
new file mode 100644
index 000000000..be3bbfc0e
--- /dev/null
+++ b/playground/typescript-pinia-vitest-playwright/e2e/tsconfig.json
@@ -0,0 +1,4 @@
+{
+ "extends": "@tsconfig/node20/tsconfig.json",
+ "include": ["./**/*"]
+}
diff --git a/playground/typescript-pinia-vitest-playwright/e2e/vue.spec.ts b/playground/typescript-pinia-vitest-playwright/e2e/vue.spec.ts
new file mode 100644
index 000000000..3e5a3d02d
--- /dev/null
+++ b/playground/typescript-pinia-vitest-playwright/e2e/vue.spec.ts
@@ -0,0 +1,8 @@
+import { test, expect } from '@playwright/test';
+
+// See here how to get started:
+// https://playwright.dev/docs/intro
+test('visits the app root url', async ({ page }) => {
+ await page.goto('/');
+ await expect(page.locator('div.greetings > h1')).toHaveText('You did it!');
+})
diff --git a/playground/typescript-pinia-vitest-playwright/env.d.ts b/playground/typescript-pinia-vitest-playwright/env.d.ts
new file mode 100644
index 000000000..11f02fe2a
--- /dev/null
+++ b/playground/typescript-pinia-vitest-playwright/env.d.ts
@@ -0,0 +1 @@
+///
diff --git a/playground/typescript-pinia-vitest-playwright/index.html b/playground/typescript-pinia-vitest-playwright/index.html
new file mode 100644
index 000000000..a88854489
--- /dev/null
+++ b/playground/typescript-pinia-vitest-playwright/index.html
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+ Vite App
+
+
+
+
+
+
diff --git a/playground/typescript-pinia-vitest-playwright/package.json b/playground/typescript-pinia-vitest-playwright/package.json
new file mode 100644
index 000000000..2c67fd655
--- /dev/null
+++ b/playground/typescript-pinia-vitest-playwright/package.json
@@ -0,0 +1,34 @@
+{
+ "name": "typescript-pinia-vitest-playwright",
+ "version": "0.0.0",
+ "private": true,
+ "type": "module",
+ "scripts": {
+ "dev": "vite",
+ "build": "run-p type-check \"build-only {@}\" --",
+ "preview": "vite preview",
+ "test:unit": "vitest",
+ "test:e2e": "playwright test",
+ "build-only": "vite build",
+ "type-check": "vue-tsc --build --force"
+ },
+ "dependencies": {
+ "pinia": "^2.1.7",
+ "vue": "^3.4.15"
+ },
+ "devDependencies": {
+ "@playwright/test": "^1.41.2",
+ "@tsconfig/node20": "^20.1.2",
+ "@types/jsdom": "^21.1.6",
+ "@types/node": "^20.11.16",
+ "@vitejs/plugin-vue": "^5.0.3",
+ "@vue/test-utils": "^2.4.4",
+ "@vue/tsconfig": "^0.5.1",
+ "jsdom": "^24.0.0",
+ "npm-run-all2": "^6.1.2",
+ "typescript": "~5.3.0",
+ "vite": "^5.0.11",
+ "vitest": "^1.2.2",
+ "vue-tsc": "^1.8.27"
+ }
+}
diff --git a/playground/typescript-pinia-vitest-playwright/playwright.config.ts b/playground/typescript-pinia-vitest-playwright/playwright.config.ts
new file mode 100644
index 000000000..92075cc1b
--- /dev/null
+++ b/playground/typescript-pinia-vitest-playwright/playwright.config.ts
@@ -0,0 +1,110 @@
+import process from 'node:process'
+import { defineConfig, devices } from '@playwright/test'
+
+/**
+ * Read environment variables from file.
+ * https://github.com/motdotla/dotenv
+ */
+// require('dotenv').config();
+
+/**
+ * See https://playwright.dev/docs/test-configuration.
+ */
+export default defineConfig({
+ testDir: './e2e',
+ /* Maximum time one test can run for. */
+ timeout: 30 * 1000,
+ expect: {
+ /**
+ * Maximum time expect() should wait for the condition to be met.
+ * For example in `await expect(locator).toHaveText();`
+ */
+ timeout: 5000
+ },
+ /* Fail the build on CI if you accidentally left test.only in the source code. */
+ forbidOnly: !!process.env.CI,
+ /* Retry on CI only */
+ retries: process.env.CI ? 2 : 0,
+ /* Opt out of parallel tests on CI. */
+ workers: process.env.CI ? 1 : undefined,
+ /* Reporter to use. See https://playwright.dev/docs/test-reporters */
+ reporter: 'html',
+ /* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
+ use: {
+ /* Maximum time each action such as `click()` can take. Defaults to 0 (no limit). */
+ actionTimeout: 0,
+ /* Base URL to use in actions like `await page.goto('/')`. */
+ baseURL: 'http://localhost:5173',
+
+ /* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
+ trace: 'on-first-retry',
+
+ /* Only on CI systems run the tests headless */
+ headless: !!process.env.CI
+ },
+
+ /* Configure projects for major browsers */
+ projects: [
+ {
+ name: 'chromium',
+ use: {
+ ...devices['Desktop Chrome']
+ }
+ },
+ {
+ name: 'firefox',
+ use: {
+ ...devices['Desktop Firefox']
+ }
+ },
+ {
+ name: 'webkit',
+ use: {
+ ...devices['Desktop Safari']
+ }
+ }
+
+ /* Test against mobile viewports. */
+ // {
+ // name: 'Mobile Chrome',
+ // use: {
+ // ...devices['Pixel 5'],
+ // },
+ // },
+ // {
+ // name: 'Mobile Safari',
+ // use: {
+ // ...devices['iPhone 12'],
+ // },
+ // },
+
+ /* Test against branded browsers. */
+ // {
+ // name: 'Microsoft Edge',
+ // use: {
+ // channel: 'msedge',
+ // },
+ // },
+ // {
+ // name: 'Google Chrome',
+ // use: {
+ // channel: 'chrome',
+ // },
+ // },
+ ],
+
+ /* Folder for test artifacts such as screenshots, videos, traces, etc. */
+ // outputDir: 'test-results/',
+
+ /* Run your local dev server before starting the tests */
+ webServer: {
+ /**
+ * Use the dev server by default for faster feedback loop.
+ * Use the preview server on CI for more realistic testing.
+ * Playwright will re-use the local server if there is already a dev-server running.
+ */
+ command: process.env.CI ? 'vite preview --port 5173' : 'vite dev',
+ port: 5173,
+ reuseExistingServer: !process.env.CI
+ }
+})
diff --git a/playground/typescript-pinia-vitest-playwright/public/favicon.ico b/playground/typescript-pinia-vitest-playwright/public/favicon.ico
new file mode 100644
index 000000000..df36fcfb7
Binary files /dev/null and b/playground/typescript-pinia-vitest-playwright/public/favicon.ico differ
diff --git a/playground/typescript-pinia-vitest-playwright/src/App.vue b/playground/typescript-pinia-vitest-playwright/src/App.vue
new file mode 100644
index 000000000..69f32f91f
--- /dev/null
+++ b/playground/typescript-pinia-vitest-playwright/src/App.vue
@@ -0,0 +1,10 @@
+
+ app
+
+
+
+
+
diff --git a/playground/typescript-pinia-vitest-playwright/src/assets/logo.svg b/playground/typescript-pinia-vitest-playwright/src/assets/logo.svg
new file mode 100644
index 000000000..756566035
--- /dev/null
+++ b/playground/typescript-pinia-vitest-playwright/src/assets/logo.svg
@@ -0,0 +1 @@
+
diff --git a/playground/typescript-pinia-vitest-playwright/src/assets/main.css b/playground/typescript-pinia-vitest-playwright/src/assets/main.css
new file mode 100644
index 000000000..5aadc6ceb
--- /dev/null
+++ b/playground/typescript-pinia-vitest-playwright/src/assets/main.css
@@ -0,0 +1,6 @@
+html, body, #app {
+ width: 100%;
+ height: 100%;
+ padding: 0;
+ margin: 0;
+}
diff --git a/playground/typescript-pinia-vitest-playwright/src/components/__tests__/HelloWorld.spec.ts b/playground/typescript-pinia-vitest-playwright/src/components/__tests__/HelloWorld.spec.ts
new file mode 100644
index 000000000..253320200
--- /dev/null
+++ b/playground/typescript-pinia-vitest-playwright/src/components/__tests__/HelloWorld.spec.ts
@@ -0,0 +1,11 @@
+import { describe, it, expect } from 'vitest'
+
+import { mount } from '@vue/test-utils'
+import HelloWorld from '../HelloWorld.vue'
+
+describe('HelloWorld', () => {
+ it('renders properly', () => {
+ const wrapper = mount(HelloWorld, { props: { msg: 'Hello Vitest' } })
+ expect(wrapper.text()).toContain('Hello Vitest')
+ })
+})
diff --git a/playground/typescript-pinia-vitest-playwright/src/main.ts b/playground/typescript-pinia-vitest-playwright/src/main.ts
new file mode 100644
index 000000000..48dad4313
--- /dev/null
+++ b/playground/typescript-pinia-vitest-playwright/src/main.ts
@@ -0,0 +1,11 @@
+import './assets/main.css'
+
+import { createApp } from 'vue'
+import { createPinia } from 'pinia'
+import App from './App.vue'
+
+const app = createApp(App)
+
+app.use(createPinia())
+
+app.mount('#app')
diff --git a/playground/typescript-pinia-vitest-playwright/src/stores/counter.ts b/playground/typescript-pinia-vitest-playwright/src/stores/counter.ts
new file mode 100644
index 000000000..b6757ba57
--- /dev/null
+++ b/playground/typescript-pinia-vitest-playwright/src/stores/counter.ts
@@ -0,0 +1,12 @@
+import { ref, computed } from 'vue'
+import { defineStore } from 'pinia'
+
+export const useCounterStore = defineStore('counter', () => {
+ const count = ref(0)
+ const doubleCount = computed(() => count.value * 2)
+ function increment() {
+ count.value++
+ }
+
+ return { count, doubleCount, increment }
+})
diff --git a/playground/typescript-pinia-vitest-playwright/tsconfig.app.json b/playground/typescript-pinia-vitest-playwright/tsconfig.app.json
new file mode 100644
index 000000000..e14c754d3
--- /dev/null
+++ b/playground/typescript-pinia-vitest-playwright/tsconfig.app.json
@@ -0,0 +1,14 @@
+{
+ "extends": "@vue/tsconfig/tsconfig.dom.json",
+ "include": ["env.d.ts", "src/**/*", "src/**/*.vue"],
+ "exclude": ["src/**/__tests__/*"],
+ "compilerOptions": {
+ "composite": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
+
+ "baseUrl": ".",
+ "paths": {
+ "@/*": ["./src/*"]
+ }
+ }
+}
diff --git a/playground/typescript-pinia-vitest-playwright/tsconfig.json b/playground/typescript-pinia-vitest-playwright/tsconfig.json
new file mode 100644
index 000000000..100cf6a8f
--- /dev/null
+++ b/playground/typescript-pinia-vitest-playwright/tsconfig.json
@@ -0,0 +1,14 @@
+{
+ "files": [],
+ "references": [
+ {
+ "path": "./tsconfig.node.json"
+ },
+ {
+ "path": "./tsconfig.app.json"
+ },
+ {
+ "path": "./tsconfig.vitest.json"
+ }
+ ]
+}
diff --git a/playground/typescript-pinia-vitest-playwright/tsconfig.node.json b/playground/typescript-pinia-vitest-playwright/tsconfig.node.json
new file mode 100644
index 000000000..f09406303
--- /dev/null
+++ b/playground/typescript-pinia-vitest-playwright/tsconfig.node.json
@@ -0,0 +1,19 @@
+{
+ "extends": "@tsconfig/node20/tsconfig.json",
+ "include": [
+ "vite.config.*",
+ "vitest.config.*",
+ "cypress.config.*",
+ "nightwatch.conf.*",
+ "playwright.config.*"
+ ],
+ "compilerOptions": {
+ "composite": true,
+ "noEmit": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
+
+ "module": "ESNext",
+ "moduleResolution": "Bundler",
+ "types": ["node"]
+ }
+}
diff --git a/playground/typescript-pinia-vitest-playwright/tsconfig.vitest.json b/playground/typescript-pinia-vitest-playwright/tsconfig.vitest.json
new file mode 100644
index 000000000..571995d11
--- /dev/null
+++ b/playground/typescript-pinia-vitest-playwright/tsconfig.vitest.json
@@ -0,0 +1,11 @@
+{
+ "extends": "./tsconfig.app.json",
+ "exclude": [],
+ "compilerOptions": {
+ "composite": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.vitest.tsbuildinfo",
+
+ "lib": [],
+ "types": ["node", "jsdom"]
+ }
+}
diff --git a/playground/typescript-pinia-vitest-playwright/vite.config.ts b/playground/typescript-pinia-vitest-playwright/vite.config.ts
new file mode 100644
index 000000000..5c45e1d9b
--- /dev/null
+++ b/playground/typescript-pinia-vitest-playwright/vite.config.ts
@@ -0,0 +1,16 @@
+import { fileURLToPath, URL } from 'node:url'
+
+import { defineConfig } from 'vite'
+import vue from '@vitejs/plugin-vue'
+
+// https://vitejs.dev/config/
+export default defineConfig({
+ plugins: [
+ vue(),
+ ],
+ resolve: {
+ alias: {
+ '@': fileURLToPath(new URL('./src', import.meta.url))
+ }
+ }
+})
diff --git a/playground/typescript-pinia-vitest-playwright/vitest.config.ts b/playground/typescript-pinia-vitest-playwright/vitest.config.ts
new file mode 100644
index 000000000..10067d578
--- /dev/null
+++ b/playground/typescript-pinia-vitest-playwright/vitest.config.ts
@@ -0,0 +1,14 @@
+import { fileURLToPath } from 'node:url'
+import { mergeConfig, defineConfig, configDefaults } from 'vitest/config'
+import viteConfig from './vite.config'
+
+export default mergeConfig(
+ viteConfig,
+ defineConfig({
+ test: {
+ environment: 'jsdom',
+ exclude: [...configDefaults.exclude, 'e2e/*'],
+ root: fileURLToPath(new URL('./', import.meta.url))
+ }
+ })
+)
diff --git a/playground/typescript-pinia-vitest/.gitignore b/playground/typescript-pinia-vitest/.gitignore
new file mode 100644
index 000000000..8ee54e8d3
--- /dev/null
+++ b/playground/typescript-pinia-vitest/.gitignore
@@ -0,0 +1,30 @@
+# 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/
+
+# Editor directories and files
+.vscode/*
+!.vscode/extensions.json
+.idea
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?
+
+*.tsbuildinfo
diff --git a/playground/typescript-pinia-vitest/README.md b/playground/typescript-pinia-vitest/README.md
new file mode 100644
index 000000000..fbe43309a
--- /dev/null
+++ b/playground/typescript-pinia-vitest/README.md
@@ -0,0 +1,46 @@
+# typescript-pinia-vitest
+
+This template should help get you started developing with Vue 3 in Vite.
+
+## Recommended IDE Setup
+
+[VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur) + [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin).
+
+## Type Support for `.vue` Imports in TS
+
+TypeScript cannot handle type information for `.vue` imports by default, so we replace the `tsc` CLI with `vue-tsc` for type checking. In editors, we need [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin) to make the TypeScript language service aware of `.vue` types.
+
+If the standalone TypeScript plugin doesn't feel fast enough to you, Volar has also implemented a [Take Over Mode](https://github.com/johnsoncodehk/volar/discussions/471#discussioncomment-1361669) that is more performant. You can enable it by the following steps:
+
+1. Disable the built-in TypeScript Extension
+ 1) Run `Extensions: Show Built-in Extensions` from VSCode's command palette
+ 2) Find `TypeScript and JavaScript Language Features`, right click and select `Disable (Workspace)`
+2. Reload the VSCode window by running `Developer: Reload Window` from the command palette.
+
+## Customize configuration
+
+See [Vite Configuration Reference](https://vitejs.dev/config/).
+
+## Project Setup
+
+```sh
+pnpm install
+```
+
+### Compile and Hot-Reload for Development
+
+```sh
+pnpm dev
+```
+
+### Type-Check, Compile and Minify for Production
+
+```sh
+pnpm build
+```
+
+### Run Unit Tests with [Vitest](https://vitest.dev/)
+
+```sh
+pnpm test:unit
+```
diff --git a/playground/typescript-pinia-vitest/env.d.ts b/playground/typescript-pinia-vitest/env.d.ts
new file mode 100644
index 000000000..11f02fe2a
--- /dev/null
+++ b/playground/typescript-pinia-vitest/env.d.ts
@@ -0,0 +1 @@
+///
diff --git a/playground/typescript-pinia-vitest/index.html b/playground/typescript-pinia-vitest/index.html
new file mode 100644
index 000000000..a88854489
--- /dev/null
+++ b/playground/typescript-pinia-vitest/index.html
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+ Vite App
+
+
+
+
+
+
diff --git a/playground/typescript-pinia-vitest/package.json b/playground/typescript-pinia-vitest/package.json
new file mode 100644
index 000000000..7cec5ff5a
--- /dev/null
+++ b/playground/typescript-pinia-vitest/package.json
@@ -0,0 +1,32 @@
+{
+ "name": "typescript-pinia-vitest",
+ "version": "0.0.0",
+ "private": true,
+ "type": "module",
+ "scripts": {
+ "dev": "vite",
+ "build": "run-p type-check \"build-only {@}\" --",
+ "preview": "vite preview",
+ "test:unit": "vitest",
+ "build-only": "vite build",
+ "type-check": "vue-tsc --build --force"
+ },
+ "dependencies": {
+ "pinia": "^2.1.7",
+ "vue": "^3.4.15"
+ },
+ "devDependencies": {
+ "@tsconfig/node20": "^20.1.2",
+ "@types/jsdom": "^21.1.6",
+ "@types/node": "^20.11.16",
+ "@vitejs/plugin-vue": "^5.0.3",
+ "@vue/test-utils": "^2.4.4",
+ "@vue/tsconfig": "^0.5.1",
+ "jsdom": "^24.0.0",
+ "npm-run-all2": "^6.1.2",
+ "typescript": "~5.3.0",
+ "vite": "^5.0.11",
+ "vitest": "^1.2.2",
+ "vue-tsc": "^1.8.27"
+ }
+}
diff --git a/playground/typescript-pinia-vitest/public/favicon.ico b/playground/typescript-pinia-vitest/public/favicon.ico
new file mode 100644
index 000000000..df36fcfb7
Binary files /dev/null and b/playground/typescript-pinia-vitest/public/favicon.ico differ
diff --git a/playground/typescript-pinia-vitest/src/App.vue b/playground/typescript-pinia-vitest/src/App.vue
new file mode 100644
index 000000000..69f32f91f
--- /dev/null
+++ b/playground/typescript-pinia-vitest/src/App.vue
@@ -0,0 +1,10 @@
+
+ app
+
+
+
+
+
diff --git a/playground/typescript-pinia-vitest/src/assets/logo.svg b/playground/typescript-pinia-vitest/src/assets/logo.svg
new file mode 100644
index 000000000..756566035
--- /dev/null
+++ b/playground/typescript-pinia-vitest/src/assets/logo.svg
@@ -0,0 +1 @@
+
diff --git a/playground/typescript-pinia-vitest/src/assets/main.css b/playground/typescript-pinia-vitest/src/assets/main.css
new file mode 100644
index 000000000..5aadc6ceb
--- /dev/null
+++ b/playground/typescript-pinia-vitest/src/assets/main.css
@@ -0,0 +1,6 @@
+html, body, #app {
+ width: 100%;
+ height: 100%;
+ padding: 0;
+ margin: 0;
+}
diff --git a/playground/typescript-pinia-vitest/src/components/__tests__/HelloWorld.spec.ts b/playground/typescript-pinia-vitest/src/components/__tests__/HelloWorld.spec.ts
new file mode 100644
index 000000000..253320200
--- /dev/null
+++ b/playground/typescript-pinia-vitest/src/components/__tests__/HelloWorld.spec.ts
@@ -0,0 +1,11 @@
+import { describe, it, expect } from 'vitest'
+
+import { mount } from '@vue/test-utils'
+import HelloWorld from '../HelloWorld.vue'
+
+describe('HelloWorld', () => {
+ it('renders properly', () => {
+ const wrapper = mount(HelloWorld, { props: { msg: 'Hello Vitest' } })
+ expect(wrapper.text()).toContain('Hello Vitest')
+ })
+})
diff --git a/playground/typescript-pinia-vitest/src/main.ts b/playground/typescript-pinia-vitest/src/main.ts
new file mode 100644
index 000000000..48dad4313
--- /dev/null
+++ b/playground/typescript-pinia-vitest/src/main.ts
@@ -0,0 +1,11 @@
+import './assets/main.css'
+
+import { createApp } from 'vue'
+import { createPinia } from 'pinia'
+import App from './App.vue'
+
+const app = createApp(App)
+
+app.use(createPinia())
+
+app.mount('#app')
diff --git a/playground/typescript-pinia-vitest/src/stores/counter.ts b/playground/typescript-pinia-vitest/src/stores/counter.ts
new file mode 100644
index 000000000..b6757ba57
--- /dev/null
+++ b/playground/typescript-pinia-vitest/src/stores/counter.ts
@@ -0,0 +1,12 @@
+import { ref, computed } from 'vue'
+import { defineStore } from 'pinia'
+
+export const useCounterStore = defineStore('counter', () => {
+ const count = ref(0)
+ const doubleCount = computed(() => count.value * 2)
+ function increment() {
+ count.value++
+ }
+
+ return { count, doubleCount, increment }
+})
diff --git a/playground/typescript-pinia-vitest/tsconfig.app.json b/playground/typescript-pinia-vitest/tsconfig.app.json
new file mode 100644
index 000000000..e14c754d3
--- /dev/null
+++ b/playground/typescript-pinia-vitest/tsconfig.app.json
@@ -0,0 +1,14 @@
+{
+ "extends": "@vue/tsconfig/tsconfig.dom.json",
+ "include": ["env.d.ts", "src/**/*", "src/**/*.vue"],
+ "exclude": ["src/**/__tests__/*"],
+ "compilerOptions": {
+ "composite": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
+
+ "baseUrl": ".",
+ "paths": {
+ "@/*": ["./src/*"]
+ }
+ }
+}
diff --git a/playground/typescript-pinia-vitest/tsconfig.json b/playground/typescript-pinia-vitest/tsconfig.json
new file mode 100644
index 000000000..100cf6a8f
--- /dev/null
+++ b/playground/typescript-pinia-vitest/tsconfig.json
@@ -0,0 +1,14 @@
+{
+ "files": [],
+ "references": [
+ {
+ "path": "./tsconfig.node.json"
+ },
+ {
+ "path": "./tsconfig.app.json"
+ },
+ {
+ "path": "./tsconfig.vitest.json"
+ }
+ ]
+}
diff --git a/playground/typescript-pinia-vitest/tsconfig.node.json b/playground/typescript-pinia-vitest/tsconfig.node.json
new file mode 100644
index 000000000..f09406303
--- /dev/null
+++ b/playground/typescript-pinia-vitest/tsconfig.node.json
@@ -0,0 +1,19 @@
+{
+ "extends": "@tsconfig/node20/tsconfig.json",
+ "include": [
+ "vite.config.*",
+ "vitest.config.*",
+ "cypress.config.*",
+ "nightwatch.conf.*",
+ "playwright.config.*"
+ ],
+ "compilerOptions": {
+ "composite": true,
+ "noEmit": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
+
+ "module": "ESNext",
+ "moduleResolution": "Bundler",
+ "types": ["node"]
+ }
+}
diff --git a/playground/typescript-pinia-vitest/tsconfig.vitest.json b/playground/typescript-pinia-vitest/tsconfig.vitest.json
new file mode 100644
index 000000000..571995d11
--- /dev/null
+++ b/playground/typescript-pinia-vitest/tsconfig.vitest.json
@@ -0,0 +1,11 @@
+{
+ "extends": "./tsconfig.app.json",
+ "exclude": [],
+ "compilerOptions": {
+ "composite": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.vitest.tsbuildinfo",
+
+ "lib": [],
+ "types": ["node", "jsdom"]
+ }
+}
diff --git a/playground/typescript-pinia-vitest/vite.config.ts b/playground/typescript-pinia-vitest/vite.config.ts
new file mode 100644
index 000000000..5c45e1d9b
--- /dev/null
+++ b/playground/typescript-pinia-vitest/vite.config.ts
@@ -0,0 +1,16 @@
+import { fileURLToPath, URL } from 'node:url'
+
+import { defineConfig } from 'vite'
+import vue from '@vitejs/plugin-vue'
+
+// https://vitejs.dev/config/
+export default defineConfig({
+ plugins: [
+ vue(),
+ ],
+ resolve: {
+ alias: {
+ '@': fileURLToPath(new URL('./src', import.meta.url))
+ }
+ }
+})
diff --git a/playground/typescript-pinia-vitest/vitest.config.ts b/playground/typescript-pinia-vitest/vitest.config.ts
new file mode 100644
index 000000000..10067d578
--- /dev/null
+++ b/playground/typescript-pinia-vitest/vitest.config.ts
@@ -0,0 +1,14 @@
+import { fileURLToPath } from 'node:url'
+import { mergeConfig, defineConfig, configDefaults } from 'vitest/config'
+import viteConfig from './vite.config'
+
+export default mergeConfig(
+ viteConfig,
+ defineConfig({
+ test: {
+ environment: 'jsdom',
+ exclude: [...configDefaults.exclude, 'e2e/*'],
+ root: fileURLToPath(new URL('./', import.meta.url))
+ }
+ })
+)
diff --git a/playground/typescript-pinia-with-tests/.gitignore b/playground/typescript-pinia-with-tests/.gitignore
new file mode 100644
index 000000000..8ee54e8d3
--- /dev/null
+++ b/playground/typescript-pinia-with-tests/.gitignore
@@ -0,0 +1,30 @@
+# 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/
+
+# Editor directories and files
+.vscode/*
+!.vscode/extensions.json
+.idea
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?
+
+*.tsbuildinfo
diff --git a/playground/typescript-pinia-with-tests/README.md b/playground/typescript-pinia-with-tests/README.md
new file mode 100644
index 000000000..6dea2f95a
--- /dev/null
+++ b/playground/typescript-pinia-with-tests/README.md
@@ -0,0 +1,62 @@
+# typescript-pinia-with-tests
+
+This template should help get you started developing with Vue 3 in Vite.
+
+## Recommended IDE Setup
+
+[VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur) + [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin).
+
+## Type Support for `.vue` Imports in TS
+
+TypeScript cannot handle type information for `.vue` imports by default, so we replace the `tsc` CLI with `vue-tsc` for type checking. In editors, we need [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin) to make the TypeScript language service aware of `.vue` types.
+
+If the standalone TypeScript plugin doesn't feel fast enough to you, Volar has also implemented a [Take Over Mode](https://github.com/johnsoncodehk/volar/discussions/471#discussioncomment-1361669) that is more performant. You can enable it by the following steps:
+
+1. Disable the built-in TypeScript Extension
+ 1) Run `Extensions: Show Built-in Extensions` from VSCode's command palette
+ 2) Find `TypeScript and JavaScript Language Features`, right click and select `Disable (Workspace)`
+2. Reload the VSCode window by running `Developer: Reload Window` from the command palette.
+
+## Customize configuration
+
+See [Vite Configuration Reference](https://vitejs.dev/config/).
+
+## Project Setup
+
+```sh
+pnpm install
+```
+
+### Compile and Hot-Reload for Development
+
+```sh
+pnpm dev
+```
+
+### Type-Check, Compile and Minify for Production
+
+```sh
+pnpm build
+```
+
+### Run Unit Tests with [Vitest](https://vitest.dev/)
+
+```sh
+pnpm test:unit
+```
+
+### Run End-to-End Tests with [Cypress](https://www.cypress.io/)
+
+```sh
+pnpm test:e2e:dev
+```
+
+This runs the end-to-end tests against the Vite development server.
+It is much faster than the production build.
+
+But it's still recommended to test the production build with `test:e2e` before deploying (e.g. in CI environments):
+
+```sh
+pnpm build
+pnpm test:e2e
+```
diff --git a/playground/typescript-pinia-with-tests/cypress.config.ts b/playground/typescript-pinia-with-tests/cypress.config.ts
new file mode 100644
index 000000000..0f66080fd
--- /dev/null
+++ b/playground/typescript-pinia-with-tests/cypress.config.ts
@@ -0,0 +1,8 @@
+import { defineConfig } from 'cypress'
+
+export default defineConfig({
+ e2e: {
+ specPattern: 'cypress/e2e/**/*.{cy,spec}.{js,jsx,ts,tsx}',
+ baseUrl: 'http://localhost:4173'
+ }
+})
diff --git a/playground/typescript-pinia-with-tests/cypress/e2e/example.cy.ts b/playground/typescript-pinia-with-tests/cypress/e2e/example.cy.ts
new file mode 100644
index 000000000..7554c35d8
--- /dev/null
+++ b/playground/typescript-pinia-with-tests/cypress/e2e/example.cy.ts
@@ -0,0 +1,8 @@
+// https://on.cypress.io/api
+
+describe('My First Test', () => {
+ it('visits the app root url', () => {
+ cy.visit('/')
+ cy.contains('h1', 'You did it!')
+ })
+})
diff --git a/playground/typescript-pinia-with-tests/cypress/e2e/tsconfig.json b/playground/typescript-pinia-with-tests/cypress/e2e/tsconfig.json
new file mode 100644
index 000000000..37748feb7
--- /dev/null
+++ b/playground/typescript-pinia-with-tests/cypress/e2e/tsconfig.json
@@ -0,0 +1,10 @@
+{
+ "extends": "@vue/tsconfig/tsconfig.dom.json",
+ "include": ["./**/*", "../support/**/*"],
+ "compilerOptions": {
+ "isolatedModules": false,
+ "target": "es5",
+ "lib": ["es5", "dom"],
+ "types": ["cypress"]
+ }
+}
diff --git a/playground/typescript-pinia-with-tests/cypress/fixtures/example.json b/playground/typescript-pinia-with-tests/cypress/fixtures/example.json
new file mode 100644
index 000000000..02e425437
--- /dev/null
+++ b/playground/typescript-pinia-with-tests/cypress/fixtures/example.json
@@ -0,0 +1,5 @@
+{
+ "name": "Using fixtures to represent data",
+ "email": "hello@cypress.io",
+ "body": "Fixtures are a great way to mock data for responses to routes"
+}
diff --git a/playground/typescript-pinia-with-tests/cypress/support/commands.ts b/playground/typescript-pinia-with-tests/cypress/support/commands.ts
new file mode 100644
index 000000000..9b7bb8e25
--- /dev/null
+++ b/playground/typescript-pinia-with-tests/cypress/support/commands.ts
@@ -0,0 +1,39 @@
+///
+// ***********************************************
+// This example commands.ts shows you how to
+// create various custom commands and overwrite
+// existing commands.
+//
+// For more comprehensive examples of custom
+// commands please read more here:
+// https://on.cypress.io/custom-commands
+// ***********************************************
+//
+//
+// -- This is a parent command --
+// Cypress.Commands.add('login', (email, password) => { ... })
+//
+//
+// -- This is a child command --
+// Cypress.Commands.add('drag', { prevSubject: 'element'}, (subject, options) => { ... })
+//
+//
+// -- This is a dual command --
+// Cypress.Commands.add('dismiss', { prevSubject: 'optional'}, (subject, options) => { ... })
+//
+//
+// -- This will overwrite an existing command --
+// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... })
+//
+// declare global {
+// namespace Cypress {
+// interface Chainable {
+// login(email: string, password: string): Chainable
+// drag(subject: string, options?: Partial): Chainable
+// dismiss(subject: string, options?: Partial): Chainable
+// visit(originalFn: CommandOriginalFn, url: string, options: Partial): Chainable
+// }
+// }
+// }
+
+export {}
diff --git a/playground/typescript-pinia-with-tests/cypress/support/e2e.ts b/playground/typescript-pinia-with-tests/cypress/support/e2e.ts
new file mode 100644
index 000000000..d68db96df
--- /dev/null
+++ b/playground/typescript-pinia-with-tests/cypress/support/e2e.ts
@@ -0,0 +1,20 @@
+// ***********************************************************
+// This example support/index.js is processed and
+// loaded automatically before your test files.
+//
+// This is a great place to put global configuration and
+// behavior that modifies Cypress.
+//
+// You can change the location of this file or turn off
+// automatically serving support files with the
+// 'supportFile' configuration option.
+//
+// You can read more here:
+// https://on.cypress.io/configuration
+// ***********************************************************
+
+// Import commands.js using ES2015 syntax:
+import './commands'
+
+// Alternatively you can use CommonJS syntax:
+// require('./commands')
diff --git a/playground/typescript-pinia-with-tests/env.d.ts b/playground/typescript-pinia-with-tests/env.d.ts
new file mode 100644
index 000000000..11f02fe2a
--- /dev/null
+++ b/playground/typescript-pinia-with-tests/env.d.ts
@@ -0,0 +1 @@
+///
diff --git a/playground/typescript-pinia-with-tests/index.html b/playground/typescript-pinia-with-tests/index.html
new file mode 100644
index 000000000..a88854489
--- /dev/null
+++ b/playground/typescript-pinia-with-tests/index.html
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+ Vite App
+
+
+
+
+
+
diff --git a/playground/typescript-pinia-with-tests/package.json b/playground/typescript-pinia-with-tests/package.json
new file mode 100644
index 000000000..13cab1ecd
--- /dev/null
+++ b/playground/typescript-pinia-with-tests/package.json
@@ -0,0 +1,36 @@
+{
+ "name": "typescript-pinia-with-tests",
+ "version": "0.0.0",
+ "private": true,
+ "type": "module",
+ "scripts": {
+ "dev": "vite",
+ "build": "run-p type-check \"build-only {@}\" --",
+ "preview": "vite preview",
+ "test:unit": "vitest",
+ "test:e2e": "start-server-and-test preview http://localhost:4173 'cypress run --e2e'",
+ "test:e2e:dev": "start-server-and-test 'vite dev --port 4173' http://localhost:4173 'cypress open --e2e'",
+ "build-only": "vite build",
+ "type-check": "vue-tsc --build --force"
+ },
+ "dependencies": {
+ "pinia": "^2.1.7",
+ "vue": "^3.4.15"
+ },
+ "devDependencies": {
+ "@tsconfig/node20": "^20.1.2",
+ "@types/jsdom": "^21.1.6",
+ "@types/node": "^20.11.16",
+ "@vitejs/plugin-vue": "^5.0.3",
+ "@vue/test-utils": "^2.4.4",
+ "@vue/tsconfig": "^0.5.1",
+ "cypress": "^13.6.4",
+ "jsdom": "^24.0.0",
+ "npm-run-all2": "^6.1.2",
+ "start-server-and-test": "^2.0.3",
+ "typescript": "~5.3.0",
+ "vite": "^5.0.11",
+ "vitest": "^1.2.2",
+ "vue-tsc": "^1.8.27"
+ }
+}
diff --git a/playground/typescript-pinia-with-tests/public/favicon.ico b/playground/typescript-pinia-with-tests/public/favicon.ico
new file mode 100644
index 000000000..df36fcfb7
Binary files /dev/null and b/playground/typescript-pinia-with-tests/public/favicon.ico differ
diff --git a/playground/typescript-pinia-with-tests/src/App.vue b/playground/typescript-pinia-with-tests/src/App.vue
new file mode 100644
index 000000000..69f32f91f
--- /dev/null
+++ b/playground/typescript-pinia-with-tests/src/App.vue
@@ -0,0 +1,10 @@
+
+ app
+
+
+
+
+
diff --git a/playground/typescript-pinia-with-tests/src/assets/logo.svg b/playground/typescript-pinia-with-tests/src/assets/logo.svg
new file mode 100644
index 000000000..756566035
--- /dev/null
+++ b/playground/typescript-pinia-with-tests/src/assets/logo.svg
@@ -0,0 +1 @@
+
diff --git a/playground/typescript-pinia-with-tests/src/assets/main.css b/playground/typescript-pinia-with-tests/src/assets/main.css
new file mode 100644
index 000000000..5aadc6ceb
--- /dev/null
+++ b/playground/typescript-pinia-with-tests/src/assets/main.css
@@ -0,0 +1,6 @@
+html, body, #app {
+ width: 100%;
+ height: 100%;
+ padding: 0;
+ margin: 0;
+}
diff --git a/playground/typescript-pinia-with-tests/src/components/__tests__/HelloWorld.spec.ts b/playground/typescript-pinia-with-tests/src/components/__tests__/HelloWorld.spec.ts
new file mode 100644
index 000000000..253320200
--- /dev/null
+++ b/playground/typescript-pinia-with-tests/src/components/__tests__/HelloWorld.spec.ts
@@ -0,0 +1,11 @@
+import { describe, it, expect } from 'vitest'
+
+import { mount } from '@vue/test-utils'
+import HelloWorld from '../HelloWorld.vue'
+
+describe('HelloWorld', () => {
+ it('renders properly', () => {
+ const wrapper = mount(HelloWorld, { props: { msg: 'Hello Vitest' } })
+ expect(wrapper.text()).toContain('Hello Vitest')
+ })
+})
diff --git a/playground/typescript-pinia-with-tests/src/main.ts b/playground/typescript-pinia-with-tests/src/main.ts
new file mode 100644
index 000000000..48dad4313
--- /dev/null
+++ b/playground/typescript-pinia-with-tests/src/main.ts
@@ -0,0 +1,11 @@
+import './assets/main.css'
+
+import { createApp } from 'vue'
+import { createPinia } from 'pinia'
+import App from './App.vue'
+
+const app = createApp(App)
+
+app.use(createPinia())
+
+app.mount('#app')
diff --git a/playground/typescript-pinia-with-tests/src/stores/counter.ts b/playground/typescript-pinia-with-tests/src/stores/counter.ts
new file mode 100644
index 000000000..b6757ba57
--- /dev/null
+++ b/playground/typescript-pinia-with-tests/src/stores/counter.ts
@@ -0,0 +1,12 @@
+import { ref, computed } from 'vue'
+import { defineStore } from 'pinia'
+
+export const useCounterStore = defineStore('counter', () => {
+ const count = ref(0)
+ const doubleCount = computed(() => count.value * 2)
+ function increment() {
+ count.value++
+ }
+
+ return { count, doubleCount, increment }
+})
diff --git a/playground/typescript-pinia-with-tests/tsconfig.app.json b/playground/typescript-pinia-with-tests/tsconfig.app.json
new file mode 100644
index 000000000..e14c754d3
--- /dev/null
+++ b/playground/typescript-pinia-with-tests/tsconfig.app.json
@@ -0,0 +1,14 @@
+{
+ "extends": "@vue/tsconfig/tsconfig.dom.json",
+ "include": ["env.d.ts", "src/**/*", "src/**/*.vue"],
+ "exclude": ["src/**/__tests__/*"],
+ "compilerOptions": {
+ "composite": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
+
+ "baseUrl": ".",
+ "paths": {
+ "@/*": ["./src/*"]
+ }
+ }
+}
diff --git a/playground/typescript-pinia-with-tests/tsconfig.json b/playground/typescript-pinia-with-tests/tsconfig.json
new file mode 100644
index 000000000..5304731b8
--- /dev/null
+++ b/playground/typescript-pinia-with-tests/tsconfig.json
@@ -0,0 +1,17 @@
+{
+ "files": [],
+ "references": [
+ {
+ "path": "./tsconfig.node.json"
+ },
+ {
+ "path": "./tsconfig.app.json"
+ },
+ {
+ "path": "./tsconfig.vitest.json"
+ }
+ ],
+ "compilerOptions": {
+ "module": "NodeNext"
+ }
+}
diff --git a/playground/typescript-pinia-with-tests/tsconfig.node.json b/playground/typescript-pinia-with-tests/tsconfig.node.json
new file mode 100644
index 000000000..f09406303
--- /dev/null
+++ b/playground/typescript-pinia-with-tests/tsconfig.node.json
@@ -0,0 +1,19 @@
+{
+ "extends": "@tsconfig/node20/tsconfig.json",
+ "include": [
+ "vite.config.*",
+ "vitest.config.*",
+ "cypress.config.*",
+ "nightwatch.conf.*",
+ "playwright.config.*"
+ ],
+ "compilerOptions": {
+ "composite": true,
+ "noEmit": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
+
+ "module": "ESNext",
+ "moduleResolution": "Bundler",
+ "types": ["node"]
+ }
+}
diff --git a/playground/typescript-pinia-with-tests/tsconfig.vitest.json b/playground/typescript-pinia-with-tests/tsconfig.vitest.json
new file mode 100644
index 000000000..571995d11
--- /dev/null
+++ b/playground/typescript-pinia-with-tests/tsconfig.vitest.json
@@ -0,0 +1,11 @@
+{
+ "extends": "./tsconfig.app.json",
+ "exclude": [],
+ "compilerOptions": {
+ "composite": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.vitest.tsbuildinfo",
+
+ "lib": [],
+ "types": ["node", "jsdom"]
+ }
+}
diff --git a/playground/typescript-pinia-with-tests/vite.config.ts b/playground/typescript-pinia-with-tests/vite.config.ts
new file mode 100644
index 000000000..5c45e1d9b
--- /dev/null
+++ b/playground/typescript-pinia-with-tests/vite.config.ts
@@ -0,0 +1,16 @@
+import { fileURLToPath, URL } from 'node:url'
+
+import { defineConfig } from 'vite'
+import vue from '@vitejs/plugin-vue'
+
+// https://vitejs.dev/config/
+export default defineConfig({
+ plugins: [
+ vue(),
+ ],
+ resolve: {
+ alias: {
+ '@': fileURLToPath(new URL('./src', import.meta.url))
+ }
+ }
+})
diff --git a/playground/typescript-pinia-with-tests/vitest.config.ts b/playground/typescript-pinia-with-tests/vitest.config.ts
new file mode 100644
index 000000000..10067d578
--- /dev/null
+++ b/playground/typescript-pinia-with-tests/vitest.config.ts
@@ -0,0 +1,14 @@
+import { fileURLToPath } from 'node:url'
+import { mergeConfig, defineConfig, configDefaults } from 'vitest/config'
+import viteConfig from './vite.config'
+
+export default mergeConfig(
+ viteConfig,
+ defineConfig({
+ test: {
+ environment: 'jsdom',
+ exclude: [...configDefaults.exclude, 'e2e/*'],
+ root: fileURLToPath(new URL('./', import.meta.url))
+ }
+ })
+)
diff --git a/playground/typescript-pinia/.gitignore b/playground/typescript-pinia/.gitignore
new file mode 100644
index 000000000..8ee54e8d3
--- /dev/null
+++ b/playground/typescript-pinia/.gitignore
@@ -0,0 +1,30 @@
+# 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/
+
+# Editor directories and files
+.vscode/*
+!.vscode/extensions.json
+.idea
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?
+
+*.tsbuildinfo
diff --git a/playground/typescript-pinia/README.md b/playground/typescript-pinia/README.md
new file mode 100644
index 000000000..47428c441
--- /dev/null
+++ b/playground/typescript-pinia/README.md
@@ -0,0 +1,40 @@
+# typescript-pinia
+
+This template should help get you started developing with Vue 3 in Vite.
+
+## Recommended IDE Setup
+
+[VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur) + [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin).
+
+## Type Support for `.vue` Imports in TS
+
+TypeScript cannot handle type information for `.vue` imports by default, so we replace the `tsc` CLI with `vue-tsc` for type checking. In editors, we need [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin) to make the TypeScript language service aware of `.vue` types.
+
+If the standalone TypeScript plugin doesn't feel fast enough to you, Volar has also implemented a [Take Over Mode](https://github.com/johnsoncodehk/volar/discussions/471#discussioncomment-1361669) that is more performant. You can enable it by the following steps:
+
+1. Disable the built-in TypeScript Extension
+ 1) Run `Extensions: Show Built-in Extensions` from VSCode's command palette
+ 2) Find `TypeScript and JavaScript Language Features`, right click and select `Disable (Workspace)`
+2. Reload the VSCode window by running `Developer: Reload Window` from the command palette.
+
+## Customize configuration
+
+See [Vite Configuration Reference](https://vitejs.dev/config/).
+
+## Project Setup
+
+```sh
+pnpm install
+```
+
+### Compile and Hot-Reload for Development
+
+```sh
+pnpm dev
+```
+
+### Type-Check, Compile and Minify for Production
+
+```sh
+pnpm build
+```
diff --git a/playground/typescript-pinia/env.d.ts b/playground/typescript-pinia/env.d.ts
new file mode 100644
index 000000000..11f02fe2a
--- /dev/null
+++ b/playground/typescript-pinia/env.d.ts
@@ -0,0 +1 @@
+///
diff --git a/playground/typescript-pinia/index.html b/playground/typescript-pinia/index.html
new file mode 100644
index 000000000..a88854489
--- /dev/null
+++ b/playground/typescript-pinia/index.html
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+ Vite App
+
+
+
+
+
+
diff --git a/playground/typescript-pinia/package.json b/playground/typescript-pinia/package.json
new file mode 100644
index 000000000..fcbd0f238
--- /dev/null
+++ b/playground/typescript-pinia/package.json
@@ -0,0 +1,27 @@
+{
+ "name": "typescript-pinia",
+ "version": "0.0.0",
+ "private": true,
+ "type": "module",
+ "scripts": {
+ "dev": "vite",
+ "build": "run-p type-check \"build-only {@}\" --",
+ "preview": "vite preview",
+ "build-only": "vite build",
+ "type-check": "vue-tsc --build --force"
+ },
+ "dependencies": {
+ "pinia": "^2.1.7",
+ "vue": "^3.4.15"
+ },
+ "devDependencies": {
+ "@tsconfig/node20": "^20.1.2",
+ "@types/node": "^20.11.16",
+ "@vitejs/plugin-vue": "^5.0.3",
+ "@vue/tsconfig": "^0.5.1",
+ "npm-run-all2": "^6.1.2",
+ "typescript": "~5.3.0",
+ "vite": "^5.0.11",
+ "vue-tsc": "^1.8.27"
+ }
+}
diff --git a/playground/typescript-pinia/public/favicon.ico b/playground/typescript-pinia/public/favicon.ico
new file mode 100644
index 000000000..df36fcfb7
Binary files /dev/null and b/playground/typescript-pinia/public/favicon.ico differ
diff --git a/playground/typescript-pinia/src/App.vue b/playground/typescript-pinia/src/App.vue
new file mode 100644
index 000000000..69f32f91f
--- /dev/null
+++ b/playground/typescript-pinia/src/App.vue
@@ -0,0 +1,10 @@
+
+ app
+
+
+
+
+
diff --git a/playground/typescript-pinia/src/assets/logo.svg b/playground/typescript-pinia/src/assets/logo.svg
new file mode 100644
index 000000000..756566035
--- /dev/null
+++ b/playground/typescript-pinia/src/assets/logo.svg
@@ -0,0 +1 @@
+
diff --git a/playground/typescript-pinia/src/assets/main.css b/playground/typescript-pinia/src/assets/main.css
new file mode 100644
index 000000000..5aadc6ceb
--- /dev/null
+++ b/playground/typescript-pinia/src/assets/main.css
@@ -0,0 +1,6 @@
+html, body, #app {
+ width: 100%;
+ height: 100%;
+ padding: 0;
+ margin: 0;
+}
diff --git a/playground/typescript-pinia/src/main.ts b/playground/typescript-pinia/src/main.ts
new file mode 100644
index 000000000..48dad4313
--- /dev/null
+++ b/playground/typescript-pinia/src/main.ts
@@ -0,0 +1,11 @@
+import './assets/main.css'
+
+import { createApp } from 'vue'
+import { createPinia } from 'pinia'
+import App from './App.vue'
+
+const app = createApp(App)
+
+app.use(createPinia())
+
+app.mount('#app')
diff --git a/playground/typescript-pinia/src/stores/counter.ts b/playground/typescript-pinia/src/stores/counter.ts
new file mode 100644
index 000000000..b6757ba57
--- /dev/null
+++ b/playground/typescript-pinia/src/stores/counter.ts
@@ -0,0 +1,12 @@
+import { ref, computed } from 'vue'
+import { defineStore } from 'pinia'
+
+export const useCounterStore = defineStore('counter', () => {
+ const count = ref(0)
+ const doubleCount = computed(() => count.value * 2)
+ function increment() {
+ count.value++
+ }
+
+ return { count, doubleCount, increment }
+})
diff --git a/playground/typescript-pinia/tsconfig.app.json b/playground/typescript-pinia/tsconfig.app.json
new file mode 100644
index 000000000..e14c754d3
--- /dev/null
+++ b/playground/typescript-pinia/tsconfig.app.json
@@ -0,0 +1,14 @@
+{
+ "extends": "@vue/tsconfig/tsconfig.dom.json",
+ "include": ["env.d.ts", "src/**/*", "src/**/*.vue"],
+ "exclude": ["src/**/__tests__/*"],
+ "compilerOptions": {
+ "composite": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
+
+ "baseUrl": ".",
+ "paths": {
+ "@/*": ["./src/*"]
+ }
+ }
+}
diff --git a/playground/typescript-pinia/tsconfig.json b/playground/typescript-pinia/tsconfig.json
new file mode 100644
index 000000000..66b5e5703
--- /dev/null
+++ b/playground/typescript-pinia/tsconfig.json
@@ -0,0 +1,11 @@
+{
+ "files": [],
+ "references": [
+ {
+ "path": "./tsconfig.node.json"
+ },
+ {
+ "path": "./tsconfig.app.json"
+ }
+ ]
+}
diff --git a/playground/typescript-pinia/tsconfig.node.json b/playground/typescript-pinia/tsconfig.node.json
new file mode 100644
index 000000000..f09406303
--- /dev/null
+++ b/playground/typescript-pinia/tsconfig.node.json
@@ -0,0 +1,19 @@
+{
+ "extends": "@tsconfig/node20/tsconfig.json",
+ "include": [
+ "vite.config.*",
+ "vitest.config.*",
+ "cypress.config.*",
+ "nightwatch.conf.*",
+ "playwright.config.*"
+ ],
+ "compilerOptions": {
+ "composite": true,
+ "noEmit": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
+
+ "module": "ESNext",
+ "moduleResolution": "Bundler",
+ "types": ["node"]
+ }
+}
diff --git a/playground/typescript-pinia/vite.config.ts b/playground/typescript-pinia/vite.config.ts
new file mode 100644
index 000000000..5c45e1d9b
--- /dev/null
+++ b/playground/typescript-pinia/vite.config.ts
@@ -0,0 +1,16 @@
+import { fileURLToPath, URL } from 'node:url'
+
+import { defineConfig } from 'vite'
+import vue from '@vitejs/plugin-vue'
+
+// https://vitejs.dev/config/
+export default defineConfig({
+ plugins: [
+ vue(),
+ ],
+ resolve: {
+ alias: {
+ '@': fileURLToPath(new URL('./src', import.meta.url))
+ }
+ }
+})
diff --git a/playground/typescript-playwright/.gitignore b/playground/typescript-playwright/.gitignore
new file mode 100644
index 000000000..aef72d03c
--- /dev/null
+++ b/playground/typescript-playwright/.gitignore
@@ -0,0 +1,33 @@
+# 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/
+
+# Editor directories and files
+.vscode/*
+!.vscode/extensions.json
+.idea
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?
+
+*.tsbuildinfo
+
+test-results/
+playwright-report/
diff --git a/playground/typescript-playwright/.vscode/extensions.json b/playground/typescript-playwright/.vscode/extensions.json
new file mode 100644
index 000000000..7b3f8bdae
--- /dev/null
+++ b/playground/typescript-playwright/.vscode/extensions.json
@@ -0,0 +1,3 @@
+{
+ "recommendations": ["ms-playwright.playwright"]
+}
diff --git a/playground/typescript-playwright/README.md b/playground/typescript-playwright/README.md
new file mode 100644
index 000000000..501c14eef
--- /dev/null
+++ b/playground/typescript-playwright/README.md
@@ -0,0 +1,59 @@
+# typescript-playwright
+
+This template should help get you started developing with Vue 3 in Vite.
+
+## Recommended IDE Setup
+
+[VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur) + [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin).
+
+## Type Support for `.vue` Imports in TS
+
+TypeScript cannot handle type information for `.vue` imports by default, so we replace the `tsc` CLI with `vue-tsc` for type checking. In editors, we need [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin) to make the TypeScript language service aware of `.vue` types.
+
+If the standalone TypeScript plugin doesn't feel fast enough to you, Volar has also implemented a [Take Over Mode](https://github.com/johnsoncodehk/volar/discussions/471#discussioncomment-1361669) that is more performant. You can enable it by the following steps:
+
+1. Disable the built-in TypeScript Extension
+ 1) Run `Extensions: Show Built-in Extensions` from VSCode's command palette
+ 2) Find `TypeScript and JavaScript Language Features`, right click and select `Disable (Workspace)`
+2. Reload the VSCode window by running `Developer: Reload Window` from the command palette.
+
+## Customize configuration
+
+See [Vite Configuration Reference](https://vitejs.dev/config/).
+
+## Project Setup
+
+```sh
+pnpm install
+```
+
+### Compile and Hot-Reload for Development
+
+```sh
+pnpm dev
+```
+
+### Type-Check, Compile and Minify for Production
+
+```sh
+pnpm build
+```
+
+### Run End-to-End Tests with [Playwright](https://playwright.dev)
+
+```sh
+# Install browsers for the first run
+npx playwright install
+
+# When testing on CI, must build the project first
+pnpm build
+
+# Runs the end-to-end tests
+pnpm test:e2e
+# Runs the tests only on Chromium
+pnpm test:e2e --project=chromium
+# Runs the tests of a specific file
+pnpm test:e2e tests/example.spec.ts
+# Runs the tests in debug mode
+pnpm test:e2e --debug
+```
diff --git a/playground/typescript-playwright/e2e/tsconfig.json b/playground/typescript-playwright/e2e/tsconfig.json
new file mode 100644
index 000000000..be3bbfc0e
--- /dev/null
+++ b/playground/typescript-playwright/e2e/tsconfig.json
@@ -0,0 +1,4 @@
+{
+ "extends": "@tsconfig/node20/tsconfig.json",
+ "include": ["./**/*"]
+}
diff --git a/playground/typescript-playwright/e2e/vue.spec.ts b/playground/typescript-playwright/e2e/vue.spec.ts
new file mode 100644
index 000000000..3e5a3d02d
--- /dev/null
+++ b/playground/typescript-playwright/e2e/vue.spec.ts
@@ -0,0 +1,8 @@
+import { test, expect } from '@playwright/test';
+
+// See here how to get started:
+// https://playwright.dev/docs/intro
+test('visits the app root url', async ({ page }) => {
+ await page.goto('/');
+ await expect(page.locator('div.greetings > h1')).toHaveText('You did it!');
+})
diff --git a/playground/typescript-playwright/env.d.ts b/playground/typescript-playwright/env.d.ts
new file mode 100644
index 000000000..11f02fe2a
--- /dev/null
+++ b/playground/typescript-playwright/env.d.ts
@@ -0,0 +1 @@
+///
diff --git a/playground/typescript-playwright/index.html b/playground/typescript-playwright/index.html
new file mode 100644
index 000000000..a88854489
--- /dev/null
+++ b/playground/typescript-playwright/index.html
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+ Vite App
+
+
+
+
+
+
diff --git a/playground/typescript-playwright/package.json b/playground/typescript-playwright/package.json
new file mode 100644
index 000000000..01f4b6c7f
--- /dev/null
+++ b/playground/typescript-playwright/package.json
@@ -0,0 +1,28 @@
+{
+ "name": "typescript-playwright",
+ "version": "0.0.0",
+ "private": true,
+ "type": "module",
+ "scripts": {
+ "dev": "vite",
+ "build": "run-p type-check \"build-only {@}\" --",
+ "preview": "vite preview",
+ "test:e2e": "playwright test",
+ "build-only": "vite build",
+ "type-check": "vue-tsc --build --force"
+ },
+ "dependencies": {
+ "vue": "^3.4.15"
+ },
+ "devDependencies": {
+ "@playwright/test": "^1.41.2",
+ "@tsconfig/node20": "^20.1.2",
+ "@types/node": "^20.11.16",
+ "@vitejs/plugin-vue": "^5.0.3",
+ "@vue/tsconfig": "^0.5.1",
+ "npm-run-all2": "^6.1.2",
+ "typescript": "~5.3.0",
+ "vite": "^5.0.11",
+ "vue-tsc": "^1.8.27"
+ }
+}
diff --git a/playground/typescript-playwright/playwright.config.ts b/playground/typescript-playwright/playwright.config.ts
new file mode 100644
index 000000000..92075cc1b
--- /dev/null
+++ b/playground/typescript-playwright/playwright.config.ts
@@ -0,0 +1,110 @@
+import process from 'node:process'
+import { defineConfig, devices } from '@playwright/test'
+
+/**
+ * Read environment variables from file.
+ * https://github.com/motdotla/dotenv
+ */
+// require('dotenv').config();
+
+/**
+ * See https://playwright.dev/docs/test-configuration.
+ */
+export default defineConfig({
+ testDir: './e2e',
+ /* Maximum time one test can run for. */
+ timeout: 30 * 1000,
+ expect: {
+ /**
+ * Maximum time expect() should wait for the condition to be met.
+ * For example in `await expect(locator).toHaveText();`
+ */
+ timeout: 5000
+ },
+ /* Fail the build on CI if you accidentally left test.only in the source code. */
+ forbidOnly: !!process.env.CI,
+ /* Retry on CI only */
+ retries: process.env.CI ? 2 : 0,
+ /* Opt out of parallel tests on CI. */
+ workers: process.env.CI ? 1 : undefined,
+ /* Reporter to use. See https://playwright.dev/docs/test-reporters */
+ reporter: 'html',
+ /* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
+ use: {
+ /* Maximum time each action such as `click()` can take. Defaults to 0 (no limit). */
+ actionTimeout: 0,
+ /* Base URL to use in actions like `await page.goto('/')`. */
+ baseURL: 'http://localhost:5173',
+
+ /* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
+ trace: 'on-first-retry',
+
+ /* Only on CI systems run the tests headless */
+ headless: !!process.env.CI
+ },
+
+ /* Configure projects for major browsers */
+ projects: [
+ {
+ name: 'chromium',
+ use: {
+ ...devices['Desktop Chrome']
+ }
+ },
+ {
+ name: 'firefox',
+ use: {
+ ...devices['Desktop Firefox']
+ }
+ },
+ {
+ name: 'webkit',
+ use: {
+ ...devices['Desktop Safari']
+ }
+ }
+
+ /* Test against mobile viewports. */
+ // {
+ // name: 'Mobile Chrome',
+ // use: {
+ // ...devices['Pixel 5'],
+ // },
+ // },
+ // {
+ // name: 'Mobile Safari',
+ // use: {
+ // ...devices['iPhone 12'],
+ // },
+ // },
+
+ /* Test against branded browsers. */
+ // {
+ // name: 'Microsoft Edge',
+ // use: {
+ // channel: 'msedge',
+ // },
+ // },
+ // {
+ // name: 'Google Chrome',
+ // use: {
+ // channel: 'chrome',
+ // },
+ // },
+ ],
+
+ /* Folder for test artifacts such as screenshots, videos, traces, etc. */
+ // outputDir: 'test-results/',
+
+ /* Run your local dev server before starting the tests */
+ webServer: {
+ /**
+ * Use the dev server by default for faster feedback loop.
+ * Use the preview server on CI for more realistic testing.
+ * Playwright will re-use the local server if there is already a dev-server running.
+ */
+ command: process.env.CI ? 'vite preview --port 5173' : 'vite dev',
+ port: 5173,
+ reuseExistingServer: !process.env.CI
+ }
+})
diff --git a/playground/typescript-playwright/public/favicon.ico b/playground/typescript-playwright/public/favicon.ico
new file mode 100644
index 000000000..df36fcfb7
Binary files /dev/null and b/playground/typescript-playwright/public/favicon.ico differ
diff --git a/playground/typescript-playwright/src/App.vue b/playground/typescript-playwright/src/App.vue
new file mode 100644
index 000000000..69f32f91f
--- /dev/null
+++ b/playground/typescript-playwright/src/App.vue
@@ -0,0 +1,10 @@
+
+ app
+
+
+
+
+
diff --git a/playground/typescript-playwright/src/assets/logo.svg b/playground/typescript-playwright/src/assets/logo.svg
new file mode 100644
index 000000000..756566035
--- /dev/null
+++ b/playground/typescript-playwright/src/assets/logo.svg
@@ -0,0 +1 @@
+
diff --git a/playground/typescript-playwright/src/assets/main.css b/playground/typescript-playwright/src/assets/main.css
new file mode 100644
index 000000000..5aadc6ceb
--- /dev/null
+++ b/playground/typescript-playwright/src/assets/main.css
@@ -0,0 +1,6 @@
+html, body, #app {
+ width: 100%;
+ height: 100%;
+ padding: 0;
+ margin: 0;
+}
diff --git a/playground/typescript-playwright/src/main.ts b/playground/typescript-playwright/src/main.ts
new file mode 100644
index 000000000..0ac3a5ff0
--- /dev/null
+++ b/playground/typescript-playwright/src/main.ts
@@ -0,0 +1,6 @@
+import './assets/main.css'
+
+import { createApp } from 'vue'
+import App from './App.vue'
+
+createApp(App).mount('#app')
diff --git a/playground/typescript-playwright/tsconfig.app.json b/playground/typescript-playwright/tsconfig.app.json
new file mode 100644
index 000000000..e14c754d3
--- /dev/null
+++ b/playground/typescript-playwright/tsconfig.app.json
@@ -0,0 +1,14 @@
+{
+ "extends": "@vue/tsconfig/tsconfig.dom.json",
+ "include": ["env.d.ts", "src/**/*", "src/**/*.vue"],
+ "exclude": ["src/**/__tests__/*"],
+ "compilerOptions": {
+ "composite": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
+
+ "baseUrl": ".",
+ "paths": {
+ "@/*": ["./src/*"]
+ }
+ }
+}
diff --git a/playground/typescript-playwright/tsconfig.json b/playground/typescript-playwright/tsconfig.json
new file mode 100644
index 000000000..66b5e5703
--- /dev/null
+++ b/playground/typescript-playwright/tsconfig.json
@@ -0,0 +1,11 @@
+{
+ "files": [],
+ "references": [
+ {
+ "path": "./tsconfig.node.json"
+ },
+ {
+ "path": "./tsconfig.app.json"
+ }
+ ]
+}
diff --git a/playground/typescript-playwright/tsconfig.node.json b/playground/typescript-playwright/tsconfig.node.json
new file mode 100644
index 000000000..f09406303
--- /dev/null
+++ b/playground/typescript-playwright/tsconfig.node.json
@@ -0,0 +1,19 @@
+{
+ "extends": "@tsconfig/node20/tsconfig.json",
+ "include": [
+ "vite.config.*",
+ "vitest.config.*",
+ "cypress.config.*",
+ "nightwatch.conf.*",
+ "playwright.config.*"
+ ],
+ "compilerOptions": {
+ "composite": true,
+ "noEmit": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
+
+ "module": "ESNext",
+ "moduleResolution": "Bundler",
+ "types": ["node"]
+ }
+}
diff --git a/playground/typescript-playwright/vite.config.ts b/playground/typescript-playwright/vite.config.ts
new file mode 100644
index 000000000..5c45e1d9b
--- /dev/null
+++ b/playground/typescript-playwright/vite.config.ts
@@ -0,0 +1,16 @@
+import { fileURLToPath, URL } from 'node:url'
+
+import { defineConfig } from 'vite'
+import vue from '@vitejs/plugin-vue'
+
+// https://vitejs.dev/config/
+export default defineConfig({
+ plugins: [
+ vue(),
+ ],
+ resolve: {
+ alias: {
+ '@': fileURLToPath(new URL('./src', import.meta.url))
+ }
+ }
+})
diff --git a/playground/typescript-router-cypress/.gitignore b/playground/typescript-router-cypress/.gitignore
new file mode 100644
index 000000000..8ee54e8d3
--- /dev/null
+++ b/playground/typescript-router-cypress/.gitignore
@@ -0,0 +1,30 @@
+# 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/
+
+# Editor directories and files
+.vscode/*
+!.vscode/extensions.json
+.idea
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?
+
+*.tsbuildinfo
diff --git a/playground/typescript-router-cypress/README.md b/playground/typescript-router-cypress/README.md
new file mode 100644
index 000000000..64a9a833c
--- /dev/null
+++ b/playground/typescript-router-cypress/README.md
@@ -0,0 +1,62 @@
+# typescript-router-cypress
+
+This template should help get you started developing with Vue 3 in Vite.
+
+## Recommended IDE Setup
+
+[VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur) + [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin).
+
+## Type Support for `.vue` Imports in TS
+
+TypeScript cannot handle type information for `.vue` imports by default, so we replace the `tsc` CLI with `vue-tsc` for type checking. In editors, we need [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin) to make the TypeScript language service aware of `.vue` types.
+
+If the standalone TypeScript plugin doesn't feel fast enough to you, Volar has also implemented a [Take Over Mode](https://github.com/johnsoncodehk/volar/discussions/471#discussioncomment-1361669) that is more performant. You can enable it by the following steps:
+
+1. Disable the built-in TypeScript Extension
+ 1) Run `Extensions: Show Built-in Extensions` from VSCode's command palette
+ 2) Find `TypeScript and JavaScript Language Features`, right click and select `Disable (Workspace)`
+2. Reload the VSCode window by running `Developer: Reload Window` from the command palette.
+
+## Customize configuration
+
+See [Vite Configuration Reference](https://vitejs.dev/config/).
+
+## Project Setup
+
+```sh
+pnpm install
+```
+
+### Compile and Hot-Reload for Development
+
+```sh
+pnpm dev
+```
+
+### Type-Check, Compile and Minify for Production
+
+```sh
+pnpm build
+```
+
+### Run Headed Component Tests with [Cypress Component Testing](https://on.cypress.io/component)
+
+```sh
+pnpm test:unit:dev # or `pnpm test:unit` for headless testing
+```
+
+### Run End-to-End Tests with [Cypress](https://www.cypress.io/)
+
+```sh
+pnpm test:e2e:dev
+```
+
+This runs the end-to-end tests against the Vite development server.
+It is much faster than the production build.
+
+But it's still recommended to test the production build with `test:e2e` before deploying (e.g. in CI environments):
+
+```sh
+pnpm build
+pnpm test:e2e
+```
diff --git a/playground/typescript-router-cypress/cypress.config.ts b/playground/typescript-router-cypress/cypress.config.ts
new file mode 100644
index 000000000..c8fac1298
--- /dev/null
+++ b/playground/typescript-router-cypress/cypress.config.ts
@@ -0,0 +1,15 @@
+import { defineConfig } from 'cypress'
+
+export default defineConfig({
+ e2e: {
+ specPattern: 'cypress/e2e/**/*.{cy,spec}.{js,jsx,ts,tsx}',
+ baseUrl: 'http://localhost:4173'
+ },
+ component: {
+ specPattern: 'src/**/__tests__/*.{cy,spec}.{js,ts,jsx,tsx}',
+ devServer: {
+ framework: 'vue',
+ bundler: 'vite'
+ }
+ }
+})
diff --git a/playground/typescript-router-cypress/cypress/e2e/example.cy.ts b/playground/typescript-router-cypress/cypress/e2e/example.cy.ts
new file mode 100644
index 000000000..7554c35d8
--- /dev/null
+++ b/playground/typescript-router-cypress/cypress/e2e/example.cy.ts
@@ -0,0 +1,8 @@
+// https://on.cypress.io/api
+
+describe('My First Test', () => {
+ it('visits the app root url', () => {
+ cy.visit('/')
+ cy.contains('h1', 'You did it!')
+ })
+})
diff --git a/playground/typescript-router-cypress/cypress/e2e/tsconfig.json b/playground/typescript-router-cypress/cypress/e2e/tsconfig.json
new file mode 100644
index 000000000..37748feb7
--- /dev/null
+++ b/playground/typescript-router-cypress/cypress/e2e/tsconfig.json
@@ -0,0 +1,10 @@
+{
+ "extends": "@vue/tsconfig/tsconfig.dom.json",
+ "include": ["./**/*", "../support/**/*"],
+ "compilerOptions": {
+ "isolatedModules": false,
+ "target": "es5",
+ "lib": ["es5", "dom"],
+ "types": ["cypress"]
+ }
+}
diff --git a/playground/typescript-router-cypress/cypress/fixtures/example.json b/playground/typescript-router-cypress/cypress/fixtures/example.json
new file mode 100644
index 000000000..02e425437
--- /dev/null
+++ b/playground/typescript-router-cypress/cypress/fixtures/example.json
@@ -0,0 +1,5 @@
+{
+ "name": "Using fixtures to represent data",
+ "email": "hello@cypress.io",
+ "body": "Fixtures are a great way to mock data for responses to routes"
+}
diff --git a/playground/typescript-router-cypress/cypress/support/commands.ts b/playground/typescript-router-cypress/cypress/support/commands.ts
new file mode 100644
index 000000000..9b7bb8e25
--- /dev/null
+++ b/playground/typescript-router-cypress/cypress/support/commands.ts
@@ -0,0 +1,39 @@
+///
+// ***********************************************
+// This example commands.ts shows you how to
+// create various custom commands and overwrite
+// existing commands.
+//
+// For more comprehensive examples of custom
+// commands please read more here:
+// https://on.cypress.io/custom-commands
+// ***********************************************
+//
+//
+// -- This is a parent command --
+// Cypress.Commands.add('login', (email, password) => { ... })
+//
+//
+// -- This is a child command --
+// Cypress.Commands.add('drag', { prevSubject: 'element'}, (subject, options) => { ... })
+//
+//
+// -- This is a dual command --
+// Cypress.Commands.add('dismiss', { prevSubject: 'optional'}, (subject, options) => { ... })
+//
+//
+// -- This will overwrite an existing command --
+// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... })
+//
+// declare global {
+// namespace Cypress {
+// interface Chainable {
+// login(email: string, password: string): Chainable
+// drag(subject: string, options?: Partial): Chainable
+// dismiss(subject: string, options?: Partial): Chainable
+// visit(originalFn: CommandOriginalFn, url: string, options: Partial): Chainable
+// }
+// }
+// }
+
+export {}
diff --git a/playground/typescript-router-cypress/cypress/support/component-index.html b/playground/typescript-router-cypress/cypress/support/component-index.html
new file mode 100644
index 000000000..5f9622ae2
--- /dev/null
+++ b/playground/typescript-router-cypress/cypress/support/component-index.html
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+ Components App
+
+
+
+
+
diff --git a/playground/typescript-router-cypress/cypress/support/component.ts b/playground/typescript-router-cypress/cypress/support/component.ts
new file mode 100644
index 000000000..04e4c352b
--- /dev/null
+++ b/playground/typescript-router-cypress/cypress/support/component.ts
@@ -0,0 +1,43 @@
+// ***********************************************************
+// This example support/component.ts is processed and
+// loaded automatically before your test files.
+//
+// This is a great place to put global configuration and
+// behavior that modifies Cypress.
+//
+// You can change the location of this file or turn off
+// automatically serving support files with the
+// 'supportFile' configuration option.
+//
+// You can read more here:
+// https://on.cypress.io/configuration
+// ***********************************************************
+
+// Import commands.js using ES2015 syntax:
+import './commands'
+
+// Alternatively you can use CommonJS syntax:
+// require('./commands')
+
+// Import global styles
+import '@/assets/main.css'
+
+import { mount } from 'cypress/vue'
+
+// Augment the Cypress namespace to include type definitions for
+// your custom command.
+// Alternatively, can be defined in cypress/support/component.d.ts
+// with a at the top of your spec.
+/* eslint-disable @typescript-eslint/no-namespace */
+declare global {
+ namespace Cypress {
+ interface Chainable {
+ mount: typeof mount
+ }
+ }
+}
+
+Cypress.Commands.add('mount', mount)
+
+// Example use:
+// cy.mount(MyComponent)
diff --git a/playground/typescript-router-cypress/cypress/support/e2e.ts b/playground/typescript-router-cypress/cypress/support/e2e.ts
new file mode 100644
index 000000000..d68db96df
--- /dev/null
+++ b/playground/typescript-router-cypress/cypress/support/e2e.ts
@@ -0,0 +1,20 @@
+// ***********************************************************
+// This example support/index.js is processed and
+// loaded automatically before your test files.
+//
+// This is a great place to put global configuration and
+// behavior that modifies Cypress.
+//
+// You can change the location of this file or turn off
+// automatically serving support files with the
+// 'supportFile' configuration option.
+//
+// You can read more here:
+// https://on.cypress.io/configuration
+// ***********************************************************
+
+// Import commands.js using ES2015 syntax:
+import './commands'
+
+// Alternatively you can use CommonJS syntax:
+// require('./commands')
diff --git a/playground/typescript-router-cypress/env.d.ts b/playground/typescript-router-cypress/env.d.ts
new file mode 100644
index 000000000..11f02fe2a
--- /dev/null
+++ b/playground/typescript-router-cypress/env.d.ts
@@ -0,0 +1 @@
+///
diff --git a/playground/typescript-router-cypress/index.html b/playground/typescript-router-cypress/index.html
new file mode 100644
index 000000000..a88854489
--- /dev/null
+++ b/playground/typescript-router-cypress/index.html
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+ Vite App
+
+
+
+
+
+
diff --git a/playground/typescript-router-cypress/package.json b/playground/typescript-router-cypress/package.json
new file mode 100644
index 000000000..8dd0b0b05
--- /dev/null
+++ b/playground/typescript-router-cypress/package.json
@@ -0,0 +1,33 @@
+{
+ "name": "typescript-router-cypress",
+ "version": "0.0.0",
+ "private": true,
+ "type": "module",
+ "scripts": {
+ "dev": "vite",
+ "build": "run-p type-check \"build-only {@}\" --",
+ "preview": "vite preview",
+ "test:e2e": "start-server-and-test preview http://localhost:4173 'cypress run --e2e'",
+ "test:e2e:dev": "start-server-and-test 'vite dev --port 4173' http://localhost:4173 'cypress open --e2e'",
+ "test:unit": "cypress run --component",
+ "test:unit:dev": "cypress open --component",
+ "build-only": "vite build",
+ "type-check": "vue-tsc --build --force"
+ },
+ "dependencies": {
+ "vue": "^3.4.15",
+ "vue-router": "^4.2.5"
+ },
+ "devDependencies": {
+ "@tsconfig/node20": "^20.1.2",
+ "@types/node": "^20.11.16",
+ "@vitejs/plugin-vue": "^5.0.3",
+ "@vue/tsconfig": "^0.5.1",
+ "cypress": "^13.6.4",
+ "npm-run-all2": "^6.1.2",
+ "start-server-and-test": "^2.0.3",
+ "typescript": "~5.3.0",
+ "vite": "^5.0.11",
+ "vue-tsc": "^1.8.27"
+ }
+}
diff --git a/playground/typescript-router-cypress/public/favicon.ico b/playground/typescript-router-cypress/public/favicon.ico
new file mode 100644
index 000000000..df36fcfb7
Binary files /dev/null and b/playground/typescript-router-cypress/public/favicon.ico differ
diff --git a/playground/typescript-router-cypress/src/App.vue b/playground/typescript-router-cypress/src/App.vue
new file mode 100644
index 000000000..7905b0516
--- /dev/null
+++ b/playground/typescript-router-cypress/src/App.vue
@@ -0,0 +1,85 @@
+
+
+
+
+
+
+
+ You’ve successfully created a project with
+ Vite +
+ Vue 3. What's next?
+
+
+
+
+
diff --git a/playground/typescript-router-cypress/src/components/TheWelcome.vue b/playground/typescript-router-cypress/src/components/TheWelcome.vue
new file mode 100644
index 000000000..49d8f7354
--- /dev/null
+++ b/playground/typescript-router-cypress/src/components/TheWelcome.vue
@@ -0,0 +1,88 @@
+
+
+
+
+
+
+
+ Documentation
+
+ Vue’s
+ official documentation
+ provides you with all information you need to get started.
+
+
+
+
+
+
+ Tooling
+
+ This project is served and bundled with
+ Vite. The
+ recommended IDE setup is
+ VSCode +
+ Volar. If
+ you need to test your components and web pages, check out
+ Cypress and
+ Cypress Component Testing.
+
+
+
+ More instructions are available in README.md.
+
+
+
+
+
+
+ Ecosystem
+
+ Get official tools and libraries for your project:
+ Pinia,
+ Vue Router,
+ Vue Test Utils, and
+ Vue Dev Tools. If
+ you need more resources, we suggest paying
+ Awesome Vue
+ a visit.
+
+
+
+
+
+
+ Community
+
+ Got stuck? Ask your question on
+ Vue Land, our official
+ Discord server, or
+ StackOverflow. You should also subscribe to
+ our mailing list and follow
+ the official
+ @vuejs
+ twitter account for latest news in the Vue world.
+
+
+
+
+
+
+ Support Vue
+
+ As an independent project, Vue relies on community backing for its sustainability. You can help
+ us by
+ becoming a sponsor.
+
+
diff --git a/playground/typescript-router-cypress/src/components/WelcomeItem.vue b/playground/typescript-router-cypress/src/components/WelcomeItem.vue
new file mode 100644
index 000000000..6d7086aea
--- /dev/null
+++ b/playground/typescript-router-cypress/src/components/WelcomeItem.vue
@@ -0,0 +1,87 @@
+
+
+ You’ve successfully created a project with
+ Vite +
+ Vue 3. What's next?
+
+
+
+
+
diff --git a/playground/typescript-router-nightwatch/src/components/TheWelcome.vue b/playground/typescript-router-nightwatch/src/components/TheWelcome.vue
new file mode 100644
index 000000000..49d8f7354
--- /dev/null
+++ b/playground/typescript-router-nightwatch/src/components/TheWelcome.vue
@@ -0,0 +1,88 @@
+
+
+
+
+
+
+
+ Documentation
+
+ Vue’s
+ official documentation
+ provides you with all information you need to get started.
+
+
+
+
+
+
+ Tooling
+
+ This project is served and bundled with
+ Vite. The
+ recommended IDE setup is
+ VSCode +
+ Volar. If
+ you need to test your components and web pages, check out
+ Cypress and
+ Cypress Component Testing.
+
+
+
+ More instructions are available in README.md.
+
+
+
+
+
+
+ Ecosystem
+
+ Get official tools and libraries for your project:
+ Pinia,
+ Vue Router,
+ Vue Test Utils, and
+ Vue Dev Tools. If
+ you need more resources, we suggest paying
+ Awesome Vue
+ a visit.
+
+
+
+
+
+
+ Community
+
+ Got stuck? Ask your question on
+ Vue Land, our official
+ Discord server, or
+ StackOverflow. You should also subscribe to
+ our mailing list and follow
+ the official
+ @vuejs
+ twitter account for latest news in the Vue world.
+
+
+
+
+
+
+ Support Vue
+
+ As an independent project, Vue relies on community backing for its sustainability. You can help
+ us by
+ becoming a sponsor.
+
+
diff --git a/playground/typescript-router-nightwatch/src/components/WelcomeItem.vue b/playground/typescript-router-nightwatch/src/components/WelcomeItem.vue
new file mode 100644
index 000000000..6d7086aea
--- /dev/null
+++ b/playground/typescript-router-nightwatch/src/components/WelcomeItem.vue
@@ -0,0 +1,87 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/playground/typescript-router-nightwatch/src/components/__tests__/HelloWorld.spec.ts b/playground/typescript-router-nightwatch/src/components/__tests__/HelloWorld.spec.ts
new file mode 100644
index 000000000..810641e6e
--- /dev/null
+++ b/playground/typescript-router-nightwatch/src/components/__tests__/HelloWorld.spec.ts
@@ -0,0 +1,14 @@
+describe('Hello World', function () {
+ before((browser) => {
+ browser.init()
+ })
+
+ it('renders properly', async function () {
+ const welcomeComponent = await browser.mountComponent('/src/components/HelloWorld.vue', {props: {msg: 'Hello Nightwatch'}});
+
+ browser.expect.element(welcomeComponent).to.be.present;
+ browser.expect.element('h1').text.to.contain('Hello Nightwatch');
+ })
+
+ after((browser) => browser.end())
+})
diff --git a/playground/typescript-router-nightwatch/src/components/icons/IconCommunity.vue b/playground/typescript-router-nightwatch/src/components/icons/IconCommunity.vue
new file mode 100644
index 000000000..2dc8b0552
--- /dev/null
+++ b/playground/typescript-router-nightwatch/src/components/icons/IconCommunity.vue
@@ -0,0 +1,7 @@
+
+
+
diff --git a/playground/typescript-router-nightwatch/src/components/icons/IconDocumentation.vue b/playground/typescript-router-nightwatch/src/components/icons/IconDocumentation.vue
new file mode 100644
index 000000000..6d4791cfb
--- /dev/null
+++ b/playground/typescript-router-nightwatch/src/components/icons/IconDocumentation.vue
@@ -0,0 +1,7 @@
+
+
+
diff --git a/playground/typescript-router-nightwatch/src/components/icons/IconEcosystem.vue b/playground/typescript-router-nightwatch/src/components/icons/IconEcosystem.vue
new file mode 100644
index 000000000..c3a4f078c
--- /dev/null
+++ b/playground/typescript-router-nightwatch/src/components/icons/IconEcosystem.vue
@@ -0,0 +1,7 @@
+
+
+
diff --git a/playground/typescript-router-nightwatch/src/components/icons/IconSupport.vue b/playground/typescript-router-nightwatch/src/components/icons/IconSupport.vue
new file mode 100644
index 000000000..7452834d3
--- /dev/null
+++ b/playground/typescript-router-nightwatch/src/components/icons/IconSupport.vue
@@ -0,0 +1,7 @@
+
+
+
diff --git a/playground/typescript-router-nightwatch/src/components/icons/IconTooling.vue b/playground/typescript-router-nightwatch/src/components/icons/IconTooling.vue
new file mode 100644
index 000000000..660598d7c
--- /dev/null
+++ b/playground/typescript-router-nightwatch/src/components/icons/IconTooling.vue
@@ -0,0 +1,19 @@
+
+
+
+
diff --git a/playground/typescript-router-nightwatch/src/main.ts b/playground/typescript-router-nightwatch/src/main.ts
new file mode 100644
index 000000000..5a5dbdba7
--- /dev/null
+++ b/playground/typescript-router-nightwatch/src/main.ts
@@ -0,0 +1,11 @@
+import './assets/main.css'
+
+import { createApp } from 'vue'
+import App from './App.vue'
+import router from './router'
+
+const app = createApp(App)
+
+app.use(router)
+
+app.mount('#app')
diff --git a/playground/typescript-router-nightwatch/src/router/index.ts b/playground/typescript-router-nightwatch/src/router/index.ts
new file mode 100644
index 000000000..a49ae507f
--- /dev/null
+++ b/playground/typescript-router-nightwatch/src/router/index.ts
@@ -0,0 +1,23 @@
+import { createRouter, createWebHistory } from 'vue-router'
+import HomeView from '../views/HomeView.vue'
+
+const router = createRouter({
+ history: createWebHistory(import.meta.env.BASE_URL),
+ routes: [
+ {
+ path: '/',
+ name: 'home',
+ component: HomeView
+ },
+ {
+ path: '/about',
+ name: 'about',
+ // route level code-splitting
+ // this generates a separate chunk (About.[hash].js) for this route
+ // which is lazy-loaded when the route is visited.
+ component: () => import('../views/AboutView.vue')
+ }
+ ]
+})
+
+export default router
diff --git a/playground/typescript-router-nightwatch/src/views/AboutView.vue b/playground/typescript-router-nightwatch/src/views/AboutView.vue
new file mode 100644
index 000000000..756ad2a17
--- /dev/null
+++ b/playground/typescript-router-nightwatch/src/views/AboutView.vue
@@ -0,0 +1,15 @@
+
+
+
This is an about page
+
+
+
+
diff --git a/playground/typescript-router-nightwatch/src/views/HomeView.vue b/playground/typescript-router-nightwatch/src/views/HomeView.vue
new file mode 100644
index 000000000..d5c0217e4
--- /dev/null
+++ b/playground/typescript-router-nightwatch/src/views/HomeView.vue
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
diff --git a/playground/typescript-router-nightwatch/tests/e2e/example.ts b/playground/typescript-router-nightwatch/tests/e2e/example.ts
new file mode 100644
index 000000000..43be3fce1
--- /dev/null
+++ b/playground/typescript-router-nightwatch/tests/e2e/example.ts
@@ -0,0 +1,11 @@
+describe('My First Test', function () {
+ before((browser) => {
+ browser.init()
+ })
+
+ it('visits the app root url', function () {
+ browser.assert.textContains('.green', 'You did it!')
+ })
+
+ after((browser) => browser.end())
+})
diff --git a/playground/typescript-router-nightwatch/tsconfig.app.json b/playground/typescript-router-nightwatch/tsconfig.app.json
new file mode 100644
index 000000000..e14c754d3
--- /dev/null
+++ b/playground/typescript-router-nightwatch/tsconfig.app.json
@@ -0,0 +1,14 @@
+{
+ "extends": "@vue/tsconfig/tsconfig.dom.json",
+ "include": ["env.d.ts", "src/**/*", "src/**/*.vue"],
+ "exclude": ["src/**/__tests__/*"],
+ "compilerOptions": {
+ "composite": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
+
+ "baseUrl": ".",
+ "paths": {
+ "@/*": ["./src/*"]
+ }
+ }
+}
diff --git a/playground/typescript-router-nightwatch/tsconfig.json b/playground/typescript-router-nightwatch/tsconfig.json
new file mode 100644
index 000000000..5c385ae2c
--- /dev/null
+++ b/playground/typescript-router-nightwatch/tsconfig.json
@@ -0,0 +1,14 @@
+{
+ "files": [],
+ "references": [
+ {
+ "path": "./tsconfig.node.json"
+ },
+ {
+ "path": "./tsconfig.app.json"
+ },
+ {
+ "path": "./nightwatch/tsconfig.json"
+ }
+ ]
+}
diff --git a/playground/typescript-router-nightwatch/tsconfig.node.json b/playground/typescript-router-nightwatch/tsconfig.node.json
new file mode 100644
index 000000000..f09406303
--- /dev/null
+++ b/playground/typescript-router-nightwatch/tsconfig.node.json
@@ -0,0 +1,19 @@
+{
+ "extends": "@tsconfig/node20/tsconfig.json",
+ "include": [
+ "vite.config.*",
+ "vitest.config.*",
+ "cypress.config.*",
+ "nightwatch.conf.*",
+ "playwright.config.*"
+ ],
+ "compilerOptions": {
+ "composite": true,
+ "noEmit": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
+
+ "module": "ESNext",
+ "moduleResolution": "Bundler",
+ "types": ["node"]
+ }
+}
diff --git a/playground/typescript-router-nightwatch/vite.config.ts b/playground/typescript-router-nightwatch/vite.config.ts
new file mode 100644
index 000000000..fd83c5b21
--- /dev/null
+++ b/playground/typescript-router-nightwatch/vite.config.ts
@@ -0,0 +1,20 @@
+import { fileURLToPath, URL } from 'node:url'
+
+import { defineConfig } from 'vite'
+import vue from '@vitejs/plugin-vue'
+import nightwatchPlugin from 'vite-plugin-nightwatch'
+
+// https://vitejs.dev/config/
+export default defineConfig({
+ plugins: [
+ vue(),
+ nightwatchPlugin({
+ renderPage: './nightwatch/index.html'
+ }),
+ ],
+ resolve: {
+ alias: {
+ '@': fileURLToPath(new URL('./src', import.meta.url))
+ }
+ }
+})
diff --git a/playground/typescript-router-pinia-cypress/.gitignore b/playground/typescript-router-pinia-cypress/.gitignore
new file mode 100644
index 000000000..8ee54e8d3
--- /dev/null
+++ b/playground/typescript-router-pinia-cypress/.gitignore
@@ -0,0 +1,30 @@
+# 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/
+
+# Editor directories and files
+.vscode/*
+!.vscode/extensions.json
+.idea
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?
+
+*.tsbuildinfo
diff --git a/playground/typescript-router-pinia-cypress/README.md b/playground/typescript-router-pinia-cypress/README.md
new file mode 100644
index 000000000..5d2b74d4e
--- /dev/null
+++ b/playground/typescript-router-pinia-cypress/README.md
@@ -0,0 +1,62 @@
+# typescript-router-pinia-cypress
+
+This template should help get you started developing with Vue 3 in Vite.
+
+## Recommended IDE Setup
+
+[VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur) + [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin).
+
+## Type Support for `.vue` Imports in TS
+
+TypeScript cannot handle type information for `.vue` imports by default, so we replace the `tsc` CLI with `vue-tsc` for type checking. In editors, we need [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin) to make the TypeScript language service aware of `.vue` types.
+
+If the standalone TypeScript plugin doesn't feel fast enough to you, Volar has also implemented a [Take Over Mode](https://github.com/johnsoncodehk/volar/discussions/471#discussioncomment-1361669) that is more performant. You can enable it by the following steps:
+
+1. Disable the built-in TypeScript Extension
+ 1) Run `Extensions: Show Built-in Extensions` from VSCode's command palette
+ 2) Find `TypeScript and JavaScript Language Features`, right click and select `Disable (Workspace)`
+2. Reload the VSCode window by running `Developer: Reload Window` from the command palette.
+
+## Customize configuration
+
+See [Vite Configuration Reference](https://vitejs.dev/config/).
+
+## Project Setup
+
+```sh
+pnpm install
+```
+
+### Compile and Hot-Reload for Development
+
+```sh
+pnpm dev
+```
+
+### Type-Check, Compile and Minify for Production
+
+```sh
+pnpm build
+```
+
+### Run Headed Component Tests with [Cypress Component Testing](https://on.cypress.io/component)
+
+```sh
+pnpm test:unit:dev # or `pnpm test:unit` for headless testing
+```
+
+### Run End-to-End Tests with [Cypress](https://www.cypress.io/)
+
+```sh
+pnpm test:e2e:dev
+```
+
+This runs the end-to-end tests against the Vite development server.
+It is much faster than the production build.
+
+But it's still recommended to test the production build with `test:e2e` before deploying (e.g. in CI environments):
+
+```sh
+pnpm build
+pnpm test:e2e
+```
diff --git a/playground/typescript-router-pinia-cypress/cypress.config.ts b/playground/typescript-router-pinia-cypress/cypress.config.ts
new file mode 100644
index 000000000..c8fac1298
--- /dev/null
+++ b/playground/typescript-router-pinia-cypress/cypress.config.ts
@@ -0,0 +1,15 @@
+import { defineConfig } from 'cypress'
+
+export default defineConfig({
+ e2e: {
+ specPattern: 'cypress/e2e/**/*.{cy,spec}.{js,jsx,ts,tsx}',
+ baseUrl: 'http://localhost:4173'
+ },
+ component: {
+ specPattern: 'src/**/__tests__/*.{cy,spec}.{js,ts,jsx,tsx}',
+ devServer: {
+ framework: 'vue',
+ bundler: 'vite'
+ }
+ }
+})
diff --git a/playground/typescript-router-pinia-cypress/cypress/e2e/example.cy.ts b/playground/typescript-router-pinia-cypress/cypress/e2e/example.cy.ts
new file mode 100644
index 000000000..7554c35d8
--- /dev/null
+++ b/playground/typescript-router-pinia-cypress/cypress/e2e/example.cy.ts
@@ -0,0 +1,8 @@
+// https://on.cypress.io/api
+
+describe('My First Test', () => {
+ it('visits the app root url', () => {
+ cy.visit('/')
+ cy.contains('h1', 'You did it!')
+ })
+})
diff --git a/playground/typescript-router-pinia-cypress/cypress/e2e/tsconfig.json b/playground/typescript-router-pinia-cypress/cypress/e2e/tsconfig.json
new file mode 100644
index 000000000..37748feb7
--- /dev/null
+++ b/playground/typescript-router-pinia-cypress/cypress/e2e/tsconfig.json
@@ -0,0 +1,10 @@
+{
+ "extends": "@vue/tsconfig/tsconfig.dom.json",
+ "include": ["./**/*", "../support/**/*"],
+ "compilerOptions": {
+ "isolatedModules": false,
+ "target": "es5",
+ "lib": ["es5", "dom"],
+ "types": ["cypress"]
+ }
+}
diff --git a/playground/typescript-router-pinia-cypress/cypress/fixtures/example.json b/playground/typescript-router-pinia-cypress/cypress/fixtures/example.json
new file mode 100644
index 000000000..02e425437
--- /dev/null
+++ b/playground/typescript-router-pinia-cypress/cypress/fixtures/example.json
@@ -0,0 +1,5 @@
+{
+ "name": "Using fixtures to represent data",
+ "email": "hello@cypress.io",
+ "body": "Fixtures are a great way to mock data for responses to routes"
+}
diff --git a/playground/typescript-router-pinia-cypress/cypress/support/commands.ts b/playground/typescript-router-pinia-cypress/cypress/support/commands.ts
new file mode 100644
index 000000000..9b7bb8e25
--- /dev/null
+++ b/playground/typescript-router-pinia-cypress/cypress/support/commands.ts
@@ -0,0 +1,39 @@
+///
+// ***********************************************
+// This example commands.ts shows you how to
+// create various custom commands and overwrite
+// existing commands.
+//
+// For more comprehensive examples of custom
+// commands please read more here:
+// https://on.cypress.io/custom-commands
+// ***********************************************
+//
+//
+// -- This is a parent command --
+// Cypress.Commands.add('login', (email, password) => { ... })
+//
+//
+// -- This is a child command --
+// Cypress.Commands.add('drag', { prevSubject: 'element'}, (subject, options) => { ... })
+//
+//
+// -- This is a dual command --
+// Cypress.Commands.add('dismiss', { prevSubject: 'optional'}, (subject, options) => { ... })
+//
+//
+// -- This will overwrite an existing command --
+// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... })
+//
+// declare global {
+// namespace Cypress {
+// interface Chainable {
+// login(email: string, password: string): Chainable
+// drag(subject: string, options?: Partial): Chainable
+// dismiss(subject: string, options?: Partial): Chainable
+// visit(originalFn: CommandOriginalFn, url: string, options: Partial): Chainable
+// }
+// }
+// }
+
+export {}
diff --git a/playground/typescript-router-pinia-cypress/cypress/support/component-index.html b/playground/typescript-router-pinia-cypress/cypress/support/component-index.html
new file mode 100644
index 000000000..5f9622ae2
--- /dev/null
+++ b/playground/typescript-router-pinia-cypress/cypress/support/component-index.html
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+ Components App
+
+
+
+
+
diff --git a/playground/typescript-router-pinia-cypress/cypress/support/component.ts b/playground/typescript-router-pinia-cypress/cypress/support/component.ts
new file mode 100644
index 000000000..04e4c352b
--- /dev/null
+++ b/playground/typescript-router-pinia-cypress/cypress/support/component.ts
@@ -0,0 +1,43 @@
+// ***********************************************************
+// This example support/component.ts is processed and
+// loaded automatically before your test files.
+//
+// This is a great place to put global configuration and
+// behavior that modifies Cypress.
+//
+// You can change the location of this file or turn off
+// automatically serving support files with the
+// 'supportFile' configuration option.
+//
+// You can read more here:
+// https://on.cypress.io/configuration
+// ***********************************************************
+
+// Import commands.js using ES2015 syntax:
+import './commands'
+
+// Alternatively you can use CommonJS syntax:
+// require('./commands')
+
+// Import global styles
+import '@/assets/main.css'
+
+import { mount } from 'cypress/vue'
+
+// Augment the Cypress namespace to include type definitions for
+// your custom command.
+// Alternatively, can be defined in cypress/support/component.d.ts
+// with a at the top of your spec.
+/* eslint-disable @typescript-eslint/no-namespace */
+declare global {
+ namespace Cypress {
+ interface Chainable {
+ mount: typeof mount
+ }
+ }
+}
+
+Cypress.Commands.add('mount', mount)
+
+// Example use:
+// cy.mount(MyComponent)
diff --git a/playground/typescript-router-pinia-cypress/cypress/support/e2e.ts b/playground/typescript-router-pinia-cypress/cypress/support/e2e.ts
new file mode 100644
index 000000000..d68db96df
--- /dev/null
+++ b/playground/typescript-router-pinia-cypress/cypress/support/e2e.ts
@@ -0,0 +1,20 @@
+// ***********************************************************
+// This example support/index.js is processed and
+// loaded automatically before your test files.
+//
+// This is a great place to put global configuration and
+// behavior that modifies Cypress.
+//
+// You can change the location of this file or turn off
+// automatically serving support files with the
+// 'supportFile' configuration option.
+//
+// You can read more here:
+// https://on.cypress.io/configuration
+// ***********************************************************
+
+// Import commands.js using ES2015 syntax:
+import './commands'
+
+// Alternatively you can use CommonJS syntax:
+// require('./commands')
diff --git a/playground/typescript-router-pinia-cypress/env.d.ts b/playground/typescript-router-pinia-cypress/env.d.ts
new file mode 100644
index 000000000..11f02fe2a
--- /dev/null
+++ b/playground/typescript-router-pinia-cypress/env.d.ts
@@ -0,0 +1 @@
+///
diff --git a/playground/typescript-router-pinia-cypress/index.html b/playground/typescript-router-pinia-cypress/index.html
new file mode 100644
index 000000000..a88854489
--- /dev/null
+++ b/playground/typescript-router-pinia-cypress/index.html
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+ Vite App
+
+
+
+
+
+
diff --git a/playground/typescript-router-pinia-cypress/package.json b/playground/typescript-router-pinia-cypress/package.json
new file mode 100644
index 000000000..ead9d1571
--- /dev/null
+++ b/playground/typescript-router-pinia-cypress/package.json
@@ -0,0 +1,34 @@
+{
+ "name": "typescript-router-pinia-cypress",
+ "version": "0.0.0",
+ "private": true,
+ "type": "module",
+ "scripts": {
+ "dev": "vite",
+ "build": "run-p type-check \"build-only {@}\" --",
+ "preview": "vite preview",
+ "test:e2e": "start-server-and-test preview http://localhost:4173 'cypress run --e2e'",
+ "test:e2e:dev": "start-server-and-test 'vite dev --port 4173' http://localhost:4173 'cypress open --e2e'",
+ "test:unit": "cypress run --component",
+ "test:unit:dev": "cypress open --component",
+ "build-only": "vite build",
+ "type-check": "vue-tsc --build --force"
+ },
+ "dependencies": {
+ "pinia": "^2.1.7",
+ "vue": "^3.4.15",
+ "vue-router": "^4.2.5"
+ },
+ "devDependencies": {
+ "@tsconfig/node20": "^20.1.2",
+ "@types/node": "^20.11.16",
+ "@vitejs/plugin-vue": "^5.0.3",
+ "@vue/tsconfig": "^0.5.1",
+ "cypress": "^13.6.4",
+ "npm-run-all2": "^6.1.2",
+ "start-server-and-test": "^2.0.3",
+ "typescript": "~5.3.0",
+ "vite": "^5.0.11",
+ "vue-tsc": "^1.8.27"
+ }
+}
diff --git a/playground/typescript-router-pinia-cypress/public/favicon.ico b/playground/typescript-router-pinia-cypress/public/favicon.ico
new file mode 100644
index 000000000..df36fcfb7
Binary files /dev/null and b/playground/typescript-router-pinia-cypress/public/favicon.ico differ
diff --git a/playground/typescript-router-pinia-cypress/src/App.vue b/playground/typescript-router-pinia-cypress/src/App.vue
new file mode 100644
index 000000000..7905b0516
--- /dev/null
+++ b/playground/typescript-router-pinia-cypress/src/App.vue
@@ -0,0 +1,85 @@
+
+
+
+
+
+
+
+ You’ve successfully created a project with
+ Vite +
+ Vue 3. What's next?
+
+
+
+
+
diff --git a/playground/typescript-router-pinia-cypress/src/components/TheWelcome.vue b/playground/typescript-router-pinia-cypress/src/components/TheWelcome.vue
new file mode 100644
index 000000000..49d8f7354
--- /dev/null
+++ b/playground/typescript-router-pinia-cypress/src/components/TheWelcome.vue
@@ -0,0 +1,88 @@
+
+
+
+
+
+
+
+ Documentation
+
+ Vue’s
+ official documentation
+ provides you with all information you need to get started.
+
+
+
+
+
+
+ Tooling
+
+ This project is served and bundled with
+ Vite. The
+ recommended IDE setup is
+ VSCode +
+ Volar. If
+ you need to test your components and web pages, check out
+ Cypress and
+ Cypress Component Testing.
+
+
+
+ More instructions are available in README.md.
+
+
+
+
+
+
+ Ecosystem
+
+ Get official tools and libraries for your project:
+ Pinia,
+ Vue Router,
+ Vue Test Utils, and
+ Vue Dev Tools. If
+ you need more resources, we suggest paying
+ Awesome Vue
+ a visit.
+
+
+
+
+
+
+ Community
+
+ Got stuck? Ask your question on
+ Vue Land, our official
+ Discord server, or
+ StackOverflow. You should also subscribe to
+ our mailing list and follow
+ the official
+ @vuejs
+ twitter account for latest news in the Vue world.
+
+
+
+
+
+
+ Support Vue
+
+ As an independent project, Vue relies on community backing for its sustainability. You can help
+ us by
+ becoming a sponsor.
+
+
diff --git a/playground/typescript-router-pinia-cypress/src/components/WelcomeItem.vue b/playground/typescript-router-pinia-cypress/src/components/WelcomeItem.vue
new file mode 100644
index 000000000..6d7086aea
--- /dev/null
+++ b/playground/typescript-router-pinia-cypress/src/components/WelcomeItem.vue
@@ -0,0 +1,87 @@
+
+
+ You’ve successfully created a project with
+ Vite +
+ Vue 3. What's next?
+
+
+
+
+
diff --git a/playground/typescript-router-pinia-nightwatch/src/components/TheWelcome.vue b/playground/typescript-router-pinia-nightwatch/src/components/TheWelcome.vue
new file mode 100644
index 000000000..49d8f7354
--- /dev/null
+++ b/playground/typescript-router-pinia-nightwatch/src/components/TheWelcome.vue
@@ -0,0 +1,88 @@
+
+
+
+
+
+
+
+ Documentation
+
+ Vue’s
+ official documentation
+ provides you with all information you need to get started.
+
+
+
+
+
+
+ Tooling
+
+ This project is served and bundled with
+ Vite. The
+ recommended IDE setup is
+ VSCode +
+ Volar. If
+ you need to test your components and web pages, check out
+ Cypress and
+ Cypress Component Testing.
+
+
+
+ More instructions are available in README.md.
+
+
+
+
+
+
+ Ecosystem
+
+ Get official tools and libraries for your project:
+ Pinia,
+ Vue Router,
+ Vue Test Utils, and
+ Vue Dev Tools. If
+ you need more resources, we suggest paying
+ Awesome Vue
+ a visit.
+
+
+
+
+
+
+ Community
+
+ Got stuck? Ask your question on
+ Vue Land, our official
+ Discord server, or
+ StackOverflow. You should also subscribe to
+ our mailing list and follow
+ the official
+ @vuejs
+ twitter account for latest news in the Vue world.
+
+
+
+
+
+
+ Support Vue
+
+ As an independent project, Vue relies on community backing for its sustainability. You can help
+ us by
+ becoming a sponsor.
+
+
diff --git a/playground/typescript-router-pinia-nightwatch/src/components/WelcomeItem.vue b/playground/typescript-router-pinia-nightwatch/src/components/WelcomeItem.vue
new file mode 100644
index 000000000..6d7086aea
--- /dev/null
+++ b/playground/typescript-router-pinia-nightwatch/src/components/WelcomeItem.vue
@@ -0,0 +1,87 @@
+
+
+ You’ve successfully created a project with
+ Vite +
+ Vue 3. What's next?
+
+
+
+
+
diff --git a/playground/typescript-router-pinia-playwright/src/components/TheWelcome.vue b/playground/typescript-router-pinia-playwright/src/components/TheWelcome.vue
new file mode 100644
index 000000000..49d8f7354
--- /dev/null
+++ b/playground/typescript-router-pinia-playwright/src/components/TheWelcome.vue
@@ -0,0 +1,88 @@
+
+
+
+
+
+
+
+ Documentation
+
+ Vue’s
+ official documentation
+ provides you with all information you need to get started.
+
+
+
+
+
+
+ Tooling
+
+ This project is served and bundled with
+ Vite. The
+ recommended IDE setup is
+ VSCode +
+ Volar. If
+ you need to test your components and web pages, check out
+ Cypress and
+ Cypress Component Testing.
+
+
+
+ More instructions are available in README.md.
+
+
+
+
+
+
+ Ecosystem
+
+ Get official tools and libraries for your project:
+ Pinia,
+ Vue Router,
+ Vue Test Utils, and
+ Vue Dev Tools. If
+ you need more resources, we suggest paying
+ Awesome Vue
+ a visit.
+
+
+
+
+
+
+ Community
+
+ Got stuck? Ask your question on
+ Vue Land, our official
+ Discord server, or
+ StackOverflow. You should also subscribe to
+ our mailing list and follow
+ the official
+ @vuejs
+ twitter account for latest news in the Vue world.
+
+
+
+
+
+
+ Support Vue
+
+ As an independent project, Vue relies on community backing for its sustainability. You can help
+ us by
+ becoming a sponsor.
+
+
diff --git a/playground/typescript-router-pinia-playwright/src/components/WelcomeItem.vue b/playground/typescript-router-pinia-playwright/src/components/WelcomeItem.vue
new file mode 100644
index 000000000..6d7086aea
--- /dev/null
+++ b/playground/typescript-router-pinia-playwright/src/components/WelcomeItem.vue
@@ -0,0 +1,87 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/playground/typescript-router-pinia-playwright/src/components/icons/IconCommunity.vue b/playground/typescript-router-pinia-playwright/src/components/icons/IconCommunity.vue
new file mode 100644
index 000000000..2dc8b0552
--- /dev/null
+++ b/playground/typescript-router-pinia-playwright/src/components/icons/IconCommunity.vue
@@ -0,0 +1,7 @@
+
+
+
diff --git a/playground/typescript-router-pinia-playwright/src/components/icons/IconDocumentation.vue b/playground/typescript-router-pinia-playwright/src/components/icons/IconDocumentation.vue
new file mode 100644
index 000000000..6d4791cfb
--- /dev/null
+++ b/playground/typescript-router-pinia-playwright/src/components/icons/IconDocumentation.vue
@@ -0,0 +1,7 @@
+
+
+
diff --git a/playground/typescript-router-pinia-playwright/src/components/icons/IconEcosystem.vue b/playground/typescript-router-pinia-playwright/src/components/icons/IconEcosystem.vue
new file mode 100644
index 000000000..c3a4f078c
--- /dev/null
+++ b/playground/typescript-router-pinia-playwright/src/components/icons/IconEcosystem.vue
@@ -0,0 +1,7 @@
+
+
+
diff --git a/playground/typescript-router-pinia-playwright/src/components/icons/IconSupport.vue b/playground/typescript-router-pinia-playwright/src/components/icons/IconSupport.vue
new file mode 100644
index 000000000..7452834d3
--- /dev/null
+++ b/playground/typescript-router-pinia-playwright/src/components/icons/IconSupport.vue
@@ -0,0 +1,7 @@
+
+
+
diff --git a/playground/typescript-router-pinia-playwright/src/components/icons/IconTooling.vue b/playground/typescript-router-pinia-playwright/src/components/icons/IconTooling.vue
new file mode 100644
index 000000000..660598d7c
--- /dev/null
+++ b/playground/typescript-router-pinia-playwright/src/components/icons/IconTooling.vue
@@ -0,0 +1,19 @@
+
+
+
+
diff --git a/playground/typescript-router-pinia-playwright/src/main.ts b/playground/typescript-router-pinia-playwright/src/main.ts
new file mode 100644
index 000000000..5dcad83c3
--- /dev/null
+++ b/playground/typescript-router-pinia-playwright/src/main.ts
@@ -0,0 +1,14 @@
+import './assets/main.css'
+
+import { createApp } from 'vue'
+import { createPinia } from 'pinia'
+
+import App from './App.vue'
+import router from './router'
+
+const app = createApp(App)
+
+app.use(createPinia())
+app.use(router)
+
+app.mount('#app')
diff --git a/playground/typescript-router-pinia-playwright/src/router/index.ts b/playground/typescript-router-pinia-playwright/src/router/index.ts
new file mode 100644
index 000000000..a49ae507f
--- /dev/null
+++ b/playground/typescript-router-pinia-playwright/src/router/index.ts
@@ -0,0 +1,23 @@
+import { createRouter, createWebHistory } from 'vue-router'
+import HomeView from '../views/HomeView.vue'
+
+const router = createRouter({
+ history: createWebHistory(import.meta.env.BASE_URL),
+ routes: [
+ {
+ path: '/',
+ name: 'home',
+ component: HomeView
+ },
+ {
+ path: '/about',
+ name: 'about',
+ // route level code-splitting
+ // this generates a separate chunk (About.[hash].js) for this route
+ // which is lazy-loaded when the route is visited.
+ component: () => import('../views/AboutView.vue')
+ }
+ ]
+})
+
+export default router
diff --git a/playground/typescript-router-pinia-playwright/src/stores/counter.ts b/playground/typescript-router-pinia-playwright/src/stores/counter.ts
new file mode 100644
index 000000000..b6757ba57
--- /dev/null
+++ b/playground/typescript-router-pinia-playwright/src/stores/counter.ts
@@ -0,0 +1,12 @@
+import { ref, computed } from 'vue'
+import { defineStore } from 'pinia'
+
+export const useCounterStore = defineStore('counter', () => {
+ const count = ref(0)
+ const doubleCount = computed(() => count.value * 2)
+ function increment() {
+ count.value++
+ }
+
+ return { count, doubleCount, increment }
+})
diff --git a/playground/typescript-router-pinia-playwright/src/views/AboutView.vue b/playground/typescript-router-pinia-playwright/src/views/AboutView.vue
new file mode 100644
index 000000000..756ad2a17
--- /dev/null
+++ b/playground/typescript-router-pinia-playwright/src/views/AboutView.vue
@@ -0,0 +1,15 @@
+
+
+
This is an about page
+
+
+
+
diff --git a/playground/typescript-router-pinia-playwright/src/views/HomeView.vue b/playground/typescript-router-pinia-playwright/src/views/HomeView.vue
new file mode 100644
index 000000000..d5c0217e4
--- /dev/null
+++ b/playground/typescript-router-pinia-playwright/src/views/HomeView.vue
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
diff --git a/playground/typescript-router-pinia-playwright/tsconfig.app.json b/playground/typescript-router-pinia-playwright/tsconfig.app.json
new file mode 100644
index 000000000..e14c754d3
--- /dev/null
+++ b/playground/typescript-router-pinia-playwright/tsconfig.app.json
@@ -0,0 +1,14 @@
+{
+ "extends": "@vue/tsconfig/tsconfig.dom.json",
+ "include": ["env.d.ts", "src/**/*", "src/**/*.vue"],
+ "exclude": ["src/**/__tests__/*"],
+ "compilerOptions": {
+ "composite": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
+
+ "baseUrl": ".",
+ "paths": {
+ "@/*": ["./src/*"]
+ }
+ }
+}
diff --git a/playground/typescript-router-pinia-playwright/tsconfig.json b/playground/typescript-router-pinia-playwright/tsconfig.json
new file mode 100644
index 000000000..66b5e5703
--- /dev/null
+++ b/playground/typescript-router-pinia-playwright/tsconfig.json
@@ -0,0 +1,11 @@
+{
+ "files": [],
+ "references": [
+ {
+ "path": "./tsconfig.node.json"
+ },
+ {
+ "path": "./tsconfig.app.json"
+ }
+ ]
+}
diff --git a/playground/typescript-router-pinia-playwright/tsconfig.node.json b/playground/typescript-router-pinia-playwright/tsconfig.node.json
new file mode 100644
index 000000000..f09406303
--- /dev/null
+++ b/playground/typescript-router-pinia-playwright/tsconfig.node.json
@@ -0,0 +1,19 @@
+{
+ "extends": "@tsconfig/node20/tsconfig.json",
+ "include": [
+ "vite.config.*",
+ "vitest.config.*",
+ "cypress.config.*",
+ "nightwatch.conf.*",
+ "playwright.config.*"
+ ],
+ "compilerOptions": {
+ "composite": true,
+ "noEmit": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
+
+ "module": "ESNext",
+ "moduleResolution": "Bundler",
+ "types": ["node"]
+ }
+}
diff --git a/playground/typescript-router-pinia-playwright/vite.config.ts b/playground/typescript-router-pinia-playwright/vite.config.ts
new file mode 100644
index 000000000..5c45e1d9b
--- /dev/null
+++ b/playground/typescript-router-pinia-playwright/vite.config.ts
@@ -0,0 +1,16 @@
+import { fileURLToPath, URL } from 'node:url'
+
+import { defineConfig } from 'vite'
+import vue from '@vitejs/plugin-vue'
+
+// https://vitejs.dev/config/
+export default defineConfig({
+ plugins: [
+ vue(),
+ ],
+ resolve: {
+ alias: {
+ '@': fileURLToPath(new URL('./src', import.meta.url))
+ }
+ }
+})
diff --git a/playground/typescript-router-pinia-vitest-cypress/.gitignore b/playground/typescript-router-pinia-vitest-cypress/.gitignore
new file mode 100644
index 000000000..8ee54e8d3
--- /dev/null
+++ b/playground/typescript-router-pinia-vitest-cypress/.gitignore
@@ -0,0 +1,30 @@
+# 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/
+
+# Editor directories and files
+.vscode/*
+!.vscode/extensions.json
+.idea
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?
+
+*.tsbuildinfo
diff --git a/playground/typescript-router-pinia-vitest-cypress/README.md b/playground/typescript-router-pinia-vitest-cypress/README.md
new file mode 100644
index 000000000..462f5441e
--- /dev/null
+++ b/playground/typescript-router-pinia-vitest-cypress/README.md
@@ -0,0 +1,62 @@
+# typescript-router-pinia-vitest-cypress
+
+This template should help get you started developing with Vue 3 in Vite.
+
+## Recommended IDE Setup
+
+[VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur) + [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin).
+
+## Type Support for `.vue` Imports in TS
+
+TypeScript cannot handle type information for `.vue` imports by default, so we replace the `tsc` CLI with `vue-tsc` for type checking. In editors, we need [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin) to make the TypeScript language service aware of `.vue` types.
+
+If the standalone TypeScript plugin doesn't feel fast enough to you, Volar has also implemented a [Take Over Mode](https://github.com/johnsoncodehk/volar/discussions/471#discussioncomment-1361669) that is more performant. You can enable it by the following steps:
+
+1. Disable the built-in TypeScript Extension
+ 1) Run `Extensions: Show Built-in Extensions` from VSCode's command palette
+ 2) Find `TypeScript and JavaScript Language Features`, right click and select `Disable (Workspace)`
+2. Reload the VSCode window by running `Developer: Reload Window` from the command palette.
+
+## Customize configuration
+
+See [Vite Configuration Reference](https://vitejs.dev/config/).
+
+## Project Setup
+
+```sh
+pnpm install
+```
+
+### Compile and Hot-Reload for Development
+
+```sh
+pnpm dev
+```
+
+### Type-Check, Compile and Minify for Production
+
+```sh
+pnpm build
+```
+
+### Run Unit Tests with [Vitest](https://vitest.dev/)
+
+```sh
+pnpm test:unit
+```
+
+### Run End-to-End Tests with [Cypress](https://www.cypress.io/)
+
+```sh
+pnpm test:e2e:dev
+```
+
+This runs the end-to-end tests against the Vite development server.
+It is much faster than the production build.
+
+But it's still recommended to test the production build with `test:e2e` before deploying (e.g. in CI environments):
+
+```sh
+pnpm build
+pnpm test:e2e
+```
diff --git a/playground/typescript-router-pinia-vitest-cypress/cypress.config.ts b/playground/typescript-router-pinia-vitest-cypress/cypress.config.ts
new file mode 100644
index 000000000..0f66080fd
--- /dev/null
+++ b/playground/typescript-router-pinia-vitest-cypress/cypress.config.ts
@@ -0,0 +1,8 @@
+import { defineConfig } from 'cypress'
+
+export default defineConfig({
+ e2e: {
+ specPattern: 'cypress/e2e/**/*.{cy,spec}.{js,jsx,ts,tsx}',
+ baseUrl: 'http://localhost:4173'
+ }
+})
diff --git a/playground/typescript-router-pinia-vitest-cypress/cypress/e2e/example.cy.ts b/playground/typescript-router-pinia-vitest-cypress/cypress/e2e/example.cy.ts
new file mode 100644
index 000000000..7554c35d8
--- /dev/null
+++ b/playground/typescript-router-pinia-vitest-cypress/cypress/e2e/example.cy.ts
@@ -0,0 +1,8 @@
+// https://on.cypress.io/api
+
+describe('My First Test', () => {
+ it('visits the app root url', () => {
+ cy.visit('/')
+ cy.contains('h1', 'You did it!')
+ })
+})
diff --git a/playground/typescript-router-pinia-vitest-cypress/cypress/e2e/tsconfig.json b/playground/typescript-router-pinia-vitest-cypress/cypress/e2e/tsconfig.json
new file mode 100644
index 000000000..37748feb7
--- /dev/null
+++ b/playground/typescript-router-pinia-vitest-cypress/cypress/e2e/tsconfig.json
@@ -0,0 +1,10 @@
+{
+ "extends": "@vue/tsconfig/tsconfig.dom.json",
+ "include": ["./**/*", "../support/**/*"],
+ "compilerOptions": {
+ "isolatedModules": false,
+ "target": "es5",
+ "lib": ["es5", "dom"],
+ "types": ["cypress"]
+ }
+}
diff --git a/playground/typescript-router-pinia-vitest-cypress/cypress/fixtures/example.json b/playground/typescript-router-pinia-vitest-cypress/cypress/fixtures/example.json
new file mode 100644
index 000000000..02e425437
--- /dev/null
+++ b/playground/typescript-router-pinia-vitest-cypress/cypress/fixtures/example.json
@@ -0,0 +1,5 @@
+{
+ "name": "Using fixtures to represent data",
+ "email": "hello@cypress.io",
+ "body": "Fixtures are a great way to mock data for responses to routes"
+}
diff --git a/playground/typescript-router-pinia-vitest-cypress/cypress/support/commands.ts b/playground/typescript-router-pinia-vitest-cypress/cypress/support/commands.ts
new file mode 100644
index 000000000..9b7bb8e25
--- /dev/null
+++ b/playground/typescript-router-pinia-vitest-cypress/cypress/support/commands.ts
@@ -0,0 +1,39 @@
+///
+// ***********************************************
+// This example commands.ts shows you how to
+// create various custom commands and overwrite
+// existing commands.
+//
+// For more comprehensive examples of custom
+// commands please read more here:
+// https://on.cypress.io/custom-commands
+// ***********************************************
+//
+//
+// -- This is a parent command --
+// Cypress.Commands.add('login', (email, password) => { ... })
+//
+//
+// -- This is a child command --
+// Cypress.Commands.add('drag', { prevSubject: 'element'}, (subject, options) => { ... })
+//
+//
+// -- This is a dual command --
+// Cypress.Commands.add('dismiss', { prevSubject: 'optional'}, (subject, options) => { ... })
+//
+//
+// -- This will overwrite an existing command --
+// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... })
+//
+// declare global {
+// namespace Cypress {
+// interface Chainable {
+// login(email: string, password: string): Chainable
+// drag(subject: string, options?: Partial): Chainable
+// dismiss(subject: string, options?: Partial): Chainable
+// visit(originalFn: CommandOriginalFn, url: string, options: Partial): Chainable
+// }
+// }
+// }
+
+export {}
diff --git a/playground/typescript-router-pinia-vitest-cypress/cypress/support/e2e.ts b/playground/typescript-router-pinia-vitest-cypress/cypress/support/e2e.ts
new file mode 100644
index 000000000..d68db96df
--- /dev/null
+++ b/playground/typescript-router-pinia-vitest-cypress/cypress/support/e2e.ts
@@ -0,0 +1,20 @@
+// ***********************************************************
+// This example support/index.js is processed and
+// loaded automatically before your test files.
+//
+// This is a great place to put global configuration and
+// behavior that modifies Cypress.
+//
+// You can change the location of this file or turn off
+// automatically serving support files with the
+// 'supportFile' configuration option.
+//
+// You can read more here:
+// https://on.cypress.io/configuration
+// ***********************************************************
+
+// Import commands.js using ES2015 syntax:
+import './commands'
+
+// Alternatively you can use CommonJS syntax:
+// require('./commands')
diff --git a/playground/typescript-router-pinia-vitest-cypress/env.d.ts b/playground/typescript-router-pinia-vitest-cypress/env.d.ts
new file mode 100644
index 000000000..11f02fe2a
--- /dev/null
+++ b/playground/typescript-router-pinia-vitest-cypress/env.d.ts
@@ -0,0 +1 @@
+///
diff --git a/playground/typescript-router-pinia-vitest-cypress/index.html b/playground/typescript-router-pinia-vitest-cypress/index.html
new file mode 100644
index 000000000..a88854489
--- /dev/null
+++ b/playground/typescript-router-pinia-vitest-cypress/index.html
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+ Vite App
+
+
+
+
+
+
diff --git a/playground/typescript-router-pinia-vitest-cypress/package.json b/playground/typescript-router-pinia-vitest-cypress/package.json
new file mode 100644
index 000000000..bc7a06fc4
--- /dev/null
+++ b/playground/typescript-router-pinia-vitest-cypress/package.json
@@ -0,0 +1,37 @@
+{
+ "name": "typescript-router-pinia-vitest-cypress",
+ "version": "0.0.0",
+ "private": true,
+ "type": "module",
+ "scripts": {
+ "dev": "vite",
+ "build": "run-p type-check \"build-only {@}\" --",
+ "preview": "vite preview",
+ "test:unit": "vitest",
+ "test:e2e": "start-server-and-test preview http://localhost:4173 'cypress run --e2e'",
+ "test:e2e:dev": "start-server-and-test 'vite dev --port 4173' http://localhost:4173 'cypress open --e2e'",
+ "build-only": "vite build",
+ "type-check": "vue-tsc --build --force"
+ },
+ "dependencies": {
+ "pinia": "^2.1.7",
+ "vue": "^3.4.15",
+ "vue-router": "^4.2.5"
+ },
+ "devDependencies": {
+ "@tsconfig/node20": "^20.1.2",
+ "@types/jsdom": "^21.1.6",
+ "@types/node": "^20.11.16",
+ "@vitejs/plugin-vue": "^5.0.3",
+ "@vue/test-utils": "^2.4.4",
+ "@vue/tsconfig": "^0.5.1",
+ "cypress": "^13.6.4",
+ "jsdom": "^24.0.0",
+ "npm-run-all2": "^6.1.2",
+ "start-server-and-test": "^2.0.3",
+ "typescript": "~5.3.0",
+ "vite": "^5.0.11",
+ "vitest": "^1.2.2",
+ "vue-tsc": "^1.8.27"
+ }
+}
diff --git a/playground/typescript-router-pinia-vitest-cypress/public/favicon.ico b/playground/typescript-router-pinia-vitest-cypress/public/favicon.ico
new file mode 100644
index 000000000..df36fcfb7
Binary files /dev/null and b/playground/typescript-router-pinia-vitest-cypress/public/favicon.ico differ
diff --git a/playground/typescript-router-pinia-vitest-cypress/src/App.vue b/playground/typescript-router-pinia-vitest-cypress/src/App.vue
new file mode 100644
index 000000000..7905b0516
--- /dev/null
+++ b/playground/typescript-router-pinia-vitest-cypress/src/App.vue
@@ -0,0 +1,85 @@
+
+
+
+
+
+
+
+ You’ve successfully created a project with
+ Vite +
+ Vue 3. What's next?
+
+
+
+
+
diff --git a/playground/typescript-router-pinia-vitest-cypress/src/components/TheWelcome.vue b/playground/typescript-router-pinia-vitest-cypress/src/components/TheWelcome.vue
new file mode 100644
index 000000000..49d8f7354
--- /dev/null
+++ b/playground/typescript-router-pinia-vitest-cypress/src/components/TheWelcome.vue
@@ -0,0 +1,88 @@
+
+
+
+
+
+
+
+ Documentation
+
+ Vue’s
+ official documentation
+ provides you with all information you need to get started.
+
+
+
+
+
+
+ Tooling
+
+ This project is served and bundled with
+ Vite. The
+ recommended IDE setup is
+ VSCode +
+ Volar. If
+ you need to test your components and web pages, check out
+ Cypress and
+ Cypress Component Testing.
+
+
+
+ More instructions are available in README.md.
+
+
+
+
+
+
+ Ecosystem
+
+ Get official tools and libraries for your project:
+ Pinia,
+ Vue Router,
+ Vue Test Utils, and
+ Vue Dev Tools. If
+ you need more resources, we suggest paying
+ Awesome Vue
+ a visit.
+
+
+
+
+
+
+ Community
+
+ Got stuck? Ask your question on
+ Vue Land, our official
+ Discord server, or
+ StackOverflow. You should also subscribe to
+ our mailing list and follow
+ the official
+ @vuejs
+ twitter account for latest news in the Vue world.
+
+
+
+
+
+
+ Support Vue
+
+ As an independent project, Vue relies on community backing for its sustainability. You can help
+ us by
+ becoming a sponsor.
+
+
diff --git a/playground/typescript-router-pinia-vitest-cypress/src/components/WelcomeItem.vue b/playground/typescript-router-pinia-vitest-cypress/src/components/WelcomeItem.vue
new file mode 100644
index 000000000..6d7086aea
--- /dev/null
+++ b/playground/typescript-router-pinia-vitest-cypress/src/components/WelcomeItem.vue
@@ -0,0 +1,87 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/playground/typescript-router-pinia-vitest-cypress/src/components/__tests__/HelloWorld.spec.ts b/playground/typescript-router-pinia-vitest-cypress/src/components/__tests__/HelloWorld.spec.ts
new file mode 100644
index 000000000..253320200
--- /dev/null
+++ b/playground/typescript-router-pinia-vitest-cypress/src/components/__tests__/HelloWorld.spec.ts
@@ -0,0 +1,11 @@
+import { describe, it, expect } from 'vitest'
+
+import { mount } from '@vue/test-utils'
+import HelloWorld from '../HelloWorld.vue'
+
+describe('HelloWorld', () => {
+ it('renders properly', () => {
+ const wrapper = mount(HelloWorld, { props: { msg: 'Hello Vitest' } })
+ expect(wrapper.text()).toContain('Hello Vitest')
+ })
+})
diff --git a/playground/typescript-router-pinia-vitest-cypress/src/components/icons/IconCommunity.vue b/playground/typescript-router-pinia-vitest-cypress/src/components/icons/IconCommunity.vue
new file mode 100644
index 000000000..2dc8b0552
--- /dev/null
+++ b/playground/typescript-router-pinia-vitest-cypress/src/components/icons/IconCommunity.vue
@@ -0,0 +1,7 @@
+
+
+
diff --git a/playground/typescript-router-pinia-vitest-cypress/src/components/icons/IconDocumentation.vue b/playground/typescript-router-pinia-vitest-cypress/src/components/icons/IconDocumentation.vue
new file mode 100644
index 000000000..6d4791cfb
--- /dev/null
+++ b/playground/typescript-router-pinia-vitest-cypress/src/components/icons/IconDocumentation.vue
@@ -0,0 +1,7 @@
+
+
+
diff --git a/playground/typescript-router-pinia-vitest-cypress/src/components/icons/IconEcosystem.vue b/playground/typescript-router-pinia-vitest-cypress/src/components/icons/IconEcosystem.vue
new file mode 100644
index 000000000..c3a4f078c
--- /dev/null
+++ b/playground/typescript-router-pinia-vitest-cypress/src/components/icons/IconEcosystem.vue
@@ -0,0 +1,7 @@
+
+
+
diff --git a/playground/typescript-router-pinia-vitest-cypress/src/components/icons/IconSupport.vue b/playground/typescript-router-pinia-vitest-cypress/src/components/icons/IconSupport.vue
new file mode 100644
index 000000000..7452834d3
--- /dev/null
+++ b/playground/typescript-router-pinia-vitest-cypress/src/components/icons/IconSupport.vue
@@ -0,0 +1,7 @@
+
+
+
diff --git a/playground/typescript-router-pinia-vitest-cypress/src/components/icons/IconTooling.vue b/playground/typescript-router-pinia-vitest-cypress/src/components/icons/IconTooling.vue
new file mode 100644
index 000000000..660598d7c
--- /dev/null
+++ b/playground/typescript-router-pinia-vitest-cypress/src/components/icons/IconTooling.vue
@@ -0,0 +1,19 @@
+
+
+
+
diff --git a/playground/typescript-router-pinia-vitest-cypress/src/main.ts b/playground/typescript-router-pinia-vitest-cypress/src/main.ts
new file mode 100644
index 000000000..5dcad83c3
--- /dev/null
+++ b/playground/typescript-router-pinia-vitest-cypress/src/main.ts
@@ -0,0 +1,14 @@
+import './assets/main.css'
+
+import { createApp } from 'vue'
+import { createPinia } from 'pinia'
+
+import App from './App.vue'
+import router from './router'
+
+const app = createApp(App)
+
+app.use(createPinia())
+app.use(router)
+
+app.mount('#app')
diff --git a/playground/typescript-router-pinia-vitest-cypress/src/router/index.ts b/playground/typescript-router-pinia-vitest-cypress/src/router/index.ts
new file mode 100644
index 000000000..a49ae507f
--- /dev/null
+++ b/playground/typescript-router-pinia-vitest-cypress/src/router/index.ts
@@ -0,0 +1,23 @@
+import { createRouter, createWebHistory } from 'vue-router'
+import HomeView from '../views/HomeView.vue'
+
+const router = createRouter({
+ history: createWebHistory(import.meta.env.BASE_URL),
+ routes: [
+ {
+ path: '/',
+ name: 'home',
+ component: HomeView
+ },
+ {
+ path: '/about',
+ name: 'about',
+ // route level code-splitting
+ // this generates a separate chunk (About.[hash].js) for this route
+ // which is lazy-loaded when the route is visited.
+ component: () => import('../views/AboutView.vue')
+ }
+ ]
+})
+
+export default router
diff --git a/playground/typescript-router-pinia-vitest-cypress/src/stores/counter.ts b/playground/typescript-router-pinia-vitest-cypress/src/stores/counter.ts
new file mode 100644
index 000000000..b6757ba57
--- /dev/null
+++ b/playground/typescript-router-pinia-vitest-cypress/src/stores/counter.ts
@@ -0,0 +1,12 @@
+import { ref, computed } from 'vue'
+import { defineStore } from 'pinia'
+
+export const useCounterStore = defineStore('counter', () => {
+ const count = ref(0)
+ const doubleCount = computed(() => count.value * 2)
+ function increment() {
+ count.value++
+ }
+
+ return { count, doubleCount, increment }
+})
diff --git a/playground/typescript-router-pinia-vitest-cypress/src/views/AboutView.vue b/playground/typescript-router-pinia-vitest-cypress/src/views/AboutView.vue
new file mode 100644
index 000000000..756ad2a17
--- /dev/null
+++ b/playground/typescript-router-pinia-vitest-cypress/src/views/AboutView.vue
@@ -0,0 +1,15 @@
+
+
+
This is an about page
+
+
+
+
diff --git a/playground/typescript-router-pinia-vitest-cypress/src/views/HomeView.vue b/playground/typescript-router-pinia-vitest-cypress/src/views/HomeView.vue
new file mode 100644
index 000000000..d5c0217e4
--- /dev/null
+++ b/playground/typescript-router-pinia-vitest-cypress/src/views/HomeView.vue
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
diff --git a/playground/typescript-router-pinia-vitest-cypress/tsconfig.app.json b/playground/typescript-router-pinia-vitest-cypress/tsconfig.app.json
new file mode 100644
index 000000000..e14c754d3
--- /dev/null
+++ b/playground/typescript-router-pinia-vitest-cypress/tsconfig.app.json
@@ -0,0 +1,14 @@
+{
+ "extends": "@vue/tsconfig/tsconfig.dom.json",
+ "include": ["env.d.ts", "src/**/*", "src/**/*.vue"],
+ "exclude": ["src/**/__tests__/*"],
+ "compilerOptions": {
+ "composite": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
+
+ "baseUrl": ".",
+ "paths": {
+ "@/*": ["./src/*"]
+ }
+ }
+}
diff --git a/playground/typescript-router-pinia-vitest-cypress/tsconfig.json b/playground/typescript-router-pinia-vitest-cypress/tsconfig.json
new file mode 100644
index 000000000..5304731b8
--- /dev/null
+++ b/playground/typescript-router-pinia-vitest-cypress/tsconfig.json
@@ -0,0 +1,17 @@
+{
+ "files": [],
+ "references": [
+ {
+ "path": "./tsconfig.node.json"
+ },
+ {
+ "path": "./tsconfig.app.json"
+ },
+ {
+ "path": "./tsconfig.vitest.json"
+ }
+ ],
+ "compilerOptions": {
+ "module": "NodeNext"
+ }
+}
diff --git a/playground/typescript-router-pinia-vitest-cypress/tsconfig.node.json b/playground/typescript-router-pinia-vitest-cypress/tsconfig.node.json
new file mode 100644
index 000000000..f09406303
--- /dev/null
+++ b/playground/typescript-router-pinia-vitest-cypress/tsconfig.node.json
@@ -0,0 +1,19 @@
+{
+ "extends": "@tsconfig/node20/tsconfig.json",
+ "include": [
+ "vite.config.*",
+ "vitest.config.*",
+ "cypress.config.*",
+ "nightwatch.conf.*",
+ "playwright.config.*"
+ ],
+ "compilerOptions": {
+ "composite": true,
+ "noEmit": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
+
+ "module": "ESNext",
+ "moduleResolution": "Bundler",
+ "types": ["node"]
+ }
+}
diff --git a/playground/typescript-router-pinia-vitest-cypress/tsconfig.vitest.json b/playground/typescript-router-pinia-vitest-cypress/tsconfig.vitest.json
new file mode 100644
index 000000000..571995d11
--- /dev/null
+++ b/playground/typescript-router-pinia-vitest-cypress/tsconfig.vitest.json
@@ -0,0 +1,11 @@
+{
+ "extends": "./tsconfig.app.json",
+ "exclude": [],
+ "compilerOptions": {
+ "composite": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.vitest.tsbuildinfo",
+
+ "lib": [],
+ "types": ["node", "jsdom"]
+ }
+}
diff --git a/playground/typescript-router-pinia-vitest-cypress/vite.config.ts b/playground/typescript-router-pinia-vitest-cypress/vite.config.ts
new file mode 100644
index 000000000..5c45e1d9b
--- /dev/null
+++ b/playground/typescript-router-pinia-vitest-cypress/vite.config.ts
@@ -0,0 +1,16 @@
+import { fileURLToPath, URL } from 'node:url'
+
+import { defineConfig } from 'vite'
+import vue from '@vitejs/plugin-vue'
+
+// https://vitejs.dev/config/
+export default defineConfig({
+ plugins: [
+ vue(),
+ ],
+ resolve: {
+ alias: {
+ '@': fileURLToPath(new URL('./src', import.meta.url))
+ }
+ }
+})
diff --git a/playground/typescript-router-pinia-vitest-cypress/vitest.config.ts b/playground/typescript-router-pinia-vitest-cypress/vitest.config.ts
new file mode 100644
index 000000000..10067d578
--- /dev/null
+++ b/playground/typescript-router-pinia-vitest-cypress/vitest.config.ts
@@ -0,0 +1,14 @@
+import { fileURLToPath } from 'node:url'
+import { mergeConfig, defineConfig, configDefaults } from 'vitest/config'
+import viteConfig from './vite.config'
+
+export default mergeConfig(
+ viteConfig,
+ defineConfig({
+ test: {
+ environment: 'jsdom',
+ exclude: [...configDefaults.exclude, 'e2e/*'],
+ root: fileURLToPath(new URL('./', import.meta.url))
+ }
+ })
+)
diff --git a/playground/typescript-router-pinia-vitest-nightwatch/.gitignore b/playground/typescript-router-pinia-vitest-nightwatch/.gitignore
new file mode 100644
index 000000000..0b938f131
--- /dev/null
+++ b/playground/typescript-router-pinia-vitest-nightwatch/.gitignore
@@ -0,0 +1,33 @@
+# 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/
+
+# Editor directories and files
+.vscode/*
+!.vscode/extensions.json
+.idea
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?
+
+*.tsbuildinfo
+
+logs/
+tests_output/
diff --git a/playground/typescript-router-pinia-vitest-nightwatch/.vscode/extensions.json b/playground/typescript-router-pinia-vitest-nightwatch/.vscode/extensions.json
new file mode 100644
index 000000000..dd9668a5c
--- /dev/null
+++ b/playground/typescript-router-pinia-vitest-nightwatch/.vscode/extensions.json
@@ -0,0 +1,3 @@
+{
+ "recommendations": ["browserstackcom.nightwatch"]
+}
diff --git a/playground/typescript-router-pinia-vitest-nightwatch/README.md b/playground/typescript-router-pinia-vitest-nightwatch/README.md
new file mode 100644
index 000000000..60ac018ef
--- /dev/null
+++ b/playground/typescript-router-pinia-vitest-nightwatch/README.md
@@ -0,0 +1,69 @@
+# typescript-router-pinia-vitest-nightwatch
+
+This template should help get you started developing with Vue 3 in Vite.
+
+## Recommended IDE Setup
+
+[VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur) + [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin).
+
+## Type Support for `.vue` Imports in TS
+
+TypeScript cannot handle type information for `.vue` imports by default, so we replace the `tsc` CLI with `vue-tsc` for type checking. In editors, we need [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin) to make the TypeScript language service aware of `.vue` types.
+
+If the standalone TypeScript plugin doesn't feel fast enough to you, Volar has also implemented a [Take Over Mode](https://github.com/johnsoncodehk/volar/discussions/471#discussioncomment-1361669) that is more performant. You can enable it by the following steps:
+
+1. Disable the built-in TypeScript Extension
+ 1) Run `Extensions: Show Built-in Extensions` from VSCode's command palette
+ 2) Find `TypeScript and JavaScript Language Features`, right click and select `Disable (Workspace)`
+2. Reload the VSCode window by running `Developer: Reload Window` from the command palette.
+
+## Customize configuration
+
+See [Vite Configuration Reference](https://vitejs.dev/config/).
+
+## Project Setup
+
+```sh
+pnpm install
+```
+
+### Compile and Hot-Reload for Development
+
+```sh
+pnpm dev
+```
+
+### Type-Check, Compile and Minify for Production
+
+```sh
+pnpm build
+```
+
+### Run Unit Tests with [Vitest](https://vitest.dev/)
+
+```sh
+pnpm test:unit
+```
+
+### Run End-to-End Tests with [Nightwatch](https://nightwatchjs.org/)
+
+```sh
+# When using CI, the project must be built first.
+pnpm build
+
+# Runs the end-to-end tests
+pnpm test:e2e
+# Runs the tests only on Chrome
+pnpm test:e2e --env chrome
+# Runs the tests of a specific file
+pnpm test:e2e tests/e2e/example.ts
+# Runs the tests in debug mode
+pnpm test:e2e --debug
+```
+
+### Run Headed Component Tests with [Nightwatch Component Testing](https://nightwatchjs.org/guide/component-testing/introduction.html)
+
+```sh
+pnpm test:unit
+pnpm test:unit -- --headless # for headless testing
+```
diff --git a/playground/typescript-router-pinia-vitest-nightwatch/env.d.ts b/playground/typescript-router-pinia-vitest-nightwatch/env.d.ts
new file mode 100644
index 000000000..11f02fe2a
--- /dev/null
+++ b/playground/typescript-router-pinia-vitest-nightwatch/env.d.ts
@@ -0,0 +1 @@
+///
diff --git a/playground/typescript-router-pinia-vitest-nightwatch/index.html b/playground/typescript-router-pinia-vitest-nightwatch/index.html
new file mode 100644
index 000000000..a88854489
--- /dev/null
+++ b/playground/typescript-router-pinia-vitest-nightwatch/index.html
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+ Vite App
+
+
+
+
+
+
diff --git a/playground/typescript-router-pinia-vitest-nightwatch/nightwatch.conf.cjs b/playground/typescript-router-pinia-vitest-nightwatch/nightwatch.conf.cjs
new file mode 100644
index 000000000..542647e5e
--- /dev/null
+++ b/playground/typescript-router-pinia-vitest-nightwatch/nightwatch.conf.cjs
@@ -0,0 +1,153 @@
+//
+// Refer to the online docs for more details:
+// https://nightwatchjs.org/guide/configuration/nightwatch-configuration-file.html
+//
+// _ _ _ _ _ _ _
+// | \ | |(_) | | | | | | | |
+// | \| | _ __ _ | |__ | |_ __ __ __ _ | |_ ___ | |__
+// | . ` || | / _` || '_ \ | __|\ \ /\ / / / _` || __| / __|| '_ \
+// | |\ || || (_| || | | || |_ \ V V / | (_| || |_ | (__ | | | |
+// \_| \_/|_| \__, ||_| |_| \__| \_/\_/ \__,_| \__| \___||_| |_|
+// __/ |
+// |___/
+//
+
+module.exports = {
+ // An array of folders (excluding subfolders) where your tests are located;
+ // if this is not specified, the test source must be passed as the second argument to the test runner.
+ src_folders: [],
+
+ // See https://nightwatchjs.org/guide/concepts/page-object-model.html
+ page_objects_path: [],
+
+ // See https://nightwatchjs.org/guide/extending-nightwatch/adding-custom-commands.html
+ custom_commands_path: [],
+
+ // See https://nightwatchjs.org/guide/extending-nightwatch/adding-custom-assertions.html
+ custom_assertions_path: [],
+
+ // See https://nightwatchjs.org/guide/extending-nightwatch/adding-plugins.html
+ plugins: ['@nightwatch/vue'],
+
+ // See https://nightwatchjs.org/guide/concepts/test-globals.html#external-test-globals
+ globals_path: '',
+
+ vite_dev_server: {
+ start_vite: true,
+ port: process.env.CI ? 4173 : 5173
+ },
+
+ webdriver: {},
+
+ test_workers: {
+ enabled: true,
+ workers: 'auto'
+ },
+
+ test_settings: {
+ default: {
+ disable_error_log: false,
+ launch_url: `http://localhost:${process.env.CI ? '4173' : '5173'}`,
+
+ screenshots: {
+ enabled: false,
+ path: 'screens',
+ on_failure: true
+ },
+
+ desiredCapabilities: {
+ browserName: 'firefox'
+ },
+
+ webdriver: {
+ start_process: true,
+ server_path: ''
+ }
+ },
+
+ safari: {
+ desiredCapabilities: {
+ browserName: 'safari',
+ alwaysMatch: {
+ acceptInsecureCerts: false
+ }
+ },
+ webdriver: {
+ start_process: true,
+ server_path: ''
+ }
+ },
+
+ firefox: {
+ desiredCapabilities: {
+ browserName: 'firefox',
+ alwaysMatch: {
+ acceptInsecureCerts: true,
+ 'moz:firefoxOptions': {
+ args: [
+ // '-headless',
+ // '-verbose'
+ ]
+ }
+ }
+ },
+ webdriver: {
+ start_process: true,
+ server_path: '',
+ cli_args: [
+ // very verbose geckodriver logs
+ // '-vv'
+ ]
+ }
+ },
+
+ chrome: {
+ desiredCapabilities: {
+ browserName: 'chrome',
+ 'goog:chromeOptions': {
+ // More info on Chromedriver: https://sites.google.com/a/chromium.org/chromedriver/
+ //
+ // w3c:false tells Chromedriver to run using the legacy JSONWire protocol (not required in Chrome 78)
+ w3c: true,
+ args: [
+ //'--no-sandbox',
+ //'--ignore-certificate-errors',
+ //'--allow-insecure-localhost',
+ //'--headless'
+ ]
+ }
+ },
+
+ webdriver: {
+ start_process: true,
+ server_path: '',
+ cli_args: [
+ // --verbose
+ ]
+ }
+ },
+
+ edge: {
+ desiredCapabilities: {
+ browserName: 'MicrosoftEdge',
+ 'ms:edgeOptions': {
+ w3c: true,
+ // More info on EdgeDriver: https://docs.microsoft.com/en-us/microsoft-edge/webdriver-chromium/capabilities-edge-options
+ args: [
+ //'--headless'
+ ]
+ }
+ },
+
+ webdriver: {
+ start_process: true,
+ // Download msedgedriver from https://docs.microsoft.com/en-us/microsoft-edge/webdriver-chromium/
+ // and set the location below:
+ server_path: '',
+ cli_args: [
+ // --verbose
+ ]
+ }
+ }
+ }
+}
diff --git a/playground/typescript-router-pinia-vitest-nightwatch/nightwatch/nightwatch.d.ts b/playground/typescript-router-pinia-vitest-nightwatch/nightwatch/nightwatch.d.ts
new file mode 100644
index 000000000..616e63f9f
--- /dev/null
+++ b/playground/typescript-router-pinia-vitest-nightwatch/nightwatch/nightwatch.d.ts
@@ -0,0 +1,13 @@
+import { NightwatchCustomAssertions, NightwatchCustomCommands } from 'nightwatch'
+
+declare module 'nightwatch' {
+ interface NightwatchCustomAssertions {
+ // Add your custom assertions' types here
+ // elementHasCount: (selector: string, count: number) => NightwatchBrowser
+ }
+
+ interface NightwatchCustomCommands {
+ // Add your custom commands' types here
+ // strictClick: (selector: string) => NightwatchBrowser
+ }
+}
diff --git a/playground/typescript-router-pinia-vitest-nightwatch/nightwatch/tsconfig.json b/playground/typescript-router-pinia-vitest-nightwatch/nightwatch/tsconfig.json
new file mode 100644
index 000000000..8cd7ca1da
--- /dev/null
+++ b/playground/typescript-router-pinia-vitest-nightwatch/nightwatch/tsconfig.json
@@ -0,0 +1,20 @@
+{
+ "extends": "@tsconfig/node20/tsconfig.json",
+ "compilerOptions": {
+ "composite": true,
+ "noEmit": true,
+ "tsBuildInfoFile": "../node_modules/.tmp/tsconfig.nightwatch.tsbuildinfo",
+
+ "target": "ESNext",
+ "module": "commonjs",
+ "moduleResolution": "node",
+ "rootDir": "../",
+ "lib": ["ESNext", "dom"],
+ "types": ["nightwatch"]
+ },
+ "include": ["../node_modules/@nightwatch/**/*", "../src/components/**/*", "../tests/e2e/**/*"],
+ "ts-node": {
+ "transpileOnly": true
+ },
+ "files": ["nightwatch.d.ts"]
+}
diff --git a/playground/typescript-router-pinia-vitest-nightwatch/package.json b/playground/typescript-router-pinia-vitest-nightwatch/package.json
new file mode 100644
index 000000000..e89dd3757
--- /dev/null
+++ b/playground/typescript-router-pinia-vitest-nightwatch/package.json
@@ -0,0 +1,40 @@
+{
+ "name": "typescript-router-pinia-vitest-nightwatch",
+ "version": "0.0.0",
+ "private": true,
+ "type": "module",
+ "scripts": {
+ "dev": "vite",
+ "build": "run-p type-check \"build-only {@}\" --",
+ "preview": "vite preview",
+ "test:unit": "vitest",
+ "test:e2e": "nightwatch tests/e2e/*",
+ "build-only": "vite build",
+ "type-check": "vue-tsc --build --force"
+ },
+ "dependencies": {
+ "pinia": "^2.1.7",
+ "vue": "^3.4.15",
+ "vue-router": "^4.2.5"
+ },
+ "devDependencies": {
+ "@nightwatch/vue": "^3.1.0",
+ "@tsconfig/node20": "^20.1.2",
+ "@types/jsdom": "^21.1.6",
+ "@types/node": "^20.11.16",
+ "@vitejs/plugin-vue": "^5.0.3",
+ "@vue/test-utils": "^2.4.4",
+ "@vue/tsconfig": "^0.5.1",
+ "chromedriver": "^121.0.0",
+ "geckodriver": "^4.3.2",
+ "jsdom": "^24.0.0",
+ "nightwatch": "^3.4.0",
+ "npm-run-all2": "^6.1.2",
+ "ts-node": "^10.9.2",
+ "typescript": "~5.3.0",
+ "vite": "^5.0.11",
+ "vite-plugin-nightwatch": "^0.4.6",
+ "vitest": "^1.2.2",
+ "vue-tsc": "^1.8.27"
+ }
+}
diff --git a/playground/typescript-router-pinia-vitest-nightwatch/public/favicon.ico b/playground/typescript-router-pinia-vitest-nightwatch/public/favicon.ico
new file mode 100644
index 000000000..df36fcfb7
Binary files /dev/null and b/playground/typescript-router-pinia-vitest-nightwatch/public/favicon.ico differ
diff --git a/playground/typescript-router-pinia-vitest-nightwatch/src/App.vue b/playground/typescript-router-pinia-vitest-nightwatch/src/App.vue
new file mode 100644
index 000000000..7905b0516
--- /dev/null
+++ b/playground/typescript-router-pinia-vitest-nightwatch/src/App.vue
@@ -0,0 +1,85 @@
+
+
+
+
+
+
+
+ You’ve successfully created a project with
+ Vite +
+ Vue 3. What's next?
+
+
+
+
+
diff --git a/playground/typescript-router-pinia-vitest-nightwatch/src/components/TheWelcome.vue b/playground/typescript-router-pinia-vitest-nightwatch/src/components/TheWelcome.vue
new file mode 100644
index 000000000..49d8f7354
--- /dev/null
+++ b/playground/typescript-router-pinia-vitest-nightwatch/src/components/TheWelcome.vue
@@ -0,0 +1,88 @@
+
+
+
+
+
+
+
+ Documentation
+
+ Vue’s
+ official documentation
+ provides you with all information you need to get started.
+
+
+
+
+
+
+ Tooling
+
+ This project is served and bundled with
+ Vite. The
+ recommended IDE setup is
+ VSCode +
+ Volar. If
+ you need to test your components and web pages, check out
+ Cypress and
+ Cypress Component Testing.
+
+
+
+ More instructions are available in README.md.
+
+
+
+
+
+
+ Ecosystem
+
+ Get official tools and libraries for your project:
+ Pinia,
+ Vue Router,
+ Vue Test Utils, and
+ Vue Dev Tools. If
+ you need more resources, we suggest paying
+ Awesome Vue
+ a visit.
+
+
+
+
+
+
+ Community
+
+ Got stuck? Ask your question on
+ Vue Land, our official
+ Discord server, or
+ StackOverflow. You should also subscribe to
+ our mailing list and follow
+ the official
+ @vuejs
+ twitter account for latest news in the Vue world.
+
+
+
+
+
+
+ Support Vue
+
+ As an independent project, Vue relies on community backing for its sustainability. You can help
+ us by
+ becoming a sponsor.
+
+
diff --git a/playground/typescript-router-pinia-vitest-nightwatch/src/components/WelcomeItem.vue b/playground/typescript-router-pinia-vitest-nightwatch/src/components/WelcomeItem.vue
new file mode 100644
index 000000000..6d7086aea
--- /dev/null
+++ b/playground/typescript-router-pinia-vitest-nightwatch/src/components/WelcomeItem.vue
@@ -0,0 +1,87 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/playground/typescript-router-pinia-vitest-nightwatch/src/components/__tests__/HelloWorld.spec.ts b/playground/typescript-router-pinia-vitest-nightwatch/src/components/__tests__/HelloWorld.spec.ts
new file mode 100644
index 000000000..253320200
--- /dev/null
+++ b/playground/typescript-router-pinia-vitest-nightwatch/src/components/__tests__/HelloWorld.spec.ts
@@ -0,0 +1,11 @@
+import { describe, it, expect } from 'vitest'
+
+import { mount } from '@vue/test-utils'
+import HelloWorld from '../HelloWorld.vue'
+
+describe('HelloWorld', () => {
+ it('renders properly', () => {
+ const wrapper = mount(HelloWorld, { props: { msg: 'Hello Vitest' } })
+ expect(wrapper.text()).toContain('Hello Vitest')
+ })
+})
diff --git a/playground/typescript-router-pinia-vitest-nightwatch/src/components/icons/IconCommunity.vue b/playground/typescript-router-pinia-vitest-nightwatch/src/components/icons/IconCommunity.vue
new file mode 100644
index 000000000..2dc8b0552
--- /dev/null
+++ b/playground/typescript-router-pinia-vitest-nightwatch/src/components/icons/IconCommunity.vue
@@ -0,0 +1,7 @@
+
+
+
diff --git a/playground/typescript-router-pinia-vitest-nightwatch/src/components/icons/IconDocumentation.vue b/playground/typescript-router-pinia-vitest-nightwatch/src/components/icons/IconDocumentation.vue
new file mode 100644
index 000000000..6d4791cfb
--- /dev/null
+++ b/playground/typescript-router-pinia-vitest-nightwatch/src/components/icons/IconDocumentation.vue
@@ -0,0 +1,7 @@
+
+
+
diff --git a/playground/typescript-router-pinia-vitest-nightwatch/src/components/icons/IconEcosystem.vue b/playground/typescript-router-pinia-vitest-nightwatch/src/components/icons/IconEcosystem.vue
new file mode 100644
index 000000000..c3a4f078c
--- /dev/null
+++ b/playground/typescript-router-pinia-vitest-nightwatch/src/components/icons/IconEcosystem.vue
@@ -0,0 +1,7 @@
+
+
+
diff --git a/playground/typescript-router-pinia-vitest-nightwatch/src/components/icons/IconSupport.vue b/playground/typescript-router-pinia-vitest-nightwatch/src/components/icons/IconSupport.vue
new file mode 100644
index 000000000..7452834d3
--- /dev/null
+++ b/playground/typescript-router-pinia-vitest-nightwatch/src/components/icons/IconSupport.vue
@@ -0,0 +1,7 @@
+
+
+
diff --git a/playground/typescript-router-pinia-vitest-nightwatch/src/components/icons/IconTooling.vue b/playground/typescript-router-pinia-vitest-nightwatch/src/components/icons/IconTooling.vue
new file mode 100644
index 000000000..660598d7c
--- /dev/null
+++ b/playground/typescript-router-pinia-vitest-nightwatch/src/components/icons/IconTooling.vue
@@ -0,0 +1,19 @@
+
+
+
+
diff --git a/playground/typescript-router-pinia-vitest-nightwatch/src/main.ts b/playground/typescript-router-pinia-vitest-nightwatch/src/main.ts
new file mode 100644
index 000000000..5dcad83c3
--- /dev/null
+++ b/playground/typescript-router-pinia-vitest-nightwatch/src/main.ts
@@ -0,0 +1,14 @@
+import './assets/main.css'
+
+import { createApp } from 'vue'
+import { createPinia } from 'pinia'
+
+import App from './App.vue'
+import router from './router'
+
+const app = createApp(App)
+
+app.use(createPinia())
+app.use(router)
+
+app.mount('#app')
diff --git a/playground/typescript-router-pinia-vitest-nightwatch/src/router/index.ts b/playground/typescript-router-pinia-vitest-nightwatch/src/router/index.ts
new file mode 100644
index 000000000..a49ae507f
--- /dev/null
+++ b/playground/typescript-router-pinia-vitest-nightwatch/src/router/index.ts
@@ -0,0 +1,23 @@
+import { createRouter, createWebHistory } from 'vue-router'
+import HomeView from '../views/HomeView.vue'
+
+const router = createRouter({
+ history: createWebHistory(import.meta.env.BASE_URL),
+ routes: [
+ {
+ path: '/',
+ name: 'home',
+ component: HomeView
+ },
+ {
+ path: '/about',
+ name: 'about',
+ // route level code-splitting
+ // this generates a separate chunk (About.[hash].js) for this route
+ // which is lazy-loaded when the route is visited.
+ component: () => import('../views/AboutView.vue')
+ }
+ ]
+})
+
+export default router
diff --git a/playground/typescript-router-pinia-vitest-nightwatch/src/stores/counter.ts b/playground/typescript-router-pinia-vitest-nightwatch/src/stores/counter.ts
new file mode 100644
index 000000000..b6757ba57
--- /dev/null
+++ b/playground/typescript-router-pinia-vitest-nightwatch/src/stores/counter.ts
@@ -0,0 +1,12 @@
+import { ref, computed } from 'vue'
+import { defineStore } from 'pinia'
+
+export const useCounterStore = defineStore('counter', () => {
+ const count = ref(0)
+ const doubleCount = computed(() => count.value * 2)
+ function increment() {
+ count.value++
+ }
+
+ return { count, doubleCount, increment }
+})
diff --git a/playground/typescript-router-pinia-vitest-nightwatch/src/views/AboutView.vue b/playground/typescript-router-pinia-vitest-nightwatch/src/views/AboutView.vue
new file mode 100644
index 000000000..756ad2a17
--- /dev/null
+++ b/playground/typescript-router-pinia-vitest-nightwatch/src/views/AboutView.vue
@@ -0,0 +1,15 @@
+
+
+
This is an about page
+
+
+
+
diff --git a/playground/typescript-router-pinia-vitest-nightwatch/src/views/HomeView.vue b/playground/typescript-router-pinia-vitest-nightwatch/src/views/HomeView.vue
new file mode 100644
index 000000000..d5c0217e4
--- /dev/null
+++ b/playground/typescript-router-pinia-vitest-nightwatch/src/views/HomeView.vue
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
diff --git a/playground/typescript-router-pinia-vitest-nightwatch/tests/e2e/example.ts b/playground/typescript-router-pinia-vitest-nightwatch/tests/e2e/example.ts
new file mode 100644
index 000000000..43be3fce1
--- /dev/null
+++ b/playground/typescript-router-pinia-vitest-nightwatch/tests/e2e/example.ts
@@ -0,0 +1,11 @@
+describe('My First Test', function () {
+ before((browser) => {
+ browser.init()
+ })
+
+ it('visits the app root url', function () {
+ browser.assert.textContains('.green', 'You did it!')
+ })
+
+ after((browser) => browser.end())
+})
diff --git a/playground/typescript-router-pinia-vitest-nightwatch/tsconfig.app.json b/playground/typescript-router-pinia-vitest-nightwatch/tsconfig.app.json
new file mode 100644
index 000000000..e14c754d3
--- /dev/null
+++ b/playground/typescript-router-pinia-vitest-nightwatch/tsconfig.app.json
@@ -0,0 +1,14 @@
+{
+ "extends": "@vue/tsconfig/tsconfig.dom.json",
+ "include": ["env.d.ts", "src/**/*", "src/**/*.vue"],
+ "exclude": ["src/**/__tests__/*"],
+ "compilerOptions": {
+ "composite": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
+
+ "baseUrl": ".",
+ "paths": {
+ "@/*": ["./src/*"]
+ }
+ }
+}
diff --git a/playground/typescript-router-pinia-vitest-nightwatch/tsconfig.json b/playground/typescript-router-pinia-vitest-nightwatch/tsconfig.json
new file mode 100644
index 000000000..a5352e667
--- /dev/null
+++ b/playground/typescript-router-pinia-vitest-nightwatch/tsconfig.json
@@ -0,0 +1,17 @@
+{
+ "files": [],
+ "references": [
+ {
+ "path": "./tsconfig.node.json"
+ },
+ {
+ "path": "./tsconfig.app.json"
+ },
+ {
+ "path": "./tsconfig.vitest.json"
+ },
+ {
+ "path": "./nightwatch/tsconfig.json"
+ }
+ ]
+}
diff --git a/playground/typescript-router-pinia-vitest-nightwatch/tsconfig.node.json b/playground/typescript-router-pinia-vitest-nightwatch/tsconfig.node.json
new file mode 100644
index 000000000..f09406303
--- /dev/null
+++ b/playground/typescript-router-pinia-vitest-nightwatch/tsconfig.node.json
@@ -0,0 +1,19 @@
+{
+ "extends": "@tsconfig/node20/tsconfig.json",
+ "include": [
+ "vite.config.*",
+ "vitest.config.*",
+ "cypress.config.*",
+ "nightwatch.conf.*",
+ "playwright.config.*"
+ ],
+ "compilerOptions": {
+ "composite": true,
+ "noEmit": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
+
+ "module": "ESNext",
+ "moduleResolution": "Bundler",
+ "types": ["node"]
+ }
+}
diff --git a/playground/typescript-router-pinia-vitest-nightwatch/tsconfig.vitest.json b/playground/typescript-router-pinia-vitest-nightwatch/tsconfig.vitest.json
new file mode 100644
index 000000000..571995d11
--- /dev/null
+++ b/playground/typescript-router-pinia-vitest-nightwatch/tsconfig.vitest.json
@@ -0,0 +1,11 @@
+{
+ "extends": "./tsconfig.app.json",
+ "exclude": [],
+ "compilerOptions": {
+ "composite": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.vitest.tsbuildinfo",
+
+ "lib": [],
+ "types": ["node", "jsdom"]
+ }
+}
diff --git a/playground/typescript-router-pinia-vitest-nightwatch/vite.config.ts b/playground/typescript-router-pinia-vitest-nightwatch/vite.config.ts
new file mode 100644
index 000000000..be3cb9c57
--- /dev/null
+++ b/playground/typescript-router-pinia-vitest-nightwatch/vite.config.ts
@@ -0,0 +1,18 @@
+import { fileURLToPath, URL } from 'node:url'
+
+import { defineConfig } from 'vite'
+import vue from '@vitejs/plugin-vue'
+import nightwatchPlugin from 'vite-plugin-nightwatch'
+
+// https://vitejs.dev/config/
+export default defineConfig({
+ plugins: [
+ vue(),
+ nightwatchPlugin(),
+ ],
+ resolve: {
+ alias: {
+ '@': fileURLToPath(new URL('./src', import.meta.url))
+ }
+ }
+})
diff --git a/playground/typescript-router-pinia-vitest-nightwatch/vitest.config.ts b/playground/typescript-router-pinia-vitest-nightwatch/vitest.config.ts
new file mode 100644
index 000000000..10067d578
--- /dev/null
+++ b/playground/typescript-router-pinia-vitest-nightwatch/vitest.config.ts
@@ -0,0 +1,14 @@
+import { fileURLToPath } from 'node:url'
+import { mergeConfig, defineConfig, configDefaults } from 'vitest/config'
+import viteConfig from './vite.config'
+
+export default mergeConfig(
+ viteConfig,
+ defineConfig({
+ test: {
+ environment: 'jsdom',
+ exclude: [...configDefaults.exclude, 'e2e/*'],
+ root: fileURLToPath(new URL('./', import.meta.url))
+ }
+ })
+)
diff --git a/playground/typescript-router-pinia-vitest-playwright/.gitignore b/playground/typescript-router-pinia-vitest-playwright/.gitignore
new file mode 100644
index 000000000..aef72d03c
--- /dev/null
+++ b/playground/typescript-router-pinia-vitest-playwright/.gitignore
@@ -0,0 +1,33 @@
+# 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/
+
+# Editor directories and files
+.vscode/*
+!.vscode/extensions.json
+.idea
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?
+
+*.tsbuildinfo
+
+test-results/
+playwright-report/
diff --git a/playground/typescript-router-pinia-vitest-playwright/.vscode/extensions.json b/playground/typescript-router-pinia-vitest-playwright/.vscode/extensions.json
new file mode 100644
index 000000000..7b3f8bdae
--- /dev/null
+++ b/playground/typescript-router-pinia-vitest-playwright/.vscode/extensions.json
@@ -0,0 +1,3 @@
+{
+ "recommendations": ["ms-playwright.playwright"]
+}
diff --git a/playground/typescript-router-pinia-vitest-playwright/README.md b/playground/typescript-router-pinia-vitest-playwright/README.md
new file mode 100644
index 000000000..cdff825bf
--- /dev/null
+++ b/playground/typescript-router-pinia-vitest-playwright/README.md
@@ -0,0 +1,65 @@
+# typescript-router-pinia-vitest-playwright
+
+This template should help get you started developing with Vue 3 in Vite.
+
+## Recommended IDE Setup
+
+[VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur) + [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin).
+
+## Type Support for `.vue` Imports in TS
+
+TypeScript cannot handle type information for `.vue` imports by default, so we replace the `tsc` CLI with `vue-tsc` for type checking. In editors, we need [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin) to make the TypeScript language service aware of `.vue` types.
+
+If the standalone TypeScript plugin doesn't feel fast enough to you, Volar has also implemented a [Take Over Mode](https://github.com/johnsoncodehk/volar/discussions/471#discussioncomment-1361669) that is more performant. You can enable it by the following steps:
+
+1. Disable the built-in TypeScript Extension
+ 1) Run `Extensions: Show Built-in Extensions` from VSCode's command palette
+ 2) Find `TypeScript and JavaScript Language Features`, right click and select `Disable (Workspace)`
+2. Reload the VSCode window by running `Developer: Reload Window` from the command palette.
+
+## Customize configuration
+
+See [Vite Configuration Reference](https://vitejs.dev/config/).
+
+## Project Setup
+
+```sh
+pnpm install
+```
+
+### Compile and Hot-Reload for Development
+
+```sh
+pnpm dev
+```
+
+### Type-Check, Compile and Minify for Production
+
+```sh
+pnpm build
+```
+
+### Run Unit Tests with [Vitest](https://vitest.dev/)
+
+```sh
+pnpm test:unit
+```
+
+### Run End-to-End Tests with [Playwright](https://playwright.dev)
+
+```sh
+# Install browsers for the first run
+npx playwright install
+
+# When testing on CI, must build the project first
+pnpm build
+
+# Runs the end-to-end tests
+pnpm test:e2e
+# Runs the tests only on Chromium
+pnpm test:e2e --project=chromium
+# Runs the tests of a specific file
+pnpm test:e2e tests/example.spec.ts
+# Runs the tests in debug mode
+pnpm test:e2e --debug
+```
diff --git a/playground/typescript-router-pinia-vitest-playwright/e2e/tsconfig.json b/playground/typescript-router-pinia-vitest-playwright/e2e/tsconfig.json
new file mode 100644
index 000000000..be3bbfc0e
--- /dev/null
+++ b/playground/typescript-router-pinia-vitest-playwright/e2e/tsconfig.json
@@ -0,0 +1,4 @@
+{
+ "extends": "@tsconfig/node20/tsconfig.json",
+ "include": ["./**/*"]
+}
diff --git a/playground/typescript-router-pinia-vitest-playwright/e2e/vue.spec.ts b/playground/typescript-router-pinia-vitest-playwright/e2e/vue.spec.ts
new file mode 100644
index 000000000..3e5a3d02d
--- /dev/null
+++ b/playground/typescript-router-pinia-vitest-playwright/e2e/vue.spec.ts
@@ -0,0 +1,8 @@
+import { test, expect } from '@playwright/test';
+
+// See here how to get started:
+// https://playwright.dev/docs/intro
+test('visits the app root url', async ({ page }) => {
+ await page.goto('/');
+ await expect(page.locator('div.greetings > h1')).toHaveText('You did it!');
+})
diff --git a/playground/typescript-router-pinia-vitest-playwright/env.d.ts b/playground/typescript-router-pinia-vitest-playwright/env.d.ts
new file mode 100644
index 000000000..11f02fe2a
--- /dev/null
+++ b/playground/typescript-router-pinia-vitest-playwright/env.d.ts
@@ -0,0 +1 @@
+///
diff --git a/playground/typescript-router-pinia-vitest-playwright/index.html b/playground/typescript-router-pinia-vitest-playwright/index.html
new file mode 100644
index 000000000..a88854489
--- /dev/null
+++ b/playground/typescript-router-pinia-vitest-playwright/index.html
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+ Vite App
+
+
+
+
+
+
diff --git a/playground/typescript-router-pinia-vitest-playwright/package.json b/playground/typescript-router-pinia-vitest-playwright/package.json
new file mode 100644
index 000000000..5e4379b7a
--- /dev/null
+++ b/playground/typescript-router-pinia-vitest-playwright/package.json
@@ -0,0 +1,35 @@
+{
+ "name": "typescript-router-pinia-vitest-playwright",
+ "version": "0.0.0",
+ "private": true,
+ "type": "module",
+ "scripts": {
+ "dev": "vite",
+ "build": "run-p type-check \"build-only {@}\" --",
+ "preview": "vite preview",
+ "test:unit": "vitest",
+ "test:e2e": "playwright test",
+ "build-only": "vite build",
+ "type-check": "vue-tsc --build --force"
+ },
+ "dependencies": {
+ "pinia": "^2.1.7",
+ "vue": "^3.4.15",
+ "vue-router": "^4.2.5"
+ },
+ "devDependencies": {
+ "@playwright/test": "^1.41.2",
+ "@tsconfig/node20": "^20.1.2",
+ "@types/jsdom": "^21.1.6",
+ "@types/node": "^20.11.16",
+ "@vitejs/plugin-vue": "^5.0.3",
+ "@vue/test-utils": "^2.4.4",
+ "@vue/tsconfig": "^0.5.1",
+ "jsdom": "^24.0.0",
+ "npm-run-all2": "^6.1.2",
+ "typescript": "~5.3.0",
+ "vite": "^5.0.11",
+ "vitest": "^1.2.2",
+ "vue-tsc": "^1.8.27"
+ }
+}
diff --git a/playground/typescript-router-pinia-vitest-playwright/playwright.config.ts b/playground/typescript-router-pinia-vitest-playwright/playwright.config.ts
new file mode 100644
index 000000000..92075cc1b
--- /dev/null
+++ b/playground/typescript-router-pinia-vitest-playwright/playwright.config.ts
@@ -0,0 +1,110 @@
+import process from 'node:process'
+import { defineConfig, devices } from '@playwright/test'
+
+/**
+ * Read environment variables from file.
+ * https://github.com/motdotla/dotenv
+ */
+// require('dotenv').config();
+
+/**
+ * See https://playwright.dev/docs/test-configuration.
+ */
+export default defineConfig({
+ testDir: './e2e',
+ /* Maximum time one test can run for. */
+ timeout: 30 * 1000,
+ expect: {
+ /**
+ * Maximum time expect() should wait for the condition to be met.
+ * For example in `await expect(locator).toHaveText();`
+ */
+ timeout: 5000
+ },
+ /* Fail the build on CI if you accidentally left test.only in the source code. */
+ forbidOnly: !!process.env.CI,
+ /* Retry on CI only */
+ retries: process.env.CI ? 2 : 0,
+ /* Opt out of parallel tests on CI. */
+ workers: process.env.CI ? 1 : undefined,
+ /* Reporter to use. See https://playwright.dev/docs/test-reporters */
+ reporter: 'html',
+ /* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
+ use: {
+ /* Maximum time each action such as `click()` can take. Defaults to 0 (no limit). */
+ actionTimeout: 0,
+ /* Base URL to use in actions like `await page.goto('/')`. */
+ baseURL: 'http://localhost:5173',
+
+ /* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
+ trace: 'on-first-retry',
+
+ /* Only on CI systems run the tests headless */
+ headless: !!process.env.CI
+ },
+
+ /* Configure projects for major browsers */
+ projects: [
+ {
+ name: 'chromium',
+ use: {
+ ...devices['Desktop Chrome']
+ }
+ },
+ {
+ name: 'firefox',
+ use: {
+ ...devices['Desktop Firefox']
+ }
+ },
+ {
+ name: 'webkit',
+ use: {
+ ...devices['Desktop Safari']
+ }
+ }
+
+ /* Test against mobile viewports. */
+ // {
+ // name: 'Mobile Chrome',
+ // use: {
+ // ...devices['Pixel 5'],
+ // },
+ // },
+ // {
+ // name: 'Mobile Safari',
+ // use: {
+ // ...devices['iPhone 12'],
+ // },
+ // },
+
+ /* Test against branded browsers. */
+ // {
+ // name: 'Microsoft Edge',
+ // use: {
+ // channel: 'msedge',
+ // },
+ // },
+ // {
+ // name: 'Google Chrome',
+ // use: {
+ // channel: 'chrome',
+ // },
+ // },
+ ],
+
+ /* Folder for test artifacts such as screenshots, videos, traces, etc. */
+ // outputDir: 'test-results/',
+
+ /* Run your local dev server before starting the tests */
+ webServer: {
+ /**
+ * Use the dev server by default for faster feedback loop.
+ * Use the preview server on CI for more realistic testing.
+ * Playwright will re-use the local server if there is already a dev-server running.
+ */
+ command: process.env.CI ? 'vite preview --port 5173' : 'vite dev',
+ port: 5173,
+ reuseExistingServer: !process.env.CI
+ }
+})
diff --git a/playground/typescript-router-pinia-vitest-playwright/public/favicon.ico b/playground/typescript-router-pinia-vitest-playwright/public/favicon.ico
new file mode 100644
index 000000000..df36fcfb7
Binary files /dev/null and b/playground/typescript-router-pinia-vitest-playwright/public/favicon.ico differ
diff --git a/playground/typescript-router-pinia-vitest-playwright/src/App.vue b/playground/typescript-router-pinia-vitest-playwright/src/App.vue
new file mode 100644
index 000000000..7905b0516
--- /dev/null
+++ b/playground/typescript-router-pinia-vitest-playwright/src/App.vue
@@ -0,0 +1,85 @@
+
+
+
+
+
+
+
+ You’ve successfully created a project with
+ Vite +
+ Vue 3. What's next?
+
+
+
+
+
diff --git a/playground/typescript-router-pinia-vitest-playwright/src/components/TheWelcome.vue b/playground/typescript-router-pinia-vitest-playwright/src/components/TheWelcome.vue
new file mode 100644
index 000000000..49d8f7354
--- /dev/null
+++ b/playground/typescript-router-pinia-vitest-playwright/src/components/TheWelcome.vue
@@ -0,0 +1,88 @@
+
+
+
+
+
+
+
+ Documentation
+
+ Vue’s
+ official documentation
+ provides you with all information you need to get started.
+
+
+
+
+
+
+ Tooling
+
+ This project is served and bundled with
+ Vite. The
+ recommended IDE setup is
+ VSCode +
+ Volar. If
+ you need to test your components and web pages, check out
+ Cypress and
+ Cypress Component Testing.
+
+
+
+ More instructions are available in README.md.
+
+
+
+
+
+
+ Ecosystem
+
+ Get official tools and libraries for your project:
+ Pinia,
+ Vue Router,
+ Vue Test Utils, and
+ Vue Dev Tools. If
+ you need more resources, we suggest paying
+ Awesome Vue
+ a visit.
+
+
+
+
+
+
+ Community
+
+ Got stuck? Ask your question on
+ Vue Land, our official
+ Discord server, or
+ StackOverflow. You should also subscribe to
+ our mailing list and follow
+ the official
+ @vuejs
+ twitter account for latest news in the Vue world.
+
+
+
+
+
+
+ Support Vue
+
+ As an independent project, Vue relies on community backing for its sustainability. You can help
+ us by
+ becoming a sponsor.
+
+
diff --git a/playground/typescript-router-pinia-vitest-playwright/src/components/WelcomeItem.vue b/playground/typescript-router-pinia-vitest-playwright/src/components/WelcomeItem.vue
new file mode 100644
index 000000000..6d7086aea
--- /dev/null
+++ b/playground/typescript-router-pinia-vitest-playwright/src/components/WelcomeItem.vue
@@ -0,0 +1,87 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/playground/typescript-router-pinia-vitest-playwright/src/components/__tests__/HelloWorld.spec.ts b/playground/typescript-router-pinia-vitest-playwright/src/components/__tests__/HelloWorld.spec.ts
new file mode 100644
index 000000000..253320200
--- /dev/null
+++ b/playground/typescript-router-pinia-vitest-playwright/src/components/__tests__/HelloWorld.spec.ts
@@ -0,0 +1,11 @@
+import { describe, it, expect } from 'vitest'
+
+import { mount } from '@vue/test-utils'
+import HelloWorld from '../HelloWorld.vue'
+
+describe('HelloWorld', () => {
+ it('renders properly', () => {
+ const wrapper = mount(HelloWorld, { props: { msg: 'Hello Vitest' } })
+ expect(wrapper.text()).toContain('Hello Vitest')
+ })
+})
diff --git a/playground/typescript-router-pinia-vitest-playwright/src/components/icons/IconCommunity.vue b/playground/typescript-router-pinia-vitest-playwright/src/components/icons/IconCommunity.vue
new file mode 100644
index 000000000..2dc8b0552
--- /dev/null
+++ b/playground/typescript-router-pinia-vitest-playwright/src/components/icons/IconCommunity.vue
@@ -0,0 +1,7 @@
+
+
+
diff --git a/playground/typescript-router-pinia-vitest-playwright/src/components/icons/IconDocumentation.vue b/playground/typescript-router-pinia-vitest-playwright/src/components/icons/IconDocumentation.vue
new file mode 100644
index 000000000..6d4791cfb
--- /dev/null
+++ b/playground/typescript-router-pinia-vitest-playwright/src/components/icons/IconDocumentation.vue
@@ -0,0 +1,7 @@
+
+
+
diff --git a/playground/typescript-router-pinia-vitest-playwright/src/components/icons/IconEcosystem.vue b/playground/typescript-router-pinia-vitest-playwright/src/components/icons/IconEcosystem.vue
new file mode 100644
index 000000000..c3a4f078c
--- /dev/null
+++ b/playground/typescript-router-pinia-vitest-playwright/src/components/icons/IconEcosystem.vue
@@ -0,0 +1,7 @@
+
+
+
diff --git a/playground/typescript-router-pinia-vitest-playwright/src/components/icons/IconSupport.vue b/playground/typescript-router-pinia-vitest-playwright/src/components/icons/IconSupport.vue
new file mode 100644
index 000000000..7452834d3
--- /dev/null
+++ b/playground/typescript-router-pinia-vitest-playwright/src/components/icons/IconSupport.vue
@@ -0,0 +1,7 @@
+
+
+
diff --git a/playground/typescript-router-pinia-vitest-playwright/src/components/icons/IconTooling.vue b/playground/typescript-router-pinia-vitest-playwright/src/components/icons/IconTooling.vue
new file mode 100644
index 000000000..660598d7c
--- /dev/null
+++ b/playground/typescript-router-pinia-vitest-playwright/src/components/icons/IconTooling.vue
@@ -0,0 +1,19 @@
+
+
+
+
diff --git a/playground/typescript-router-pinia-vitest-playwright/src/main.ts b/playground/typescript-router-pinia-vitest-playwright/src/main.ts
new file mode 100644
index 000000000..5dcad83c3
--- /dev/null
+++ b/playground/typescript-router-pinia-vitest-playwright/src/main.ts
@@ -0,0 +1,14 @@
+import './assets/main.css'
+
+import { createApp } from 'vue'
+import { createPinia } from 'pinia'
+
+import App from './App.vue'
+import router from './router'
+
+const app = createApp(App)
+
+app.use(createPinia())
+app.use(router)
+
+app.mount('#app')
diff --git a/playground/typescript-router-pinia-vitest-playwright/src/router/index.ts b/playground/typescript-router-pinia-vitest-playwright/src/router/index.ts
new file mode 100644
index 000000000..a49ae507f
--- /dev/null
+++ b/playground/typescript-router-pinia-vitest-playwright/src/router/index.ts
@@ -0,0 +1,23 @@
+import { createRouter, createWebHistory } from 'vue-router'
+import HomeView from '../views/HomeView.vue'
+
+const router = createRouter({
+ history: createWebHistory(import.meta.env.BASE_URL),
+ routes: [
+ {
+ path: '/',
+ name: 'home',
+ component: HomeView
+ },
+ {
+ path: '/about',
+ name: 'about',
+ // route level code-splitting
+ // this generates a separate chunk (About.[hash].js) for this route
+ // which is lazy-loaded when the route is visited.
+ component: () => import('../views/AboutView.vue')
+ }
+ ]
+})
+
+export default router
diff --git a/playground/typescript-router-pinia-vitest-playwright/src/stores/counter.ts b/playground/typescript-router-pinia-vitest-playwright/src/stores/counter.ts
new file mode 100644
index 000000000..b6757ba57
--- /dev/null
+++ b/playground/typescript-router-pinia-vitest-playwright/src/stores/counter.ts
@@ -0,0 +1,12 @@
+import { ref, computed } from 'vue'
+import { defineStore } from 'pinia'
+
+export const useCounterStore = defineStore('counter', () => {
+ const count = ref(0)
+ const doubleCount = computed(() => count.value * 2)
+ function increment() {
+ count.value++
+ }
+
+ return { count, doubleCount, increment }
+})
diff --git a/playground/typescript-router-pinia-vitest-playwright/src/views/AboutView.vue b/playground/typescript-router-pinia-vitest-playwright/src/views/AboutView.vue
new file mode 100644
index 000000000..756ad2a17
--- /dev/null
+++ b/playground/typescript-router-pinia-vitest-playwright/src/views/AboutView.vue
@@ -0,0 +1,15 @@
+
+
+
This is an about page
+
+
+
+
diff --git a/playground/typescript-router-pinia-vitest-playwright/src/views/HomeView.vue b/playground/typescript-router-pinia-vitest-playwright/src/views/HomeView.vue
new file mode 100644
index 000000000..d5c0217e4
--- /dev/null
+++ b/playground/typescript-router-pinia-vitest-playwright/src/views/HomeView.vue
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
diff --git a/playground/typescript-router-pinia-vitest-playwright/tsconfig.app.json b/playground/typescript-router-pinia-vitest-playwright/tsconfig.app.json
new file mode 100644
index 000000000..e14c754d3
--- /dev/null
+++ b/playground/typescript-router-pinia-vitest-playwright/tsconfig.app.json
@@ -0,0 +1,14 @@
+{
+ "extends": "@vue/tsconfig/tsconfig.dom.json",
+ "include": ["env.d.ts", "src/**/*", "src/**/*.vue"],
+ "exclude": ["src/**/__tests__/*"],
+ "compilerOptions": {
+ "composite": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
+
+ "baseUrl": ".",
+ "paths": {
+ "@/*": ["./src/*"]
+ }
+ }
+}
diff --git a/playground/typescript-router-pinia-vitest-playwright/tsconfig.json b/playground/typescript-router-pinia-vitest-playwright/tsconfig.json
new file mode 100644
index 000000000..100cf6a8f
--- /dev/null
+++ b/playground/typescript-router-pinia-vitest-playwright/tsconfig.json
@@ -0,0 +1,14 @@
+{
+ "files": [],
+ "references": [
+ {
+ "path": "./tsconfig.node.json"
+ },
+ {
+ "path": "./tsconfig.app.json"
+ },
+ {
+ "path": "./tsconfig.vitest.json"
+ }
+ ]
+}
diff --git a/playground/typescript-router-pinia-vitest-playwright/tsconfig.node.json b/playground/typescript-router-pinia-vitest-playwright/tsconfig.node.json
new file mode 100644
index 000000000..f09406303
--- /dev/null
+++ b/playground/typescript-router-pinia-vitest-playwright/tsconfig.node.json
@@ -0,0 +1,19 @@
+{
+ "extends": "@tsconfig/node20/tsconfig.json",
+ "include": [
+ "vite.config.*",
+ "vitest.config.*",
+ "cypress.config.*",
+ "nightwatch.conf.*",
+ "playwright.config.*"
+ ],
+ "compilerOptions": {
+ "composite": true,
+ "noEmit": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
+
+ "module": "ESNext",
+ "moduleResolution": "Bundler",
+ "types": ["node"]
+ }
+}
diff --git a/playground/typescript-router-pinia-vitest-playwright/tsconfig.vitest.json b/playground/typescript-router-pinia-vitest-playwright/tsconfig.vitest.json
new file mode 100644
index 000000000..571995d11
--- /dev/null
+++ b/playground/typescript-router-pinia-vitest-playwright/tsconfig.vitest.json
@@ -0,0 +1,11 @@
+{
+ "extends": "./tsconfig.app.json",
+ "exclude": [],
+ "compilerOptions": {
+ "composite": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.vitest.tsbuildinfo",
+
+ "lib": [],
+ "types": ["node", "jsdom"]
+ }
+}
diff --git a/playground/typescript-router-pinia-vitest-playwright/vite.config.ts b/playground/typescript-router-pinia-vitest-playwright/vite.config.ts
new file mode 100644
index 000000000..5c45e1d9b
--- /dev/null
+++ b/playground/typescript-router-pinia-vitest-playwright/vite.config.ts
@@ -0,0 +1,16 @@
+import { fileURLToPath, URL } from 'node:url'
+
+import { defineConfig } from 'vite'
+import vue from '@vitejs/plugin-vue'
+
+// https://vitejs.dev/config/
+export default defineConfig({
+ plugins: [
+ vue(),
+ ],
+ resolve: {
+ alias: {
+ '@': fileURLToPath(new URL('./src', import.meta.url))
+ }
+ }
+})
diff --git a/playground/typescript-router-pinia-vitest-playwright/vitest.config.ts b/playground/typescript-router-pinia-vitest-playwright/vitest.config.ts
new file mode 100644
index 000000000..10067d578
--- /dev/null
+++ b/playground/typescript-router-pinia-vitest-playwright/vitest.config.ts
@@ -0,0 +1,14 @@
+import { fileURLToPath } from 'node:url'
+import { mergeConfig, defineConfig, configDefaults } from 'vitest/config'
+import viteConfig from './vite.config'
+
+export default mergeConfig(
+ viteConfig,
+ defineConfig({
+ test: {
+ environment: 'jsdom',
+ exclude: [...configDefaults.exclude, 'e2e/*'],
+ root: fileURLToPath(new URL('./', import.meta.url))
+ }
+ })
+)
diff --git a/playground/typescript-router-pinia-vitest/.gitignore b/playground/typescript-router-pinia-vitest/.gitignore
new file mode 100644
index 000000000..8ee54e8d3
--- /dev/null
+++ b/playground/typescript-router-pinia-vitest/.gitignore
@@ -0,0 +1,30 @@
+# 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/
+
+# Editor directories and files
+.vscode/*
+!.vscode/extensions.json
+.idea
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?
+
+*.tsbuildinfo
diff --git a/playground/typescript-router-pinia-vitest/README.md b/playground/typescript-router-pinia-vitest/README.md
new file mode 100644
index 000000000..5277cebfc
--- /dev/null
+++ b/playground/typescript-router-pinia-vitest/README.md
@@ -0,0 +1,46 @@
+# typescript-router-pinia-vitest
+
+This template should help get you started developing with Vue 3 in Vite.
+
+## Recommended IDE Setup
+
+[VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur) + [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin).
+
+## Type Support for `.vue` Imports in TS
+
+TypeScript cannot handle type information for `.vue` imports by default, so we replace the `tsc` CLI with `vue-tsc` for type checking. In editors, we need [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin) to make the TypeScript language service aware of `.vue` types.
+
+If the standalone TypeScript plugin doesn't feel fast enough to you, Volar has also implemented a [Take Over Mode](https://github.com/johnsoncodehk/volar/discussions/471#discussioncomment-1361669) that is more performant. You can enable it by the following steps:
+
+1. Disable the built-in TypeScript Extension
+ 1) Run `Extensions: Show Built-in Extensions` from VSCode's command palette
+ 2) Find `TypeScript and JavaScript Language Features`, right click and select `Disable (Workspace)`
+2. Reload the VSCode window by running `Developer: Reload Window` from the command palette.
+
+## Customize configuration
+
+See [Vite Configuration Reference](https://vitejs.dev/config/).
+
+## Project Setup
+
+```sh
+pnpm install
+```
+
+### Compile and Hot-Reload for Development
+
+```sh
+pnpm dev
+```
+
+### Type-Check, Compile and Minify for Production
+
+```sh
+pnpm build
+```
+
+### Run Unit Tests with [Vitest](https://vitest.dev/)
+
+```sh
+pnpm test:unit
+```
diff --git a/playground/typescript-router-pinia-vitest/env.d.ts b/playground/typescript-router-pinia-vitest/env.d.ts
new file mode 100644
index 000000000..11f02fe2a
--- /dev/null
+++ b/playground/typescript-router-pinia-vitest/env.d.ts
@@ -0,0 +1 @@
+///
diff --git a/playground/typescript-router-pinia-vitest/index.html b/playground/typescript-router-pinia-vitest/index.html
new file mode 100644
index 000000000..a88854489
--- /dev/null
+++ b/playground/typescript-router-pinia-vitest/index.html
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+ Vite App
+
+
+
+
+
+
diff --git a/playground/typescript-router-pinia-vitest/package.json b/playground/typescript-router-pinia-vitest/package.json
new file mode 100644
index 000000000..691b6653f
--- /dev/null
+++ b/playground/typescript-router-pinia-vitest/package.json
@@ -0,0 +1,33 @@
+{
+ "name": "typescript-router-pinia-vitest",
+ "version": "0.0.0",
+ "private": true,
+ "type": "module",
+ "scripts": {
+ "dev": "vite",
+ "build": "run-p type-check \"build-only {@}\" --",
+ "preview": "vite preview",
+ "test:unit": "vitest",
+ "build-only": "vite build",
+ "type-check": "vue-tsc --build --force"
+ },
+ "dependencies": {
+ "pinia": "^2.1.7",
+ "vue": "^3.4.15",
+ "vue-router": "^4.2.5"
+ },
+ "devDependencies": {
+ "@tsconfig/node20": "^20.1.2",
+ "@types/jsdom": "^21.1.6",
+ "@types/node": "^20.11.16",
+ "@vitejs/plugin-vue": "^5.0.3",
+ "@vue/test-utils": "^2.4.4",
+ "@vue/tsconfig": "^0.5.1",
+ "jsdom": "^24.0.0",
+ "npm-run-all2": "^6.1.2",
+ "typescript": "~5.3.0",
+ "vite": "^5.0.11",
+ "vitest": "^1.2.2",
+ "vue-tsc": "^1.8.27"
+ }
+}
diff --git a/playground/typescript-router-pinia-vitest/public/favicon.ico b/playground/typescript-router-pinia-vitest/public/favicon.ico
new file mode 100644
index 000000000..df36fcfb7
Binary files /dev/null and b/playground/typescript-router-pinia-vitest/public/favicon.ico differ
diff --git a/playground/typescript-router-pinia-vitest/src/App.vue b/playground/typescript-router-pinia-vitest/src/App.vue
new file mode 100644
index 000000000..7905b0516
--- /dev/null
+++ b/playground/typescript-router-pinia-vitest/src/App.vue
@@ -0,0 +1,85 @@
+
+
+
+
+
+
+
+ You’ve successfully created a project with
+ Vite +
+ Vue 3. What's next?
+
+
+
+
+
diff --git a/playground/typescript-router-pinia-vitest/src/components/TheWelcome.vue b/playground/typescript-router-pinia-vitest/src/components/TheWelcome.vue
new file mode 100644
index 000000000..49d8f7354
--- /dev/null
+++ b/playground/typescript-router-pinia-vitest/src/components/TheWelcome.vue
@@ -0,0 +1,88 @@
+
+
+
+
+
+
+
+ Documentation
+
+ Vue’s
+ official documentation
+ provides you with all information you need to get started.
+
+
+
+
+
+
+ Tooling
+
+ This project is served and bundled with
+ Vite. The
+ recommended IDE setup is
+ VSCode +
+ Volar. If
+ you need to test your components and web pages, check out
+ Cypress and
+ Cypress Component Testing.
+
+
+
+ More instructions are available in README.md.
+
+
+
+
+
+
+ Ecosystem
+
+ Get official tools and libraries for your project:
+ Pinia,
+ Vue Router,
+ Vue Test Utils, and
+ Vue Dev Tools. If
+ you need more resources, we suggest paying
+ Awesome Vue
+ a visit.
+
+
+
+
+
+
+ Community
+
+ Got stuck? Ask your question on
+ Vue Land, our official
+ Discord server, or
+ StackOverflow. You should also subscribe to
+ our mailing list and follow
+ the official
+ @vuejs
+ twitter account for latest news in the Vue world.
+
+
+
+
+
+
+ Support Vue
+
+ As an independent project, Vue relies on community backing for its sustainability. You can help
+ us by
+ becoming a sponsor.
+
+
diff --git a/playground/typescript-router-pinia-vitest/src/components/WelcomeItem.vue b/playground/typescript-router-pinia-vitest/src/components/WelcomeItem.vue
new file mode 100644
index 000000000..6d7086aea
--- /dev/null
+++ b/playground/typescript-router-pinia-vitest/src/components/WelcomeItem.vue
@@ -0,0 +1,87 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/playground/typescript-router-pinia-vitest/src/components/__tests__/HelloWorld.spec.ts b/playground/typescript-router-pinia-vitest/src/components/__tests__/HelloWorld.spec.ts
new file mode 100644
index 000000000..253320200
--- /dev/null
+++ b/playground/typescript-router-pinia-vitest/src/components/__tests__/HelloWorld.spec.ts
@@ -0,0 +1,11 @@
+import { describe, it, expect } from 'vitest'
+
+import { mount } from '@vue/test-utils'
+import HelloWorld from '../HelloWorld.vue'
+
+describe('HelloWorld', () => {
+ it('renders properly', () => {
+ const wrapper = mount(HelloWorld, { props: { msg: 'Hello Vitest' } })
+ expect(wrapper.text()).toContain('Hello Vitest')
+ })
+})
diff --git a/playground/typescript-router-pinia-vitest/src/components/icons/IconCommunity.vue b/playground/typescript-router-pinia-vitest/src/components/icons/IconCommunity.vue
new file mode 100644
index 000000000..2dc8b0552
--- /dev/null
+++ b/playground/typescript-router-pinia-vitest/src/components/icons/IconCommunity.vue
@@ -0,0 +1,7 @@
+
+
+
diff --git a/playground/typescript-router-pinia-vitest/src/components/icons/IconDocumentation.vue b/playground/typescript-router-pinia-vitest/src/components/icons/IconDocumentation.vue
new file mode 100644
index 000000000..6d4791cfb
--- /dev/null
+++ b/playground/typescript-router-pinia-vitest/src/components/icons/IconDocumentation.vue
@@ -0,0 +1,7 @@
+
+
+
diff --git a/playground/typescript-router-pinia-vitest/src/components/icons/IconEcosystem.vue b/playground/typescript-router-pinia-vitest/src/components/icons/IconEcosystem.vue
new file mode 100644
index 000000000..c3a4f078c
--- /dev/null
+++ b/playground/typescript-router-pinia-vitest/src/components/icons/IconEcosystem.vue
@@ -0,0 +1,7 @@
+
+
+
diff --git a/playground/typescript-router-pinia-vitest/src/components/icons/IconSupport.vue b/playground/typescript-router-pinia-vitest/src/components/icons/IconSupport.vue
new file mode 100644
index 000000000..7452834d3
--- /dev/null
+++ b/playground/typescript-router-pinia-vitest/src/components/icons/IconSupport.vue
@@ -0,0 +1,7 @@
+
+
+
diff --git a/playground/typescript-router-pinia-vitest/src/components/icons/IconTooling.vue b/playground/typescript-router-pinia-vitest/src/components/icons/IconTooling.vue
new file mode 100644
index 000000000..660598d7c
--- /dev/null
+++ b/playground/typescript-router-pinia-vitest/src/components/icons/IconTooling.vue
@@ -0,0 +1,19 @@
+
+
+
+
diff --git a/playground/typescript-router-pinia-vitest/src/main.ts b/playground/typescript-router-pinia-vitest/src/main.ts
new file mode 100644
index 000000000..5dcad83c3
--- /dev/null
+++ b/playground/typescript-router-pinia-vitest/src/main.ts
@@ -0,0 +1,14 @@
+import './assets/main.css'
+
+import { createApp } from 'vue'
+import { createPinia } from 'pinia'
+
+import App from './App.vue'
+import router from './router'
+
+const app = createApp(App)
+
+app.use(createPinia())
+app.use(router)
+
+app.mount('#app')
diff --git a/playground/typescript-router-pinia-vitest/src/router/index.ts b/playground/typescript-router-pinia-vitest/src/router/index.ts
new file mode 100644
index 000000000..a49ae507f
--- /dev/null
+++ b/playground/typescript-router-pinia-vitest/src/router/index.ts
@@ -0,0 +1,23 @@
+import { createRouter, createWebHistory } from 'vue-router'
+import HomeView from '../views/HomeView.vue'
+
+const router = createRouter({
+ history: createWebHistory(import.meta.env.BASE_URL),
+ routes: [
+ {
+ path: '/',
+ name: 'home',
+ component: HomeView
+ },
+ {
+ path: '/about',
+ name: 'about',
+ // route level code-splitting
+ // this generates a separate chunk (About.[hash].js) for this route
+ // which is lazy-loaded when the route is visited.
+ component: () => import('../views/AboutView.vue')
+ }
+ ]
+})
+
+export default router
diff --git a/playground/typescript-router-pinia-vitest/src/stores/counter.ts b/playground/typescript-router-pinia-vitest/src/stores/counter.ts
new file mode 100644
index 000000000..b6757ba57
--- /dev/null
+++ b/playground/typescript-router-pinia-vitest/src/stores/counter.ts
@@ -0,0 +1,12 @@
+import { ref, computed } from 'vue'
+import { defineStore } from 'pinia'
+
+export const useCounterStore = defineStore('counter', () => {
+ const count = ref(0)
+ const doubleCount = computed(() => count.value * 2)
+ function increment() {
+ count.value++
+ }
+
+ return { count, doubleCount, increment }
+})
diff --git a/playground/typescript-router-pinia-vitest/src/views/AboutView.vue b/playground/typescript-router-pinia-vitest/src/views/AboutView.vue
new file mode 100644
index 000000000..756ad2a17
--- /dev/null
+++ b/playground/typescript-router-pinia-vitest/src/views/AboutView.vue
@@ -0,0 +1,15 @@
+
+
+
This is an about page
+
+
+
+
diff --git a/playground/typescript-router-pinia-vitest/src/views/HomeView.vue b/playground/typescript-router-pinia-vitest/src/views/HomeView.vue
new file mode 100644
index 000000000..d5c0217e4
--- /dev/null
+++ b/playground/typescript-router-pinia-vitest/src/views/HomeView.vue
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
diff --git a/playground/typescript-router-pinia-vitest/tsconfig.app.json b/playground/typescript-router-pinia-vitest/tsconfig.app.json
new file mode 100644
index 000000000..e14c754d3
--- /dev/null
+++ b/playground/typescript-router-pinia-vitest/tsconfig.app.json
@@ -0,0 +1,14 @@
+{
+ "extends": "@vue/tsconfig/tsconfig.dom.json",
+ "include": ["env.d.ts", "src/**/*", "src/**/*.vue"],
+ "exclude": ["src/**/__tests__/*"],
+ "compilerOptions": {
+ "composite": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
+
+ "baseUrl": ".",
+ "paths": {
+ "@/*": ["./src/*"]
+ }
+ }
+}
diff --git a/playground/typescript-router-pinia-vitest/tsconfig.json b/playground/typescript-router-pinia-vitest/tsconfig.json
new file mode 100644
index 000000000..100cf6a8f
--- /dev/null
+++ b/playground/typescript-router-pinia-vitest/tsconfig.json
@@ -0,0 +1,14 @@
+{
+ "files": [],
+ "references": [
+ {
+ "path": "./tsconfig.node.json"
+ },
+ {
+ "path": "./tsconfig.app.json"
+ },
+ {
+ "path": "./tsconfig.vitest.json"
+ }
+ ]
+}
diff --git a/playground/typescript-router-pinia-vitest/tsconfig.node.json b/playground/typescript-router-pinia-vitest/tsconfig.node.json
new file mode 100644
index 000000000..f09406303
--- /dev/null
+++ b/playground/typescript-router-pinia-vitest/tsconfig.node.json
@@ -0,0 +1,19 @@
+{
+ "extends": "@tsconfig/node20/tsconfig.json",
+ "include": [
+ "vite.config.*",
+ "vitest.config.*",
+ "cypress.config.*",
+ "nightwatch.conf.*",
+ "playwright.config.*"
+ ],
+ "compilerOptions": {
+ "composite": true,
+ "noEmit": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
+
+ "module": "ESNext",
+ "moduleResolution": "Bundler",
+ "types": ["node"]
+ }
+}
diff --git a/playground/typescript-router-pinia-vitest/tsconfig.vitest.json b/playground/typescript-router-pinia-vitest/tsconfig.vitest.json
new file mode 100644
index 000000000..571995d11
--- /dev/null
+++ b/playground/typescript-router-pinia-vitest/tsconfig.vitest.json
@@ -0,0 +1,11 @@
+{
+ "extends": "./tsconfig.app.json",
+ "exclude": [],
+ "compilerOptions": {
+ "composite": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.vitest.tsbuildinfo",
+
+ "lib": [],
+ "types": ["node", "jsdom"]
+ }
+}
diff --git a/playground/typescript-router-pinia-vitest/vite.config.ts b/playground/typescript-router-pinia-vitest/vite.config.ts
new file mode 100644
index 000000000..5c45e1d9b
--- /dev/null
+++ b/playground/typescript-router-pinia-vitest/vite.config.ts
@@ -0,0 +1,16 @@
+import { fileURLToPath, URL } from 'node:url'
+
+import { defineConfig } from 'vite'
+import vue from '@vitejs/plugin-vue'
+
+// https://vitejs.dev/config/
+export default defineConfig({
+ plugins: [
+ vue(),
+ ],
+ resolve: {
+ alias: {
+ '@': fileURLToPath(new URL('./src', import.meta.url))
+ }
+ }
+})
diff --git a/playground/typescript-router-pinia-vitest/vitest.config.ts b/playground/typescript-router-pinia-vitest/vitest.config.ts
new file mode 100644
index 000000000..10067d578
--- /dev/null
+++ b/playground/typescript-router-pinia-vitest/vitest.config.ts
@@ -0,0 +1,14 @@
+import { fileURLToPath } from 'node:url'
+import { mergeConfig, defineConfig, configDefaults } from 'vitest/config'
+import viteConfig from './vite.config'
+
+export default mergeConfig(
+ viteConfig,
+ defineConfig({
+ test: {
+ environment: 'jsdom',
+ exclude: [...configDefaults.exclude, 'e2e/*'],
+ root: fileURLToPath(new URL('./', import.meta.url))
+ }
+ })
+)
diff --git a/playground/typescript-router-pinia-with-tests/.gitignore b/playground/typescript-router-pinia-with-tests/.gitignore
new file mode 100644
index 000000000..8ee54e8d3
--- /dev/null
+++ b/playground/typescript-router-pinia-with-tests/.gitignore
@@ -0,0 +1,30 @@
+# 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/
+
+# Editor directories and files
+.vscode/*
+!.vscode/extensions.json
+.idea
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?
+
+*.tsbuildinfo
diff --git a/playground/typescript-router-pinia-with-tests/README.md b/playground/typescript-router-pinia-with-tests/README.md
new file mode 100644
index 000000000..b664aa57a
--- /dev/null
+++ b/playground/typescript-router-pinia-with-tests/README.md
@@ -0,0 +1,62 @@
+# typescript-router-pinia-with-tests
+
+This template should help get you started developing with Vue 3 in Vite.
+
+## Recommended IDE Setup
+
+[VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur) + [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin).
+
+## Type Support for `.vue` Imports in TS
+
+TypeScript cannot handle type information for `.vue` imports by default, so we replace the `tsc` CLI with `vue-tsc` for type checking. In editors, we need [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin) to make the TypeScript language service aware of `.vue` types.
+
+If the standalone TypeScript plugin doesn't feel fast enough to you, Volar has also implemented a [Take Over Mode](https://github.com/johnsoncodehk/volar/discussions/471#discussioncomment-1361669) that is more performant. You can enable it by the following steps:
+
+1. Disable the built-in TypeScript Extension
+ 1) Run `Extensions: Show Built-in Extensions` from VSCode's command palette
+ 2) Find `TypeScript and JavaScript Language Features`, right click and select `Disable (Workspace)`
+2. Reload the VSCode window by running `Developer: Reload Window` from the command palette.
+
+## Customize configuration
+
+See [Vite Configuration Reference](https://vitejs.dev/config/).
+
+## Project Setup
+
+```sh
+pnpm install
+```
+
+### Compile and Hot-Reload for Development
+
+```sh
+pnpm dev
+```
+
+### Type-Check, Compile and Minify for Production
+
+```sh
+pnpm build
+```
+
+### Run Unit Tests with [Vitest](https://vitest.dev/)
+
+```sh
+pnpm test:unit
+```
+
+### Run End-to-End Tests with [Cypress](https://www.cypress.io/)
+
+```sh
+pnpm test:e2e:dev
+```
+
+This runs the end-to-end tests against the Vite development server.
+It is much faster than the production build.
+
+But it's still recommended to test the production build with `test:e2e` before deploying (e.g. in CI environments):
+
+```sh
+pnpm build
+pnpm test:e2e
+```
diff --git a/playground/typescript-router-pinia-with-tests/cypress.config.ts b/playground/typescript-router-pinia-with-tests/cypress.config.ts
new file mode 100644
index 000000000..0f66080fd
--- /dev/null
+++ b/playground/typescript-router-pinia-with-tests/cypress.config.ts
@@ -0,0 +1,8 @@
+import { defineConfig } from 'cypress'
+
+export default defineConfig({
+ e2e: {
+ specPattern: 'cypress/e2e/**/*.{cy,spec}.{js,jsx,ts,tsx}',
+ baseUrl: 'http://localhost:4173'
+ }
+})
diff --git a/playground/typescript-router-pinia-with-tests/cypress/e2e/example.cy.ts b/playground/typescript-router-pinia-with-tests/cypress/e2e/example.cy.ts
new file mode 100644
index 000000000..7554c35d8
--- /dev/null
+++ b/playground/typescript-router-pinia-with-tests/cypress/e2e/example.cy.ts
@@ -0,0 +1,8 @@
+// https://on.cypress.io/api
+
+describe('My First Test', () => {
+ it('visits the app root url', () => {
+ cy.visit('/')
+ cy.contains('h1', 'You did it!')
+ })
+})
diff --git a/playground/typescript-router-pinia-with-tests/cypress/e2e/tsconfig.json b/playground/typescript-router-pinia-with-tests/cypress/e2e/tsconfig.json
new file mode 100644
index 000000000..37748feb7
--- /dev/null
+++ b/playground/typescript-router-pinia-with-tests/cypress/e2e/tsconfig.json
@@ -0,0 +1,10 @@
+{
+ "extends": "@vue/tsconfig/tsconfig.dom.json",
+ "include": ["./**/*", "../support/**/*"],
+ "compilerOptions": {
+ "isolatedModules": false,
+ "target": "es5",
+ "lib": ["es5", "dom"],
+ "types": ["cypress"]
+ }
+}
diff --git a/playground/typescript-router-pinia-with-tests/cypress/fixtures/example.json b/playground/typescript-router-pinia-with-tests/cypress/fixtures/example.json
new file mode 100644
index 000000000..02e425437
--- /dev/null
+++ b/playground/typescript-router-pinia-with-tests/cypress/fixtures/example.json
@@ -0,0 +1,5 @@
+{
+ "name": "Using fixtures to represent data",
+ "email": "hello@cypress.io",
+ "body": "Fixtures are a great way to mock data for responses to routes"
+}
diff --git a/playground/typescript-router-pinia-with-tests/cypress/support/commands.ts b/playground/typescript-router-pinia-with-tests/cypress/support/commands.ts
new file mode 100644
index 000000000..9b7bb8e25
--- /dev/null
+++ b/playground/typescript-router-pinia-with-tests/cypress/support/commands.ts
@@ -0,0 +1,39 @@
+///
+// ***********************************************
+// This example commands.ts shows you how to
+// create various custom commands and overwrite
+// existing commands.
+//
+// For more comprehensive examples of custom
+// commands please read more here:
+// https://on.cypress.io/custom-commands
+// ***********************************************
+//
+//
+// -- This is a parent command --
+// Cypress.Commands.add('login', (email, password) => { ... })
+//
+//
+// -- This is a child command --
+// Cypress.Commands.add('drag', { prevSubject: 'element'}, (subject, options) => { ... })
+//
+//
+// -- This is a dual command --
+// Cypress.Commands.add('dismiss', { prevSubject: 'optional'}, (subject, options) => { ... })
+//
+//
+// -- This will overwrite an existing command --
+// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... })
+//
+// declare global {
+// namespace Cypress {
+// interface Chainable {
+// login(email: string, password: string): Chainable
+// drag(subject: string, options?: Partial): Chainable
+// dismiss(subject: string, options?: Partial): Chainable
+// visit(originalFn: CommandOriginalFn, url: string, options: Partial): Chainable
+// }
+// }
+// }
+
+export {}
diff --git a/playground/typescript-router-pinia-with-tests/cypress/support/e2e.ts b/playground/typescript-router-pinia-with-tests/cypress/support/e2e.ts
new file mode 100644
index 000000000..d68db96df
--- /dev/null
+++ b/playground/typescript-router-pinia-with-tests/cypress/support/e2e.ts
@@ -0,0 +1,20 @@
+// ***********************************************************
+// This example support/index.js is processed and
+// loaded automatically before your test files.
+//
+// This is a great place to put global configuration and
+// behavior that modifies Cypress.
+//
+// You can change the location of this file or turn off
+// automatically serving support files with the
+// 'supportFile' configuration option.
+//
+// You can read more here:
+// https://on.cypress.io/configuration
+// ***********************************************************
+
+// Import commands.js using ES2015 syntax:
+import './commands'
+
+// Alternatively you can use CommonJS syntax:
+// require('./commands')
diff --git a/playground/typescript-router-pinia-with-tests/env.d.ts b/playground/typescript-router-pinia-with-tests/env.d.ts
new file mode 100644
index 000000000..11f02fe2a
--- /dev/null
+++ b/playground/typescript-router-pinia-with-tests/env.d.ts
@@ -0,0 +1 @@
+///
diff --git a/playground/typescript-router-pinia-with-tests/index.html b/playground/typescript-router-pinia-with-tests/index.html
new file mode 100644
index 000000000..a88854489
--- /dev/null
+++ b/playground/typescript-router-pinia-with-tests/index.html
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+ Vite App
+
+
+
+
+
+
diff --git a/playground/typescript-router-pinia-with-tests/package.json b/playground/typescript-router-pinia-with-tests/package.json
new file mode 100644
index 000000000..0d7334fc2
--- /dev/null
+++ b/playground/typescript-router-pinia-with-tests/package.json
@@ -0,0 +1,37 @@
+{
+ "name": "typescript-router-pinia-with-tests",
+ "version": "0.0.0",
+ "private": true,
+ "type": "module",
+ "scripts": {
+ "dev": "vite",
+ "build": "run-p type-check \"build-only {@}\" --",
+ "preview": "vite preview",
+ "test:unit": "vitest",
+ "test:e2e": "start-server-and-test preview http://localhost:4173 'cypress run --e2e'",
+ "test:e2e:dev": "start-server-and-test 'vite dev --port 4173' http://localhost:4173 'cypress open --e2e'",
+ "build-only": "vite build",
+ "type-check": "vue-tsc --build --force"
+ },
+ "dependencies": {
+ "pinia": "^2.1.7",
+ "vue": "^3.4.15",
+ "vue-router": "^4.2.5"
+ },
+ "devDependencies": {
+ "@tsconfig/node20": "^20.1.2",
+ "@types/jsdom": "^21.1.6",
+ "@types/node": "^20.11.16",
+ "@vitejs/plugin-vue": "^5.0.3",
+ "@vue/test-utils": "^2.4.4",
+ "@vue/tsconfig": "^0.5.1",
+ "cypress": "^13.6.4",
+ "jsdom": "^24.0.0",
+ "npm-run-all2": "^6.1.2",
+ "start-server-and-test": "^2.0.3",
+ "typescript": "~5.3.0",
+ "vite": "^5.0.11",
+ "vitest": "^1.2.2",
+ "vue-tsc": "^1.8.27"
+ }
+}
diff --git a/playground/typescript-router-pinia-with-tests/public/favicon.ico b/playground/typescript-router-pinia-with-tests/public/favicon.ico
new file mode 100644
index 000000000..df36fcfb7
Binary files /dev/null and b/playground/typescript-router-pinia-with-tests/public/favicon.ico differ
diff --git a/playground/typescript-router-pinia-with-tests/src/App.vue b/playground/typescript-router-pinia-with-tests/src/App.vue
new file mode 100644
index 000000000..7905b0516
--- /dev/null
+++ b/playground/typescript-router-pinia-with-tests/src/App.vue
@@ -0,0 +1,85 @@
+
+
+
+
+
+
+
+ You’ve successfully created a project with
+ Vite +
+ Vue 3. What's next?
+
+
+
+
+
diff --git a/playground/typescript-router-pinia-with-tests/src/components/TheWelcome.vue b/playground/typescript-router-pinia-with-tests/src/components/TheWelcome.vue
new file mode 100644
index 000000000..49d8f7354
--- /dev/null
+++ b/playground/typescript-router-pinia-with-tests/src/components/TheWelcome.vue
@@ -0,0 +1,88 @@
+
+
+
+
+
+
+
+ Documentation
+
+ Vue’s
+ official documentation
+ provides you with all information you need to get started.
+
+
+
+
+
+
+ Tooling
+
+ This project is served and bundled with
+ Vite. The
+ recommended IDE setup is
+ VSCode +
+ Volar. If
+ you need to test your components and web pages, check out
+ Cypress and
+ Cypress Component Testing.
+
+
+
+ More instructions are available in README.md.
+
+
+
+
+
+
+ Ecosystem
+
+ Get official tools and libraries for your project:
+ Pinia,
+ Vue Router,
+ Vue Test Utils, and
+ Vue Dev Tools. If
+ you need more resources, we suggest paying
+ Awesome Vue
+ a visit.
+
+
+
+
+
+
+ Community
+
+ Got stuck? Ask your question on
+ Vue Land, our official
+ Discord server, or
+ StackOverflow. You should also subscribe to
+ our mailing list and follow
+ the official
+ @vuejs
+ twitter account for latest news in the Vue world.
+
+
+
+
+
+
+ Support Vue
+
+ As an independent project, Vue relies on community backing for its sustainability. You can help
+ us by
+ becoming a sponsor.
+
+
diff --git a/playground/typescript-router-pinia-with-tests/src/components/WelcomeItem.vue b/playground/typescript-router-pinia-with-tests/src/components/WelcomeItem.vue
new file mode 100644
index 000000000..6d7086aea
--- /dev/null
+++ b/playground/typescript-router-pinia-with-tests/src/components/WelcomeItem.vue
@@ -0,0 +1,87 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/playground/typescript-router-pinia-with-tests/src/components/__tests__/HelloWorld.spec.ts b/playground/typescript-router-pinia-with-tests/src/components/__tests__/HelloWorld.spec.ts
new file mode 100644
index 000000000..253320200
--- /dev/null
+++ b/playground/typescript-router-pinia-with-tests/src/components/__tests__/HelloWorld.spec.ts
@@ -0,0 +1,11 @@
+import { describe, it, expect } from 'vitest'
+
+import { mount } from '@vue/test-utils'
+import HelloWorld from '../HelloWorld.vue'
+
+describe('HelloWorld', () => {
+ it('renders properly', () => {
+ const wrapper = mount(HelloWorld, { props: { msg: 'Hello Vitest' } })
+ expect(wrapper.text()).toContain('Hello Vitest')
+ })
+})
diff --git a/playground/typescript-router-pinia-with-tests/src/components/icons/IconCommunity.vue b/playground/typescript-router-pinia-with-tests/src/components/icons/IconCommunity.vue
new file mode 100644
index 000000000..2dc8b0552
--- /dev/null
+++ b/playground/typescript-router-pinia-with-tests/src/components/icons/IconCommunity.vue
@@ -0,0 +1,7 @@
+
+
+
diff --git a/playground/typescript-router-pinia-with-tests/src/components/icons/IconDocumentation.vue b/playground/typescript-router-pinia-with-tests/src/components/icons/IconDocumentation.vue
new file mode 100644
index 000000000..6d4791cfb
--- /dev/null
+++ b/playground/typescript-router-pinia-with-tests/src/components/icons/IconDocumentation.vue
@@ -0,0 +1,7 @@
+
+
+
diff --git a/playground/typescript-router-pinia-with-tests/src/components/icons/IconEcosystem.vue b/playground/typescript-router-pinia-with-tests/src/components/icons/IconEcosystem.vue
new file mode 100644
index 000000000..c3a4f078c
--- /dev/null
+++ b/playground/typescript-router-pinia-with-tests/src/components/icons/IconEcosystem.vue
@@ -0,0 +1,7 @@
+
+
+
diff --git a/playground/typescript-router-pinia-with-tests/src/components/icons/IconSupport.vue b/playground/typescript-router-pinia-with-tests/src/components/icons/IconSupport.vue
new file mode 100644
index 000000000..7452834d3
--- /dev/null
+++ b/playground/typescript-router-pinia-with-tests/src/components/icons/IconSupport.vue
@@ -0,0 +1,7 @@
+
+
+
diff --git a/playground/typescript-router-pinia-with-tests/src/components/icons/IconTooling.vue b/playground/typescript-router-pinia-with-tests/src/components/icons/IconTooling.vue
new file mode 100644
index 000000000..660598d7c
--- /dev/null
+++ b/playground/typescript-router-pinia-with-tests/src/components/icons/IconTooling.vue
@@ -0,0 +1,19 @@
+
+
+
+
diff --git a/playground/typescript-router-pinia-with-tests/src/main.ts b/playground/typescript-router-pinia-with-tests/src/main.ts
new file mode 100644
index 000000000..5dcad83c3
--- /dev/null
+++ b/playground/typescript-router-pinia-with-tests/src/main.ts
@@ -0,0 +1,14 @@
+import './assets/main.css'
+
+import { createApp } from 'vue'
+import { createPinia } from 'pinia'
+
+import App from './App.vue'
+import router from './router'
+
+const app = createApp(App)
+
+app.use(createPinia())
+app.use(router)
+
+app.mount('#app')
diff --git a/playground/typescript-router-pinia-with-tests/src/router/index.ts b/playground/typescript-router-pinia-with-tests/src/router/index.ts
new file mode 100644
index 000000000..a49ae507f
--- /dev/null
+++ b/playground/typescript-router-pinia-with-tests/src/router/index.ts
@@ -0,0 +1,23 @@
+import { createRouter, createWebHistory } from 'vue-router'
+import HomeView from '../views/HomeView.vue'
+
+const router = createRouter({
+ history: createWebHistory(import.meta.env.BASE_URL),
+ routes: [
+ {
+ path: '/',
+ name: 'home',
+ component: HomeView
+ },
+ {
+ path: '/about',
+ name: 'about',
+ // route level code-splitting
+ // this generates a separate chunk (About.[hash].js) for this route
+ // which is lazy-loaded when the route is visited.
+ component: () => import('../views/AboutView.vue')
+ }
+ ]
+})
+
+export default router
diff --git a/playground/typescript-router-pinia-with-tests/src/stores/counter.ts b/playground/typescript-router-pinia-with-tests/src/stores/counter.ts
new file mode 100644
index 000000000..b6757ba57
--- /dev/null
+++ b/playground/typescript-router-pinia-with-tests/src/stores/counter.ts
@@ -0,0 +1,12 @@
+import { ref, computed } from 'vue'
+import { defineStore } from 'pinia'
+
+export const useCounterStore = defineStore('counter', () => {
+ const count = ref(0)
+ const doubleCount = computed(() => count.value * 2)
+ function increment() {
+ count.value++
+ }
+
+ return { count, doubleCount, increment }
+})
diff --git a/playground/typescript-router-pinia-with-tests/src/views/AboutView.vue b/playground/typescript-router-pinia-with-tests/src/views/AboutView.vue
new file mode 100644
index 000000000..756ad2a17
--- /dev/null
+++ b/playground/typescript-router-pinia-with-tests/src/views/AboutView.vue
@@ -0,0 +1,15 @@
+
+
+
This is an about page
+
+
+
+
diff --git a/playground/typescript-router-pinia-with-tests/src/views/HomeView.vue b/playground/typescript-router-pinia-with-tests/src/views/HomeView.vue
new file mode 100644
index 000000000..d5c0217e4
--- /dev/null
+++ b/playground/typescript-router-pinia-with-tests/src/views/HomeView.vue
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
diff --git a/playground/typescript-router-pinia-with-tests/tsconfig.app.json b/playground/typescript-router-pinia-with-tests/tsconfig.app.json
new file mode 100644
index 000000000..e14c754d3
--- /dev/null
+++ b/playground/typescript-router-pinia-with-tests/tsconfig.app.json
@@ -0,0 +1,14 @@
+{
+ "extends": "@vue/tsconfig/tsconfig.dom.json",
+ "include": ["env.d.ts", "src/**/*", "src/**/*.vue"],
+ "exclude": ["src/**/__tests__/*"],
+ "compilerOptions": {
+ "composite": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
+
+ "baseUrl": ".",
+ "paths": {
+ "@/*": ["./src/*"]
+ }
+ }
+}
diff --git a/playground/typescript-router-pinia-with-tests/tsconfig.json b/playground/typescript-router-pinia-with-tests/tsconfig.json
new file mode 100644
index 000000000..5304731b8
--- /dev/null
+++ b/playground/typescript-router-pinia-with-tests/tsconfig.json
@@ -0,0 +1,17 @@
+{
+ "files": [],
+ "references": [
+ {
+ "path": "./tsconfig.node.json"
+ },
+ {
+ "path": "./tsconfig.app.json"
+ },
+ {
+ "path": "./tsconfig.vitest.json"
+ }
+ ],
+ "compilerOptions": {
+ "module": "NodeNext"
+ }
+}
diff --git a/playground/typescript-router-pinia-with-tests/tsconfig.node.json b/playground/typescript-router-pinia-with-tests/tsconfig.node.json
new file mode 100644
index 000000000..f09406303
--- /dev/null
+++ b/playground/typescript-router-pinia-with-tests/tsconfig.node.json
@@ -0,0 +1,19 @@
+{
+ "extends": "@tsconfig/node20/tsconfig.json",
+ "include": [
+ "vite.config.*",
+ "vitest.config.*",
+ "cypress.config.*",
+ "nightwatch.conf.*",
+ "playwright.config.*"
+ ],
+ "compilerOptions": {
+ "composite": true,
+ "noEmit": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
+
+ "module": "ESNext",
+ "moduleResolution": "Bundler",
+ "types": ["node"]
+ }
+}
diff --git a/playground/typescript-router-pinia-with-tests/tsconfig.vitest.json b/playground/typescript-router-pinia-with-tests/tsconfig.vitest.json
new file mode 100644
index 000000000..571995d11
--- /dev/null
+++ b/playground/typescript-router-pinia-with-tests/tsconfig.vitest.json
@@ -0,0 +1,11 @@
+{
+ "extends": "./tsconfig.app.json",
+ "exclude": [],
+ "compilerOptions": {
+ "composite": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.vitest.tsbuildinfo",
+
+ "lib": [],
+ "types": ["node", "jsdom"]
+ }
+}
diff --git a/playground/typescript-router-pinia-with-tests/vite.config.ts b/playground/typescript-router-pinia-with-tests/vite.config.ts
new file mode 100644
index 000000000..5c45e1d9b
--- /dev/null
+++ b/playground/typescript-router-pinia-with-tests/vite.config.ts
@@ -0,0 +1,16 @@
+import { fileURLToPath, URL } from 'node:url'
+
+import { defineConfig } from 'vite'
+import vue from '@vitejs/plugin-vue'
+
+// https://vitejs.dev/config/
+export default defineConfig({
+ plugins: [
+ vue(),
+ ],
+ resolve: {
+ alias: {
+ '@': fileURLToPath(new URL('./src', import.meta.url))
+ }
+ }
+})
diff --git a/playground/typescript-router-pinia-with-tests/vitest.config.ts b/playground/typescript-router-pinia-with-tests/vitest.config.ts
new file mode 100644
index 000000000..10067d578
--- /dev/null
+++ b/playground/typescript-router-pinia-with-tests/vitest.config.ts
@@ -0,0 +1,14 @@
+import { fileURLToPath } from 'node:url'
+import { mergeConfig, defineConfig, configDefaults } from 'vitest/config'
+import viteConfig from './vite.config'
+
+export default mergeConfig(
+ viteConfig,
+ defineConfig({
+ test: {
+ environment: 'jsdom',
+ exclude: [...configDefaults.exclude, 'e2e/*'],
+ root: fileURLToPath(new URL('./', import.meta.url))
+ }
+ })
+)
diff --git a/playground/typescript-router-pinia/.gitignore b/playground/typescript-router-pinia/.gitignore
new file mode 100644
index 000000000..8ee54e8d3
--- /dev/null
+++ b/playground/typescript-router-pinia/.gitignore
@@ -0,0 +1,30 @@
+# 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/
+
+# Editor directories and files
+.vscode/*
+!.vscode/extensions.json
+.idea
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?
+
+*.tsbuildinfo
diff --git a/playground/typescript-router-pinia/README.md b/playground/typescript-router-pinia/README.md
new file mode 100644
index 000000000..4f731fff7
--- /dev/null
+++ b/playground/typescript-router-pinia/README.md
@@ -0,0 +1,40 @@
+# typescript-router-pinia
+
+This template should help get you started developing with Vue 3 in Vite.
+
+## Recommended IDE Setup
+
+[VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur) + [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin).
+
+## Type Support for `.vue` Imports in TS
+
+TypeScript cannot handle type information for `.vue` imports by default, so we replace the `tsc` CLI with `vue-tsc` for type checking. In editors, we need [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin) to make the TypeScript language service aware of `.vue` types.
+
+If the standalone TypeScript plugin doesn't feel fast enough to you, Volar has also implemented a [Take Over Mode](https://github.com/johnsoncodehk/volar/discussions/471#discussioncomment-1361669) that is more performant. You can enable it by the following steps:
+
+1. Disable the built-in TypeScript Extension
+ 1) Run `Extensions: Show Built-in Extensions` from VSCode's command palette
+ 2) Find `TypeScript and JavaScript Language Features`, right click and select `Disable (Workspace)`
+2. Reload the VSCode window by running `Developer: Reload Window` from the command palette.
+
+## Customize configuration
+
+See [Vite Configuration Reference](https://vitejs.dev/config/).
+
+## Project Setup
+
+```sh
+pnpm install
+```
+
+### Compile and Hot-Reload for Development
+
+```sh
+pnpm dev
+```
+
+### Type-Check, Compile and Minify for Production
+
+```sh
+pnpm build
+```
diff --git a/playground/typescript-router-pinia/env.d.ts b/playground/typescript-router-pinia/env.d.ts
new file mode 100644
index 000000000..11f02fe2a
--- /dev/null
+++ b/playground/typescript-router-pinia/env.d.ts
@@ -0,0 +1 @@
+///
diff --git a/playground/typescript-router-pinia/index.html b/playground/typescript-router-pinia/index.html
new file mode 100644
index 000000000..a88854489
--- /dev/null
+++ b/playground/typescript-router-pinia/index.html
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+ Vite App
+
+
+
+
+
+
diff --git a/playground/typescript-router-pinia/package.json b/playground/typescript-router-pinia/package.json
new file mode 100644
index 000000000..6f6b50a76
--- /dev/null
+++ b/playground/typescript-router-pinia/package.json
@@ -0,0 +1,28 @@
+{
+ "name": "typescript-router-pinia",
+ "version": "0.0.0",
+ "private": true,
+ "type": "module",
+ "scripts": {
+ "dev": "vite",
+ "build": "run-p type-check \"build-only {@}\" --",
+ "preview": "vite preview",
+ "build-only": "vite build",
+ "type-check": "vue-tsc --build --force"
+ },
+ "dependencies": {
+ "pinia": "^2.1.7",
+ "vue": "^3.4.15",
+ "vue-router": "^4.2.5"
+ },
+ "devDependencies": {
+ "@tsconfig/node20": "^20.1.2",
+ "@types/node": "^20.11.16",
+ "@vitejs/plugin-vue": "^5.0.3",
+ "@vue/tsconfig": "^0.5.1",
+ "npm-run-all2": "^6.1.2",
+ "typescript": "~5.3.0",
+ "vite": "^5.0.11",
+ "vue-tsc": "^1.8.27"
+ }
+}
diff --git a/playground/typescript-router-pinia/public/favicon.ico b/playground/typescript-router-pinia/public/favicon.ico
new file mode 100644
index 000000000..df36fcfb7
Binary files /dev/null and b/playground/typescript-router-pinia/public/favicon.ico differ
diff --git a/playground/typescript-router-pinia/src/App.vue b/playground/typescript-router-pinia/src/App.vue
new file mode 100644
index 000000000..7905b0516
--- /dev/null
+++ b/playground/typescript-router-pinia/src/App.vue
@@ -0,0 +1,85 @@
+
+
+
+
+
+
+
+ You’ve successfully created a project with
+ Vite +
+ Vue 3. What's next?
+
+
+
+
+
diff --git a/playground/typescript-router-pinia/src/components/TheWelcome.vue b/playground/typescript-router-pinia/src/components/TheWelcome.vue
new file mode 100644
index 000000000..49d8f7354
--- /dev/null
+++ b/playground/typescript-router-pinia/src/components/TheWelcome.vue
@@ -0,0 +1,88 @@
+
+
+
+
+
+
+
+ Documentation
+
+ Vue’s
+ official documentation
+ provides you with all information you need to get started.
+
+
+
+
+
+
+ Tooling
+
+ This project is served and bundled with
+ Vite. The
+ recommended IDE setup is
+ VSCode +
+ Volar. If
+ you need to test your components and web pages, check out
+ Cypress and
+ Cypress Component Testing.
+
+
+
+ More instructions are available in README.md.
+
+
+
+
+
+
+ Ecosystem
+
+ Get official tools and libraries for your project:
+ Pinia,
+ Vue Router,
+ Vue Test Utils, and
+ Vue Dev Tools. If
+ you need more resources, we suggest paying
+ Awesome Vue
+ a visit.
+
+
+
+
+
+
+ Community
+
+ Got stuck? Ask your question on
+ Vue Land, our official
+ Discord server, or
+ StackOverflow. You should also subscribe to
+ our mailing list and follow
+ the official
+ @vuejs
+ twitter account for latest news in the Vue world.
+
+
+
+
+
+
+ Support Vue
+
+ As an independent project, Vue relies on community backing for its sustainability. You can help
+ us by
+ becoming a sponsor.
+
+
diff --git a/playground/typescript-router-pinia/src/components/WelcomeItem.vue b/playground/typescript-router-pinia/src/components/WelcomeItem.vue
new file mode 100644
index 000000000..6d7086aea
--- /dev/null
+++ b/playground/typescript-router-pinia/src/components/WelcomeItem.vue
@@ -0,0 +1,87 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/playground/typescript-router-pinia/src/components/icons/IconCommunity.vue b/playground/typescript-router-pinia/src/components/icons/IconCommunity.vue
new file mode 100644
index 000000000..2dc8b0552
--- /dev/null
+++ b/playground/typescript-router-pinia/src/components/icons/IconCommunity.vue
@@ -0,0 +1,7 @@
+
+
+
diff --git a/playground/typescript-router-pinia/src/components/icons/IconDocumentation.vue b/playground/typescript-router-pinia/src/components/icons/IconDocumentation.vue
new file mode 100644
index 000000000..6d4791cfb
--- /dev/null
+++ b/playground/typescript-router-pinia/src/components/icons/IconDocumentation.vue
@@ -0,0 +1,7 @@
+
+
+
diff --git a/playground/typescript-router-pinia/src/components/icons/IconEcosystem.vue b/playground/typescript-router-pinia/src/components/icons/IconEcosystem.vue
new file mode 100644
index 000000000..c3a4f078c
--- /dev/null
+++ b/playground/typescript-router-pinia/src/components/icons/IconEcosystem.vue
@@ -0,0 +1,7 @@
+
+
+
diff --git a/playground/typescript-router-pinia/src/components/icons/IconSupport.vue b/playground/typescript-router-pinia/src/components/icons/IconSupport.vue
new file mode 100644
index 000000000..7452834d3
--- /dev/null
+++ b/playground/typescript-router-pinia/src/components/icons/IconSupport.vue
@@ -0,0 +1,7 @@
+
+
+
diff --git a/playground/typescript-router-pinia/src/components/icons/IconTooling.vue b/playground/typescript-router-pinia/src/components/icons/IconTooling.vue
new file mode 100644
index 000000000..660598d7c
--- /dev/null
+++ b/playground/typescript-router-pinia/src/components/icons/IconTooling.vue
@@ -0,0 +1,19 @@
+
+
+
+
diff --git a/playground/typescript-router-pinia/src/main.ts b/playground/typescript-router-pinia/src/main.ts
new file mode 100644
index 000000000..5dcad83c3
--- /dev/null
+++ b/playground/typescript-router-pinia/src/main.ts
@@ -0,0 +1,14 @@
+import './assets/main.css'
+
+import { createApp } from 'vue'
+import { createPinia } from 'pinia'
+
+import App from './App.vue'
+import router from './router'
+
+const app = createApp(App)
+
+app.use(createPinia())
+app.use(router)
+
+app.mount('#app')
diff --git a/playground/typescript-router-pinia/src/router/index.ts b/playground/typescript-router-pinia/src/router/index.ts
new file mode 100644
index 000000000..a49ae507f
--- /dev/null
+++ b/playground/typescript-router-pinia/src/router/index.ts
@@ -0,0 +1,23 @@
+import { createRouter, createWebHistory } from 'vue-router'
+import HomeView from '../views/HomeView.vue'
+
+const router = createRouter({
+ history: createWebHistory(import.meta.env.BASE_URL),
+ routes: [
+ {
+ path: '/',
+ name: 'home',
+ component: HomeView
+ },
+ {
+ path: '/about',
+ name: 'about',
+ // route level code-splitting
+ // this generates a separate chunk (About.[hash].js) for this route
+ // which is lazy-loaded when the route is visited.
+ component: () => import('../views/AboutView.vue')
+ }
+ ]
+})
+
+export default router
diff --git a/playground/typescript-router-pinia/src/stores/counter.ts b/playground/typescript-router-pinia/src/stores/counter.ts
new file mode 100644
index 000000000..b6757ba57
--- /dev/null
+++ b/playground/typescript-router-pinia/src/stores/counter.ts
@@ -0,0 +1,12 @@
+import { ref, computed } from 'vue'
+import { defineStore } from 'pinia'
+
+export const useCounterStore = defineStore('counter', () => {
+ const count = ref(0)
+ const doubleCount = computed(() => count.value * 2)
+ function increment() {
+ count.value++
+ }
+
+ return { count, doubleCount, increment }
+})
diff --git a/playground/typescript-router-pinia/src/views/AboutView.vue b/playground/typescript-router-pinia/src/views/AboutView.vue
new file mode 100644
index 000000000..756ad2a17
--- /dev/null
+++ b/playground/typescript-router-pinia/src/views/AboutView.vue
@@ -0,0 +1,15 @@
+
+
+
This is an about page
+
+
+
+
diff --git a/playground/typescript-router-pinia/src/views/HomeView.vue b/playground/typescript-router-pinia/src/views/HomeView.vue
new file mode 100644
index 000000000..d5c0217e4
--- /dev/null
+++ b/playground/typescript-router-pinia/src/views/HomeView.vue
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
diff --git a/playground/typescript-router-pinia/tsconfig.app.json b/playground/typescript-router-pinia/tsconfig.app.json
new file mode 100644
index 000000000..e14c754d3
--- /dev/null
+++ b/playground/typescript-router-pinia/tsconfig.app.json
@@ -0,0 +1,14 @@
+{
+ "extends": "@vue/tsconfig/tsconfig.dom.json",
+ "include": ["env.d.ts", "src/**/*", "src/**/*.vue"],
+ "exclude": ["src/**/__tests__/*"],
+ "compilerOptions": {
+ "composite": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
+
+ "baseUrl": ".",
+ "paths": {
+ "@/*": ["./src/*"]
+ }
+ }
+}
diff --git a/playground/typescript-router-pinia/tsconfig.json b/playground/typescript-router-pinia/tsconfig.json
new file mode 100644
index 000000000..66b5e5703
--- /dev/null
+++ b/playground/typescript-router-pinia/tsconfig.json
@@ -0,0 +1,11 @@
+{
+ "files": [],
+ "references": [
+ {
+ "path": "./tsconfig.node.json"
+ },
+ {
+ "path": "./tsconfig.app.json"
+ }
+ ]
+}
diff --git a/playground/typescript-router-pinia/tsconfig.node.json b/playground/typescript-router-pinia/tsconfig.node.json
new file mode 100644
index 000000000..f09406303
--- /dev/null
+++ b/playground/typescript-router-pinia/tsconfig.node.json
@@ -0,0 +1,19 @@
+{
+ "extends": "@tsconfig/node20/tsconfig.json",
+ "include": [
+ "vite.config.*",
+ "vitest.config.*",
+ "cypress.config.*",
+ "nightwatch.conf.*",
+ "playwright.config.*"
+ ],
+ "compilerOptions": {
+ "composite": true,
+ "noEmit": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
+
+ "module": "ESNext",
+ "moduleResolution": "Bundler",
+ "types": ["node"]
+ }
+}
diff --git a/playground/typescript-router-pinia/vite.config.ts b/playground/typescript-router-pinia/vite.config.ts
new file mode 100644
index 000000000..5c45e1d9b
--- /dev/null
+++ b/playground/typescript-router-pinia/vite.config.ts
@@ -0,0 +1,16 @@
+import { fileURLToPath, URL } from 'node:url'
+
+import { defineConfig } from 'vite'
+import vue from '@vitejs/plugin-vue'
+
+// https://vitejs.dev/config/
+export default defineConfig({
+ plugins: [
+ vue(),
+ ],
+ resolve: {
+ alias: {
+ '@': fileURLToPath(new URL('./src', import.meta.url))
+ }
+ }
+})
diff --git a/playground/typescript-router-playwright/.gitignore b/playground/typescript-router-playwright/.gitignore
new file mode 100644
index 000000000..aef72d03c
--- /dev/null
+++ b/playground/typescript-router-playwright/.gitignore
@@ -0,0 +1,33 @@
+# 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/
+
+# Editor directories and files
+.vscode/*
+!.vscode/extensions.json
+.idea
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?
+
+*.tsbuildinfo
+
+test-results/
+playwright-report/
diff --git a/playground/typescript-router-playwright/.vscode/extensions.json b/playground/typescript-router-playwright/.vscode/extensions.json
new file mode 100644
index 000000000..7b3f8bdae
--- /dev/null
+++ b/playground/typescript-router-playwright/.vscode/extensions.json
@@ -0,0 +1,3 @@
+{
+ "recommendations": ["ms-playwright.playwright"]
+}
diff --git a/playground/typescript-router-playwright/README.md b/playground/typescript-router-playwright/README.md
new file mode 100644
index 000000000..66baddb01
--- /dev/null
+++ b/playground/typescript-router-playwright/README.md
@@ -0,0 +1,59 @@
+# typescript-router-playwright
+
+This template should help get you started developing with Vue 3 in Vite.
+
+## Recommended IDE Setup
+
+[VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur) + [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin).
+
+## Type Support for `.vue` Imports in TS
+
+TypeScript cannot handle type information for `.vue` imports by default, so we replace the `tsc` CLI with `vue-tsc` for type checking. In editors, we need [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin) to make the TypeScript language service aware of `.vue` types.
+
+If the standalone TypeScript plugin doesn't feel fast enough to you, Volar has also implemented a [Take Over Mode](https://github.com/johnsoncodehk/volar/discussions/471#discussioncomment-1361669) that is more performant. You can enable it by the following steps:
+
+1. Disable the built-in TypeScript Extension
+ 1) Run `Extensions: Show Built-in Extensions` from VSCode's command palette
+ 2) Find `TypeScript and JavaScript Language Features`, right click and select `Disable (Workspace)`
+2. Reload the VSCode window by running `Developer: Reload Window` from the command palette.
+
+## Customize configuration
+
+See [Vite Configuration Reference](https://vitejs.dev/config/).
+
+## Project Setup
+
+```sh
+pnpm install
+```
+
+### Compile and Hot-Reload for Development
+
+```sh
+pnpm dev
+```
+
+### Type-Check, Compile and Minify for Production
+
+```sh
+pnpm build
+```
+
+### Run End-to-End Tests with [Playwright](https://playwright.dev)
+
+```sh
+# Install browsers for the first run
+npx playwright install
+
+# When testing on CI, must build the project first
+pnpm build
+
+# Runs the end-to-end tests
+pnpm test:e2e
+# Runs the tests only on Chromium
+pnpm test:e2e --project=chromium
+# Runs the tests of a specific file
+pnpm test:e2e tests/example.spec.ts
+# Runs the tests in debug mode
+pnpm test:e2e --debug
+```
diff --git a/playground/typescript-router-playwright/e2e/tsconfig.json b/playground/typescript-router-playwright/e2e/tsconfig.json
new file mode 100644
index 000000000..be3bbfc0e
--- /dev/null
+++ b/playground/typescript-router-playwright/e2e/tsconfig.json
@@ -0,0 +1,4 @@
+{
+ "extends": "@tsconfig/node20/tsconfig.json",
+ "include": ["./**/*"]
+}
diff --git a/playground/typescript-router-playwright/e2e/vue.spec.ts b/playground/typescript-router-playwright/e2e/vue.spec.ts
new file mode 100644
index 000000000..3e5a3d02d
--- /dev/null
+++ b/playground/typescript-router-playwright/e2e/vue.spec.ts
@@ -0,0 +1,8 @@
+import { test, expect } from '@playwright/test';
+
+// See here how to get started:
+// https://playwright.dev/docs/intro
+test('visits the app root url', async ({ page }) => {
+ await page.goto('/');
+ await expect(page.locator('div.greetings > h1')).toHaveText('You did it!');
+})
diff --git a/playground/typescript-router-playwright/env.d.ts b/playground/typescript-router-playwright/env.d.ts
new file mode 100644
index 000000000..11f02fe2a
--- /dev/null
+++ b/playground/typescript-router-playwright/env.d.ts
@@ -0,0 +1 @@
+///
diff --git a/playground/typescript-router-playwright/index.html b/playground/typescript-router-playwright/index.html
new file mode 100644
index 000000000..a88854489
--- /dev/null
+++ b/playground/typescript-router-playwright/index.html
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+ Vite App
+
+
+
+
+
+
diff --git a/playground/typescript-router-playwright/package.json b/playground/typescript-router-playwright/package.json
new file mode 100644
index 000000000..a61f6c005
--- /dev/null
+++ b/playground/typescript-router-playwright/package.json
@@ -0,0 +1,29 @@
+{
+ "name": "typescript-router-playwright",
+ "version": "0.0.0",
+ "private": true,
+ "type": "module",
+ "scripts": {
+ "dev": "vite",
+ "build": "run-p type-check \"build-only {@}\" --",
+ "preview": "vite preview",
+ "test:e2e": "playwright test",
+ "build-only": "vite build",
+ "type-check": "vue-tsc --build --force"
+ },
+ "dependencies": {
+ "vue": "^3.4.15",
+ "vue-router": "^4.2.5"
+ },
+ "devDependencies": {
+ "@playwright/test": "^1.41.2",
+ "@tsconfig/node20": "^20.1.2",
+ "@types/node": "^20.11.16",
+ "@vitejs/plugin-vue": "^5.0.3",
+ "@vue/tsconfig": "^0.5.1",
+ "npm-run-all2": "^6.1.2",
+ "typescript": "~5.3.0",
+ "vite": "^5.0.11",
+ "vue-tsc": "^1.8.27"
+ }
+}
diff --git a/playground/typescript-router-playwright/playwright.config.ts b/playground/typescript-router-playwright/playwright.config.ts
new file mode 100644
index 000000000..92075cc1b
--- /dev/null
+++ b/playground/typescript-router-playwright/playwright.config.ts
@@ -0,0 +1,110 @@
+import process from 'node:process'
+import { defineConfig, devices } from '@playwright/test'
+
+/**
+ * Read environment variables from file.
+ * https://github.com/motdotla/dotenv
+ */
+// require('dotenv').config();
+
+/**
+ * See https://playwright.dev/docs/test-configuration.
+ */
+export default defineConfig({
+ testDir: './e2e',
+ /* Maximum time one test can run for. */
+ timeout: 30 * 1000,
+ expect: {
+ /**
+ * Maximum time expect() should wait for the condition to be met.
+ * For example in `await expect(locator).toHaveText();`
+ */
+ timeout: 5000
+ },
+ /* Fail the build on CI if you accidentally left test.only in the source code. */
+ forbidOnly: !!process.env.CI,
+ /* Retry on CI only */
+ retries: process.env.CI ? 2 : 0,
+ /* Opt out of parallel tests on CI. */
+ workers: process.env.CI ? 1 : undefined,
+ /* Reporter to use. See https://playwright.dev/docs/test-reporters */
+ reporter: 'html',
+ /* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
+ use: {
+ /* Maximum time each action such as `click()` can take. Defaults to 0 (no limit). */
+ actionTimeout: 0,
+ /* Base URL to use in actions like `await page.goto('/')`. */
+ baseURL: 'http://localhost:5173',
+
+ /* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
+ trace: 'on-first-retry',
+
+ /* Only on CI systems run the tests headless */
+ headless: !!process.env.CI
+ },
+
+ /* Configure projects for major browsers */
+ projects: [
+ {
+ name: 'chromium',
+ use: {
+ ...devices['Desktop Chrome']
+ }
+ },
+ {
+ name: 'firefox',
+ use: {
+ ...devices['Desktop Firefox']
+ }
+ },
+ {
+ name: 'webkit',
+ use: {
+ ...devices['Desktop Safari']
+ }
+ }
+
+ /* Test against mobile viewports. */
+ // {
+ // name: 'Mobile Chrome',
+ // use: {
+ // ...devices['Pixel 5'],
+ // },
+ // },
+ // {
+ // name: 'Mobile Safari',
+ // use: {
+ // ...devices['iPhone 12'],
+ // },
+ // },
+
+ /* Test against branded browsers. */
+ // {
+ // name: 'Microsoft Edge',
+ // use: {
+ // channel: 'msedge',
+ // },
+ // },
+ // {
+ // name: 'Google Chrome',
+ // use: {
+ // channel: 'chrome',
+ // },
+ // },
+ ],
+
+ /* Folder for test artifacts such as screenshots, videos, traces, etc. */
+ // outputDir: 'test-results/',
+
+ /* Run your local dev server before starting the tests */
+ webServer: {
+ /**
+ * Use the dev server by default for faster feedback loop.
+ * Use the preview server on CI for more realistic testing.
+ * Playwright will re-use the local server if there is already a dev-server running.
+ */
+ command: process.env.CI ? 'vite preview --port 5173' : 'vite dev',
+ port: 5173,
+ reuseExistingServer: !process.env.CI
+ }
+})
diff --git a/playground/typescript-router-playwright/public/favicon.ico b/playground/typescript-router-playwright/public/favicon.ico
new file mode 100644
index 000000000..df36fcfb7
Binary files /dev/null and b/playground/typescript-router-playwright/public/favicon.ico differ
diff --git a/playground/typescript-router-playwright/src/App.vue b/playground/typescript-router-playwright/src/App.vue
new file mode 100644
index 000000000..7905b0516
--- /dev/null
+++ b/playground/typescript-router-playwright/src/App.vue
@@ -0,0 +1,85 @@
+
+
+
+
+
+
+
+ You’ve successfully created a project with
+ Vite +
+ Vue 3. What's next?
+
+
+
+
+
diff --git a/playground/typescript-router-playwright/src/components/TheWelcome.vue b/playground/typescript-router-playwright/src/components/TheWelcome.vue
new file mode 100644
index 000000000..49d8f7354
--- /dev/null
+++ b/playground/typescript-router-playwright/src/components/TheWelcome.vue
@@ -0,0 +1,88 @@
+
+
+
+
+
+
+
+ Documentation
+
+ Vue’s
+ official documentation
+ provides you with all information you need to get started.
+
+
+
+
+
+
+ Tooling
+
+ This project is served and bundled with
+ Vite. The
+ recommended IDE setup is
+ VSCode +
+ Volar. If
+ you need to test your components and web pages, check out
+ Cypress and
+ Cypress Component Testing.
+
+
+
+ More instructions are available in README.md.
+
+
+
+
+
+
+ Ecosystem
+
+ Get official tools and libraries for your project:
+ Pinia,
+ Vue Router,
+ Vue Test Utils, and
+ Vue Dev Tools. If
+ you need more resources, we suggest paying
+ Awesome Vue
+ a visit.
+
+
+
+
+
+
+ Community
+
+ Got stuck? Ask your question on
+ Vue Land, our official
+ Discord server, or
+ StackOverflow. You should also subscribe to
+ our mailing list and follow
+ the official
+ @vuejs
+ twitter account for latest news in the Vue world.
+
+
+
+
+
+
+ Support Vue
+
+ As an independent project, Vue relies on community backing for its sustainability. You can help
+ us by
+ becoming a sponsor.
+
+
diff --git a/playground/typescript-router-playwright/src/components/WelcomeItem.vue b/playground/typescript-router-playwright/src/components/WelcomeItem.vue
new file mode 100644
index 000000000..6d7086aea
--- /dev/null
+++ b/playground/typescript-router-playwright/src/components/WelcomeItem.vue
@@ -0,0 +1,87 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/playground/typescript-router-playwright/src/components/icons/IconCommunity.vue b/playground/typescript-router-playwright/src/components/icons/IconCommunity.vue
new file mode 100644
index 000000000..2dc8b0552
--- /dev/null
+++ b/playground/typescript-router-playwright/src/components/icons/IconCommunity.vue
@@ -0,0 +1,7 @@
+
+
+
diff --git a/playground/typescript-router-playwright/src/components/icons/IconDocumentation.vue b/playground/typescript-router-playwright/src/components/icons/IconDocumentation.vue
new file mode 100644
index 000000000..6d4791cfb
--- /dev/null
+++ b/playground/typescript-router-playwright/src/components/icons/IconDocumentation.vue
@@ -0,0 +1,7 @@
+
+
+
diff --git a/playground/typescript-router-playwright/src/components/icons/IconEcosystem.vue b/playground/typescript-router-playwright/src/components/icons/IconEcosystem.vue
new file mode 100644
index 000000000..c3a4f078c
--- /dev/null
+++ b/playground/typescript-router-playwright/src/components/icons/IconEcosystem.vue
@@ -0,0 +1,7 @@
+
+
+
diff --git a/playground/typescript-router-playwright/src/components/icons/IconSupport.vue b/playground/typescript-router-playwright/src/components/icons/IconSupport.vue
new file mode 100644
index 000000000..7452834d3
--- /dev/null
+++ b/playground/typescript-router-playwright/src/components/icons/IconSupport.vue
@@ -0,0 +1,7 @@
+
+
+
diff --git a/playground/typescript-router-playwright/src/components/icons/IconTooling.vue b/playground/typescript-router-playwright/src/components/icons/IconTooling.vue
new file mode 100644
index 000000000..660598d7c
--- /dev/null
+++ b/playground/typescript-router-playwright/src/components/icons/IconTooling.vue
@@ -0,0 +1,19 @@
+
+
+
+
diff --git a/playground/typescript-router-playwright/src/main.ts b/playground/typescript-router-playwright/src/main.ts
new file mode 100644
index 000000000..5a5dbdba7
--- /dev/null
+++ b/playground/typescript-router-playwright/src/main.ts
@@ -0,0 +1,11 @@
+import './assets/main.css'
+
+import { createApp } from 'vue'
+import App from './App.vue'
+import router from './router'
+
+const app = createApp(App)
+
+app.use(router)
+
+app.mount('#app')
diff --git a/playground/typescript-router-playwright/src/router/index.ts b/playground/typescript-router-playwright/src/router/index.ts
new file mode 100644
index 000000000..a49ae507f
--- /dev/null
+++ b/playground/typescript-router-playwright/src/router/index.ts
@@ -0,0 +1,23 @@
+import { createRouter, createWebHistory } from 'vue-router'
+import HomeView from '../views/HomeView.vue'
+
+const router = createRouter({
+ history: createWebHistory(import.meta.env.BASE_URL),
+ routes: [
+ {
+ path: '/',
+ name: 'home',
+ component: HomeView
+ },
+ {
+ path: '/about',
+ name: 'about',
+ // route level code-splitting
+ // this generates a separate chunk (About.[hash].js) for this route
+ // which is lazy-loaded when the route is visited.
+ component: () => import('../views/AboutView.vue')
+ }
+ ]
+})
+
+export default router
diff --git a/playground/typescript-router-playwright/src/views/AboutView.vue b/playground/typescript-router-playwright/src/views/AboutView.vue
new file mode 100644
index 000000000..756ad2a17
--- /dev/null
+++ b/playground/typescript-router-playwright/src/views/AboutView.vue
@@ -0,0 +1,15 @@
+
+
+
This is an about page
+
+
+
+
diff --git a/playground/typescript-router-playwright/src/views/HomeView.vue b/playground/typescript-router-playwright/src/views/HomeView.vue
new file mode 100644
index 000000000..d5c0217e4
--- /dev/null
+++ b/playground/typescript-router-playwright/src/views/HomeView.vue
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
diff --git a/playground/typescript-router-playwright/tsconfig.app.json b/playground/typescript-router-playwright/tsconfig.app.json
new file mode 100644
index 000000000..e14c754d3
--- /dev/null
+++ b/playground/typescript-router-playwright/tsconfig.app.json
@@ -0,0 +1,14 @@
+{
+ "extends": "@vue/tsconfig/tsconfig.dom.json",
+ "include": ["env.d.ts", "src/**/*", "src/**/*.vue"],
+ "exclude": ["src/**/__tests__/*"],
+ "compilerOptions": {
+ "composite": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
+
+ "baseUrl": ".",
+ "paths": {
+ "@/*": ["./src/*"]
+ }
+ }
+}
diff --git a/playground/typescript-router-playwright/tsconfig.json b/playground/typescript-router-playwright/tsconfig.json
new file mode 100644
index 000000000..66b5e5703
--- /dev/null
+++ b/playground/typescript-router-playwright/tsconfig.json
@@ -0,0 +1,11 @@
+{
+ "files": [],
+ "references": [
+ {
+ "path": "./tsconfig.node.json"
+ },
+ {
+ "path": "./tsconfig.app.json"
+ }
+ ]
+}
diff --git a/playground/typescript-router-playwright/tsconfig.node.json b/playground/typescript-router-playwright/tsconfig.node.json
new file mode 100644
index 000000000..f09406303
--- /dev/null
+++ b/playground/typescript-router-playwright/tsconfig.node.json
@@ -0,0 +1,19 @@
+{
+ "extends": "@tsconfig/node20/tsconfig.json",
+ "include": [
+ "vite.config.*",
+ "vitest.config.*",
+ "cypress.config.*",
+ "nightwatch.conf.*",
+ "playwright.config.*"
+ ],
+ "compilerOptions": {
+ "composite": true,
+ "noEmit": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
+
+ "module": "ESNext",
+ "moduleResolution": "Bundler",
+ "types": ["node"]
+ }
+}
diff --git a/playground/typescript-router-playwright/vite.config.ts b/playground/typescript-router-playwright/vite.config.ts
new file mode 100644
index 000000000..5c45e1d9b
--- /dev/null
+++ b/playground/typescript-router-playwright/vite.config.ts
@@ -0,0 +1,16 @@
+import { fileURLToPath, URL } from 'node:url'
+
+import { defineConfig } from 'vite'
+import vue from '@vitejs/plugin-vue'
+
+// https://vitejs.dev/config/
+export default defineConfig({
+ plugins: [
+ vue(),
+ ],
+ resolve: {
+ alias: {
+ '@': fileURLToPath(new URL('./src', import.meta.url))
+ }
+ }
+})
diff --git a/playground/typescript-router-vitest-cypress/.gitignore b/playground/typescript-router-vitest-cypress/.gitignore
new file mode 100644
index 000000000..8ee54e8d3
--- /dev/null
+++ b/playground/typescript-router-vitest-cypress/.gitignore
@@ -0,0 +1,30 @@
+# 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/
+
+# Editor directories and files
+.vscode/*
+!.vscode/extensions.json
+.idea
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?
+
+*.tsbuildinfo
diff --git a/playground/typescript-router-vitest-cypress/README.md b/playground/typescript-router-vitest-cypress/README.md
new file mode 100644
index 000000000..1766beb75
--- /dev/null
+++ b/playground/typescript-router-vitest-cypress/README.md
@@ -0,0 +1,62 @@
+# typescript-router-vitest-cypress
+
+This template should help get you started developing with Vue 3 in Vite.
+
+## Recommended IDE Setup
+
+[VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur) + [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin).
+
+## Type Support for `.vue` Imports in TS
+
+TypeScript cannot handle type information for `.vue` imports by default, so we replace the `tsc` CLI with `vue-tsc` for type checking. In editors, we need [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin) to make the TypeScript language service aware of `.vue` types.
+
+If the standalone TypeScript plugin doesn't feel fast enough to you, Volar has also implemented a [Take Over Mode](https://github.com/johnsoncodehk/volar/discussions/471#discussioncomment-1361669) that is more performant. You can enable it by the following steps:
+
+1. Disable the built-in TypeScript Extension
+ 1) Run `Extensions: Show Built-in Extensions` from VSCode's command palette
+ 2) Find `TypeScript and JavaScript Language Features`, right click and select `Disable (Workspace)`
+2. Reload the VSCode window by running `Developer: Reload Window` from the command palette.
+
+## Customize configuration
+
+See [Vite Configuration Reference](https://vitejs.dev/config/).
+
+## Project Setup
+
+```sh
+pnpm install
+```
+
+### Compile and Hot-Reload for Development
+
+```sh
+pnpm dev
+```
+
+### Type-Check, Compile and Minify for Production
+
+```sh
+pnpm build
+```
+
+### Run Unit Tests with [Vitest](https://vitest.dev/)
+
+```sh
+pnpm test:unit
+```
+
+### Run End-to-End Tests with [Cypress](https://www.cypress.io/)
+
+```sh
+pnpm test:e2e:dev
+```
+
+This runs the end-to-end tests against the Vite development server.
+It is much faster than the production build.
+
+But it's still recommended to test the production build with `test:e2e` before deploying (e.g. in CI environments):
+
+```sh
+pnpm build
+pnpm test:e2e
+```
diff --git a/playground/typescript-router-vitest-cypress/cypress.config.ts b/playground/typescript-router-vitest-cypress/cypress.config.ts
new file mode 100644
index 000000000..0f66080fd
--- /dev/null
+++ b/playground/typescript-router-vitest-cypress/cypress.config.ts
@@ -0,0 +1,8 @@
+import { defineConfig } from 'cypress'
+
+export default defineConfig({
+ e2e: {
+ specPattern: 'cypress/e2e/**/*.{cy,spec}.{js,jsx,ts,tsx}',
+ baseUrl: 'http://localhost:4173'
+ }
+})
diff --git a/playground/typescript-router-vitest-cypress/cypress/e2e/example.cy.ts b/playground/typescript-router-vitest-cypress/cypress/e2e/example.cy.ts
new file mode 100644
index 000000000..7554c35d8
--- /dev/null
+++ b/playground/typescript-router-vitest-cypress/cypress/e2e/example.cy.ts
@@ -0,0 +1,8 @@
+// https://on.cypress.io/api
+
+describe('My First Test', () => {
+ it('visits the app root url', () => {
+ cy.visit('/')
+ cy.contains('h1', 'You did it!')
+ })
+})
diff --git a/playground/typescript-router-vitest-cypress/cypress/e2e/tsconfig.json b/playground/typescript-router-vitest-cypress/cypress/e2e/tsconfig.json
new file mode 100644
index 000000000..37748feb7
--- /dev/null
+++ b/playground/typescript-router-vitest-cypress/cypress/e2e/tsconfig.json
@@ -0,0 +1,10 @@
+{
+ "extends": "@vue/tsconfig/tsconfig.dom.json",
+ "include": ["./**/*", "../support/**/*"],
+ "compilerOptions": {
+ "isolatedModules": false,
+ "target": "es5",
+ "lib": ["es5", "dom"],
+ "types": ["cypress"]
+ }
+}
diff --git a/playground/typescript-router-vitest-cypress/cypress/fixtures/example.json b/playground/typescript-router-vitest-cypress/cypress/fixtures/example.json
new file mode 100644
index 000000000..02e425437
--- /dev/null
+++ b/playground/typescript-router-vitest-cypress/cypress/fixtures/example.json
@@ -0,0 +1,5 @@
+{
+ "name": "Using fixtures to represent data",
+ "email": "hello@cypress.io",
+ "body": "Fixtures are a great way to mock data for responses to routes"
+}
diff --git a/playground/typescript-router-vitest-cypress/cypress/support/commands.ts b/playground/typescript-router-vitest-cypress/cypress/support/commands.ts
new file mode 100644
index 000000000..9b7bb8e25
--- /dev/null
+++ b/playground/typescript-router-vitest-cypress/cypress/support/commands.ts
@@ -0,0 +1,39 @@
+///
+// ***********************************************
+// This example commands.ts shows you how to
+// create various custom commands and overwrite
+// existing commands.
+//
+// For more comprehensive examples of custom
+// commands please read more here:
+// https://on.cypress.io/custom-commands
+// ***********************************************
+//
+//
+// -- This is a parent command --
+// Cypress.Commands.add('login', (email, password) => { ... })
+//
+//
+// -- This is a child command --
+// Cypress.Commands.add('drag', { prevSubject: 'element'}, (subject, options) => { ... })
+//
+//
+// -- This is a dual command --
+// Cypress.Commands.add('dismiss', { prevSubject: 'optional'}, (subject, options) => { ... })
+//
+//
+// -- This will overwrite an existing command --
+// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... })
+//
+// declare global {
+// namespace Cypress {
+// interface Chainable {
+// login(email: string, password: string): Chainable
+// drag(subject: string, options?: Partial): Chainable
+// dismiss(subject: string, options?: Partial): Chainable
+// visit(originalFn: CommandOriginalFn, url: string, options: Partial): Chainable
+// }
+// }
+// }
+
+export {}
diff --git a/playground/typescript-router-vitest-cypress/cypress/support/e2e.ts b/playground/typescript-router-vitest-cypress/cypress/support/e2e.ts
new file mode 100644
index 000000000..d68db96df
--- /dev/null
+++ b/playground/typescript-router-vitest-cypress/cypress/support/e2e.ts
@@ -0,0 +1,20 @@
+// ***********************************************************
+// This example support/index.js is processed and
+// loaded automatically before your test files.
+//
+// This is a great place to put global configuration and
+// behavior that modifies Cypress.
+//
+// You can change the location of this file or turn off
+// automatically serving support files with the
+// 'supportFile' configuration option.
+//
+// You can read more here:
+// https://on.cypress.io/configuration
+// ***********************************************************
+
+// Import commands.js using ES2015 syntax:
+import './commands'
+
+// Alternatively you can use CommonJS syntax:
+// require('./commands')
diff --git a/playground/typescript-router-vitest-cypress/env.d.ts b/playground/typescript-router-vitest-cypress/env.d.ts
new file mode 100644
index 000000000..11f02fe2a
--- /dev/null
+++ b/playground/typescript-router-vitest-cypress/env.d.ts
@@ -0,0 +1 @@
+///
diff --git a/playground/typescript-router-vitest-cypress/index.html b/playground/typescript-router-vitest-cypress/index.html
new file mode 100644
index 000000000..a88854489
--- /dev/null
+++ b/playground/typescript-router-vitest-cypress/index.html
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+ Vite App
+
+
+
+
+
+
diff --git a/playground/typescript-router-vitest-cypress/package.json b/playground/typescript-router-vitest-cypress/package.json
new file mode 100644
index 000000000..3986af842
--- /dev/null
+++ b/playground/typescript-router-vitest-cypress/package.json
@@ -0,0 +1,36 @@
+{
+ "name": "typescript-router-vitest-cypress",
+ "version": "0.0.0",
+ "private": true,
+ "type": "module",
+ "scripts": {
+ "dev": "vite",
+ "build": "run-p type-check \"build-only {@}\" --",
+ "preview": "vite preview",
+ "test:unit": "vitest",
+ "test:e2e": "start-server-and-test preview http://localhost:4173 'cypress run --e2e'",
+ "test:e2e:dev": "start-server-and-test 'vite dev --port 4173' http://localhost:4173 'cypress open --e2e'",
+ "build-only": "vite build",
+ "type-check": "vue-tsc --build --force"
+ },
+ "dependencies": {
+ "vue": "^3.4.15",
+ "vue-router": "^4.2.5"
+ },
+ "devDependencies": {
+ "@tsconfig/node20": "^20.1.2",
+ "@types/jsdom": "^21.1.6",
+ "@types/node": "^20.11.16",
+ "@vitejs/plugin-vue": "^5.0.3",
+ "@vue/test-utils": "^2.4.4",
+ "@vue/tsconfig": "^0.5.1",
+ "cypress": "^13.6.4",
+ "jsdom": "^24.0.0",
+ "npm-run-all2": "^6.1.2",
+ "start-server-and-test": "^2.0.3",
+ "typescript": "~5.3.0",
+ "vite": "^5.0.11",
+ "vitest": "^1.2.2",
+ "vue-tsc": "^1.8.27"
+ }
+}
diff --git a/playground/typescript-router-vitest-cypress/public/favicon.ico b/playground/typescript-router-vitest-cypress/public/favicon.ico
new file mode 100644
index 000000000..df36fcfb7
Binary files /dev/null and b/playground/typescript-router-vitest-cypress/public/favicon.ico differ
diff --git a/playground/typescript-router-vitest-cypress/src/App.vue b/playground/typescript-router-vitest-cypress/src/App.vue
new file mode 100644
index 000000000..7905b0516
--- /dev/null
+++ b/playground/typescript-router-vitest-cypress/src/App.vue
@@ -0,0 +1,85 @@
+
+
+
+
+
+
+
+ You’ve successfully created a project with
+ Vite +
+ Vue 3. What's next?
+
+
+
+
+
diff --git a/playground/typescript-router-vitest-cypress/src/components/TheWelcome.vue b/playground/typescript-router-vitest-cypress/src/components/TheWelcome.vue
new file mode 100644
index 000000000..49d8f7354
--- /dev/null
+++ b/playground/typescript-router-vitest-cypress/src/components/TheWelcome.vue
@@ -0,0 +1,88 @@
+
+
+
+
+
+
+
+ Documentation
+
+ Vue’s
+ official documentation
+ provides you with all information you need to get started.
+
+
+
+
+
+
+ Tooling
+
+ This project is served and bundled with
+ Vite. The
+ recommended IDE setup is
+ VSCode +
+ Volar. If
+ you need to test your components and web pages, check out
+ Cypress and
+ Cypress Component Testing.
+
+
+
+ More instructions are available in README.md.
+
+
+
+
+
+
+ Ecosystem
+
+ Get official tools and libraries for your project:
+ Pinia,
+ Vue Router,
+ Vue Test Utils, and
+ Vue Dev Tools. If
+ you need more resources, we suggest paying
+ Awesome Vue
+ a visit.
+
+
+
+
+
+
+ Community
+
+ Got stuck? Ask your question on
+ Vue Land, our official
+ Discord server, or
+ StackOverflow. You should also subscribe to
+ our mailing list and follow
+ the official
+ @vuejs
+ twitter account for latest news in the Vue world.
+
+
+
+
+
+
+ Support Vue
+
+ As an independent project, Vue relies on community backing for its sustainability. You can help
+ us by
+ becoming a sponsor.
+
+
diff --git a/playground/typescript-router-vitest-cypress/src/components/WelcomeItem.vue b/playground/typescript-router-vitest-cypress/src/components/WelcomeItem.vue
new file mode 100644
index 000000000..6d7086aea
--- /dev/null
+++ b/playground/typescript-router-vitest-cypress/src/components/WelcomeItem.vue
@@ -0,0 +1,87 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/playground/typescript-router-vitest-cypress/src/components/__tests__/HelloWorld.spec.ts b/playground/typescript-router-vitest-cypress/src/components/__tests__/HelloWorld.spec.ts
new file mode 100644
index 000000000..253320200
--- /dev/null
+++ b/playground/typescript-router-vitest-cypress/src/components/__tests__/HelloWorld.spec.ts
@@ -0,0 +1,11 @@
+import { describe, it, expect } from 'vitest'
+
+import { mount } from '@vue/test-utils'
+import HelloWorld from '../HelloWorld.vue'
+
+describe('HelloWorld', () => {
+ it('renders properly', () => {
+ const wrapper = mount(HelloWorld, { props: { msg: 'Hello Vitest' } })
+ expect(wrapper.text()).toContain('Hello Vitest')
+ })
+})
diff --git a/playground/typescript-router-vitest-cypress/src/components/icons/IconCommunity.vue b/playground/typescript-router-vitest-cypress/src/components/icons/IconCommunity.vue
new file mode 100644
index 000000000..2dc8b0552
--- /dev/null
+++ b/playground/typescript-router-vitest-cypress/src/components/icons/IconCommunity.vue
@@ -0,0 +1,7 @@
+
+
+
diff --git a/playground/typescript-router-vitest-cypress/src/components/icons/IconDocumentation.vue b/playground/typescript-router-vitest-cypress/src/components/icons/IconDocumentation.vue
new file mode 100644
index 000000000..6d4791cfb
--- /dev/null
+++ b/playground/typescript-router-vitest-cypress/src/components/icons/IconDocumentation.vue
@@ -0,0 +1,7 @@
+
+
+
diff --git a/playground/typescript-router-vitest-cypress/src/components/icons/IconEcosystem.vue b/playground/typescript-router-vitest-cypress/src/components/icons/IconEcosystem.vue
new file mode 100644
index 000000000..c3a4f078c
--- /dev/null
+++ b/playground/typescript-router-vitest-cypress/src/components/icons/IconEcosystem.vue
@@ -0,0 +1,7 @@
+
+
+
diff --git a/playground/typescript-router-vitest-cypress/src/components/icons/IconSupport.vue b/playground/typescript-router-vitest-cypress/src/components/icons/IconSupport.vue
new file mode 100644
index 000000000..7452834d3
--- /dev/null
+++ b/playground/typescript-router-vitest-cypress/src/components/icons/IconSupport.vue
@@ -0,0 +1,7 @@
+
+
+
diff --git a/playground/typescript-router-vitest-cypress/src/components/icons/IconTooling.vue b/playground/typescript-router-vitest-cypress/src/components/icons/IconTooling.vue
new file mode 100644
index 000000000..660598d7c
--- /dev/null
+++ b/playground/typescript-router-vitest-cypress/src/components/icons/IconTooling.vue
@@ -0,0 +1,19 @@
+
+
+
+
diff --git a/playground/typescript-router-vitest-cypress/src/main.ts b/playground/typescript-router-vitest-cypress/src/main.ts
new file mode 100644
index 000000000..5a5dbdba7
--- /dev/null
+++ b/playground/typescript-router-vitest-cypress/src/main.ts
@@ -0,0 +1,11 @@
+import './assets/main.css'
+
+import { createApp } from 'vue'
+import App from './App.vue'
+import router from './router'
+
+const app = createApp(App)
+
+app.use(router)
+
+app.mount('#app')
diff --git a/playground/typescript-router-vitest-cypress/src/router/index.ts b/playground/typescript-router-vitest-cypress/src/router/index.ts
new file mode 100644
index 000000000..a49ae507f
--- /dev/null
+++ b/playground/typescript-router-vitest-cypress/src/router/index.ts
@@ -0,0 +1,23 @@
+import { createRouter, createWebHistory } from 'vue-router'
+import HomeView from '../views/HomeView.vue'
+
+const router = createRouter({
+ history: createWebHistory(import.meta.env.BASE_URL),
+ routes: [
+ {
+ path: '/',
+ name: 'home',
+ component: HomeView
+ },
+ {
+ path: '/about',
+ name: 'about',
+ // route level code-splitting
+ // this generates a separate chunk (About.[hash].js) for this route
+ // which is lazy-loaded when the route is visited.
+ component: () => import('../views/AboutView.vue')
+ }
+ ]
+})
+
+export default router
diff --git a/playground/typescript-router-vitest-cypress/src/views/AboutView.vue b/playground/typescript-router-vitest-cypress/src/views/AboutView.vue
new file mode 100644
index 000000000..756ad2a17
--- /dev/null
+++ b/playground/typescript-router-vitest-cypress/src/views/AboutView.vue
@@ -0,0 +1,15 @@
+
+
+
This is an about page
+
+
+
+
diff --git a/playground/typescript-router-vitest-cypress/src/views/HomeView.vue b/playground/typescript-router-vitest-cypress/src/views/HomeView.vue
new file mode 100644
index 000000000..d5c0217e4
--- /dev/null
+++ b/playground/typescript-router-vitest-cypress/src/views/HomeView.vue
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
diff --git a/playground/typescript-router-vitest-cypress/tsconfig.app.json b/playground/typescript-router-vitest-cypress/tsconfig.app.json
new file mode 100644
index 000000000..e14c754d3
--- /dev/null
+++ b/playground/typescript-router-vitest-cypress/tsconfig.app.json
@@ -0,0 +1,14 @@
+{
+ "extends": "@vue/tsconfig/tsconfig.dom.json",
+ "include": ["env.d.ts", "src/**/*", "src/**/*.vue"],
+ "exclude": ["src/**/__tests__/*"],
+ "compilerOptions": {
+ "composite": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
+
+ "baseUrl": ".",
+ "paths": {
+ "@/*": ["./src/*"]
+ }
+ }
+}
diff --git a/playground/typescript-router-vitest-cypress/tsconfig.json b/playground/typescript-router-vitest-cypress/tsconfig.json
new file mode 100644
index 000000000..5304731b8
--- /dev/null
+++ b/playground/typescript-router-vitest-cypress/tsconfig.json
@@ -0,0 +1,17 @@
+{
+ "files": [],
+ "references": [
+ {
+ "path": "./tsconfig.node.json"
+ },
+ {
+ "path": "./tsconfig.app.json"
+ },
+ {
+ "path": "./tsconfig.vitest.json"
+ }
+ ],
+ "compilerOptions": {
+ "module": "NodeNext"
+ }
+}
diff --git a/playground/typescript-router-vitest-cypress/tsconfig.node.json b/playground/typescript-router-vitest-cypress/tsconfig.node.json
new file mode 100644
index 000000000..f09406303
--- /dev/null
+++ b/playground/typescript-router-vitest-cypress/tsconfig.node.json
@@ -0,0 +1,19 @@
+{
+ "extends": "@tsconfig/node20/tsconfig.json",
+ "include": [
+ "vite.config.*",
+ "vitest.config.*",
+ "cypress.config.*",
+ "nightwatch.conf.*",
+ "playwright.config.*"
+ ],
+ "compilerOptions": {
+ "composite": true,
+ "noEmit": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
+
+ "module": "ESNext",
+ "moduleResolution": "Bundler",
+ "types": ["node"]
+ }
+}
diff --git a/playground/typescript-router-vitest-cypress/tsconfig.vitest.json b/playground/typescript-router-vitest-cypress/tsconfig.vitest.json
new file mode 100644
index 000000000..571995d11
--- /dev/null
+++ b/playground/typescript-router-vitest-cypress/tsconfig.vitest.json
@@ -0,0 +1,11 @@
+{
+ "extends": "./tsconfig.app.json",
+ "exclude": [],
+ "compilerOptions": {
+ "composite": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.vitest.tsbuildinfo",
+
+ "lib": [],
+ "types": ["node", "jsdom"]
+ }
+}
diff --git a/playground/typescript-router-vitest-cypress/vite.config.ts b/playground/typescript-router-vitest-cypress/vite.config.ts
new file mode 100644
index 000000000..5c45e1d9b
--- /dev/null
+++ b/playground/typescript-router-vitest-cypress/vite.config.ts
@@ -0,0 +1,16 @@
+import { fileURLToPath, URL } from 'node:url'
+
+import { defineConfig } from 'vite'
+import vue from '@vitejs/plugin-vue'
+
+// https://vitejs.dev/config/
+export default defineConfig({
+ plugins: [
+ vue(),
+ ],
+ resolve: {
+ alias: {
+ '@': fileURLToPath(new URL('./src', import.meta.url))
+ }
+ }
+})
diff --git a/playground/typescript-router-vitest-cypress/vitest.config.ts b/playground/typescript-router-vitest-cypress/vitest.config.ts
new file mode 100644
index 000000000..10067d578
--- /dev/null
+++ b/playground/typescript-router-vitest-cypress/vitest.config.ts
@@ -0,0 +1,14 @@
+import { fileURLToPath } from 'node:url'
+import { mergeConfig, defineConfig, configDefaults } from 'vitest/config'
+import viteConfig from './vite.config'
+
+export default mergeConfig(
+ viteConfig,
+ defineConfig({
+ test: {
+ environment: 'jsdom',
+ exclude: [...configDefaults.exclude, 'e2e/*'],
+ root: fileURLToPath(new URL('./', import.meta.url))
+ }
+ })
+)
diff --git a/playground/typescript-router-vitest-nightwatch/.gitignore b/playground/typescript-router-vitest-nightwatch/.gitignore
new file mode 100644
index 000000000..0b938f131
--- /dev/null
+++ b/playground/typescript-router-vitest-nightwatch/.gitignore
@@ -0,0 +1,33 @@
+# 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/
+
+# Editor directories and files
+.vscode/*
+!.vscode/extensions.json
+.idea
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?
+
+*.tsbuildinfo
+
+logs/
+tests_output/
diff --git a/playground/typescript-router-vitest-nightwatch/.vscode/extensions.json b/playground/typescript-router-vitest-nightwatch/.vscode/extensions.json
new file mode 100644
index 000000000..dd9668a5c
--- /dev/null
+++ b/playground/typescript-router-vitest-nightwatch/.vscode/extensions.json
@@ -0,0 +1,3 @@
+{
+ "recommendations": ["browserstackcom.nightwatch"]
+}
diff --git a/playground/typescript-router-vitest-nightwatch/README.md b/playground/typescript-router-vitest-nightwatch/README.md
new file mode 100644
index 000000000..0fab55c12
--- /dev/null
+++ b/playground/typescript-router-vitest-nightwatch/README.md
@@ -0,0 +1,69 @@
+# typescript-router-vitest-nightwatch
+
+This template should help get you started developing with Vue 3 in Vite.
+
+## Recommended IDE Setup
+
+[VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur) + [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin).
+
+## Type Support for `.vue` Imports in TS
+
+TypeScript cannot handle type information for `.vue` imports by default, so we replace the `tsc` CLI with `vue-tsc` for type checking. In editors, we need [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin) to make the TypeScript language service aware of `.vue` types.
+
+If the standalone TypeScript plugin doesn't feel fast enough to you, Volar has also implemented a [Take Over Mode](https://github.com/johnsoncodehk/volar/discussions/471#discussioncomment-1361669) that is more performant. You can enable it by the following steps:
+
+1. Disable the built-in TypeScript Extension
+ 1) Run `Extensions: Show Built-in Extensions` from VSCode's command palette
+ 2) Find `TypeScript and JavaScript Language Features`, right click and select `Disable (Workspace)`
+2. Reload the VSCode window by running `Developer: Reload Window` from the command palette.
+
+## Customize configuration
+
+See [Vite Configuration Reference](https://vitejs.dev/config/).
+
+## Project Setup
+
+```sh
+pnpm install
+```
+
+### Compile and Hot-Reload for Development
+
+```sh
+pnpm dev
+```
+
+### Type-Check, Compile and Minify for Production
+
+```sh
+pnpm build
+```
+
+### Run Unit Tests with [Vitest](https://vitest.dev/)
+
+```sh
+pnpm test:unit
+```
+
+### Run End-to-End Tests with [Nightwatch](https://nightwatchjs.org/)
+
+```sh
+# When using CI, the project must be built first.
+pnpm build
+
+# Runs the end-to-end tests
+pnpm test:e2e
+# Runs the tests only on Chrome
+pnpm test:e2e --env chrome
+# Runs the tests of a specific file
+pnpm test:e2e tests/e2e/example.ts
+# Runs the tests in debug mode
+pnpm test:e2e --debug
+```
+
+### Run Headed Component Tests with [Nightwatch Component Testing](https://nightwatchjs.org/guide/component-testing/introduction.html)
+
+```sh
+pnpm test:unit
+pnpm test:unit -- --headless # for headless testing
+```
diff --git a/playground/typescript-router-vitest-nightwatch/env.d.ts b/playground/typescript-router-vitest-nightwatch/env.d.ts
new file mode 100644
index 000000000..11f02fe2a
--- /dev/null
+++ b/playground/typescript-router-vitest-nightwatch/env.d.ts
@@ -0,0 +1 @@
+///
diff --git a/playground/typescript-router-vitest-nightwatch/index.html b/playground/typescript-router-vitest-nightwatch/index.html
new file mode 100644
index 000000000..a88854489
--- /dev/null
+++ b/playground/typescript-router-vitest-nightwatch/index.html
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+ Vite App
+
+
+
+
+
+
diff --git a/playground/typescript-router-vitest-nightwatch/nightwatch.conf.cjs b/playground/typescript-router-vitest-nightwatch/nightwatch.conf.cjs
new file mode 100644
index 000000000..542647e5e
--- /dev/null
+++ b/playground/typescript-router-vitest-nightwatch/nightwatch.conf.cjs
@@ -0,0 +1,153 @@
+//
+// Refer to the online docs for more details:
+// https://nightwatchjs.org/guide/configuration/nightwatch-configuration-file.html
+//
+// _ _ _ _ _ _ _
+// | \ | |(_) | | | | | | | |
+// | \| | _ __ _ | |__ | |_ __ __ __ _ | |_ ___ | |__
+// | . ` || | / _` || '_ \ | __|\ \ /\ / / / _` || __| / __|| '_ \
+// | |\ || || (_| || | | || |_ \ V V / | (_| || |_ | (__ | | | |
+// \_| \_/|_| \__, ||_| |_| \__| \_/\_/ \__,_| \__| \___||_| |_|
+// __/ |
+// |___/
+//
+
+module.exports = {
+ // An array of folders (excluding subfolders) where your tests are located;
+ // if this is not specified, the test source must be passed as the second argument to the test runner.
+ src_folders: [],
+
+ // See https://nightwatchjs.org/guide/concepts/page-object-model.html
+ page_objects_path: [],
+
+ // See https://nightwatchjs.org/guide/extending-nightwatch/adding-custom-commands.html
+ custom_commands_path: [],
+
+ // See https://nightwatchjs.org/guide/extending-nightwatch/adding-custom-assertions.html
+ custom_assertions_path: [],
+
+ // See https://nightwatchjs.org/guide/extending-nightwatch/adding-plugins.html
+ plugins: ['@nightwatch/vue'],
+
+ // See https://nightwatchjs.org/guide/concepts/test-globals.html#external-test-globals
+ globals_path: '',
+
+ vite_dev_server: {
+ start_vite: true,
+ port: process.env.CI ? 4173 : 5173
+ },
+
+ webdriver: {},
+
+ test_workers: {
+ enabled: true,
+ workers: 'auto'
+ },
+
+ test_settings: {
+ default: {
+ disable_error_log: false,
+ launch_url: `http://localhost:${process.env.CI ? '4173' : '5173'}`,
+
+ screenshots: {
+ enabled: false,
+ path: 'screens',
+ on_failure: true
+ },
+
+ desiredCapabilities: {
+ browserName: 'firefox'
+ },
+
+ webdriver: {
+ start_process: true,
+ server_path: ''
+ }
+ },
+
+ safari: {
+ desiredCapabilities: {
+ browserName: 'safari',
+ alwaysMatch: {
+ acceptInsecureCerts: false
+ }
+ },
+ webdriver: {
+ start_process: true,
+ server_path: ''
+ }
+ },
+
+ firefox: {
+ desiredCapabilities: {
+ browserName: 'firefox',
+ alwaysMatch: {
+ acceptInsecureCerts: true,
+ 'moz:firefoxOptions': {
+ args: [
+ // '-headless',
+ // '-verbose'
+ ]
+ }
+ }
+ },
+ webdriver: {
+ start_process: true,
+ server_path: '',
+ cli_args: [
+ // very verbose geckodriver logs
+ // '-vv'
+ ]
+ }
+ },
+
+ chrome: {
+ desiredCapabilities: {
+ browserName: 'chrome',
+ 'goog:chromeOptions': {
+ // More info on Chromedriver: https://sites.google.com/a/chromium.org/chromedriver/
+ //
+ // w3c:false tells Chromedriver to run using the legacy JSONWire protocol (not required in Chrome 78)
+ w3c: true,
+ args: [
+ //'--no-sandbox',
+ //'--ignore-certificate-errors',
+ //'--allow-insecure-localhost',
+ //'--headless'
+ ]
+ }
+ },
+
+ webdriver: {
+ start_process: true,
+ server_path: '',
+ cli_args: [
+ // --verbose
+ ]
+ }
+ },
+
+ edge: {
+ desiredCapabilities: {
+ browserName: 'MicrosoftEdge',
+ 'ms:edgeOptions': {
+ w3c: true,
+ // More info on EdgeDriver: https://docs.microsoft.com/en-us/microsoft-edge/webdriver-chromium/capabilities-edge-options
+ args: [
+ //'--headless'
+ ]
+ }
+ },
+
+ webdriver: {
+ start_process: true,
+ // Download msedgedriver from https://docs.microsoft.com/en-us/microsoft-edge/webdriver-chromium/
+ // and set the location below:
+ server_path: '',
+ cli_args: [
+ // --verbose
+ ]
+ }
+ }
+ }
+}
diff --git a/playground/typescript-router-vitest-nightwatch/nightwatch/nightwatch.d.ts b/playground/typescript-router-vitest-nightwatch/nightwatch/nightwatch.d.ts
new file mode 100644
index 000000000..616e63f9f
--- /dev/null
+++ b/playground/typescript-router-vitest-nightwatch/nightwatch/nightwatch.d.ts
@@ -0,0 +1,13 @@
+import { NightwatchCustomAssertions, NightwatchCustomCommands } from 'nightwatch'
+
+declare module 'nightwatch' {
+ interface NightwatchCustomAssertions {
+ // Add your custom assertions' types here
+ // elementHasCount: (selector: string, count: number) => NightwatchBrowser
+ }
+
+ interface NightwatchCustomCommands {
+ // Add your custom commands' types here
+ // strictClick: (selector: string) => NightwatchBrowser
+ }
+}
diff --git a/playground/typescript-router-vitest-nightwatch/nightwatch/tsconfig.json b/playground/typescript-router-vitest-nightwatch/nightwatch/tsconfig.json
new file mode 100644
index 000000000..8cd7ca1da
--- /dev/null
+++ b/playground/typescript-router-vitest-nightwatch/nightwatch/tsconfig.json
@@ -0,0 +1,20 @@
+{
+ "extends": "@tsconfig/node20/tsconfig.json",
+ "compilerOptions": {
+ "composite": true,
+ "noEmit": true,
+ "tsBuildInfoFile": "../node_modules/.tmp/tsconfig.nightwatch.tsbuildinfo",
+
+ "target": "ESNext",
+ "module": "commonjs",
+ "moduleResolution": "node",
+ "rootDir": "../",
+ "lib": ["ESNext", "dom"],
+ "types": ["nightwatch"]
+ },
+ "include": ["../node_modules/@nightwatch/**/*", "../src/components/**/*", "../tests/e2e/**/*"],
+ "ts-node": {
+ "transpileOnly": true
+ },
+ "files": ["nightwatch.d.ts"]
+}
diff --git a/playground/typescript-router-vitest-nightwatch/package.json b/playground/typescript-router-vitest-nightwatch/package.json
new file mode 100644
index 000000000..61bb96d9c
--- /dev/null
+++ b/playground/typescript-router-vitest-nightwatch/package.json
@@ -0,0 +1,39 @@
+{
+ "name": "typescript-router-vitest-nightwatch",
+ "version": "0.0.0",
+ "private": true,
+ "type": "module",
+ "scripts": {
+ "dev": "vite",
+ "build": "run-p type-check \"build-only {@}\" --",
+ "preview": "vite preview",
+ "test:unit": "vitest",
+ "test:e2e": "nightwatch tests/e2e/*",
+ "build-only": "vite build",
+ "type-check": "vue-tsc --build --force"
+ },
+ "dependencies": {
+ "vue": "^3.4.15",
+ "vue-router": "^4.2.5"
+ },
+ "devDependencies": {
+ "@nightwatch/vue": "^3.1.0",
+ "@tsconfig/node20": "^20.1.2",
+ "@types/jsdom": "^21.1.6",
+ "@types/node": "^20.11.16",
+ "@vitejs/plugin-vue": "^5.0.3",
+ "@vue/test-utils": "^2.4.4",
+ "@vue/tsconfig": "^0.5.1",
+ "chromedriver": "^121.0.0",
+ "geckodriver": "^4.3.2",
+ "jsdom": "^24.0.0",
+ "nightwatch": "^3.4.0",
+ "npm-run-all2": "^6.1.2",
+ "ts-node": "^10.9.2",
+ "typescript": "~5.3.0",
+ "vite": "^5.0.11",
+ "vite-plugin-nightwatch": "^0.4.6",
+ "vitest": "^1.2.2",
+ "vue-tsc": "^1.8.27"
+ }
+}
diff --git a/playground/typescript-router-vitest-nightwatch/public/favicon.ico b/playground/typescript-router-vitest-nightwatch/public/favicon.ico
new file mode 100644
index 000000000..df36fcfb7
Binary files /dev/null and b/playground/typescript-router-vitest-nightwatch/public/favicon.ico differ
diff --git a/playground/typescript-router-vitest-nightwatch/src/App.vue b/playground/typescript-router-vitest-nightwatch/src/App.vue
new file mode 100644
index 000000000..7905b0516
--- /dev/null
+++ b/playground/typescript-router-vitest-nightwatch/src/App.vue
@@ -0,0 +1,85 @@
+
+
+
+
+
+
+
+ You’ve successfully created a project with
+ Vite +
+ Vue 3. What's next?
+
+
+
+
+
diff --git a/playground/typescript-router-vitest-nightwatch/src/components/TheWelcome.vue b/playground/typescript-router-vitest-nightwatch/src/components/TheWelcome.vue
new file mode 100644
index 000000000..49d8f7354
--- /dev/null
+++ b/playground/typescript-router-vitest-nightwatch/src/components/TheWelcome.vue
@@ -0,0 +1,88 @@
+
+
+
+
+
+
+
+ Documentation
+
+ Vue’s
+ official documentation
+ provides you with all information you need to get started.
+
+
+
+
+
+
+ Tooling
+
+ This project is served and bundled with
+ Vite. The
+ recommended IDE setup is
+ VSCode +
+ Volar. If
+ you need to test your components and web pages, check out
+ Cypress and
+ Cypress Component Testing.
+
+
+
+ More instructions are available in README.md.
+
+
+
+
+
+
+ Ecosystem
+
+ Get official tools and libraries for your project:
+ Pinia,
+ Vue Router,
+ Vue Test Utils, and
+ Vue Dev Tools. If
+ you need more resources, we suggest paying
+ Awesome Vue
+ a visit.
+
+
+
+
+
+
+ Community
+
+ Got stuck? Ask your question on
+ Vue Land, our official
+ Discord server, or
+ StackOverflow. You should also subscribe to
+ our mailing list and follow
+ the official
+ @vuejs
+ twitter account for latest news in the Vue world.
+
+
+
+
+
+
+ Support Vue
+
+ As an independent project, Vue relies on community backing for its sustainability. You can help
+ us by
+ becoming a sponsor.
+
+
diff --git a/playground/typescript-router-vitest-nightwatch/src/components/WelcomeItem.vue b/playground/typescript-router-vitest-nightwatch/src/components/WelcomeItem.vue
new file mode 100644
index 000000000..6d7086aea
--- /dev/null
+++ b/playground/typescript-router-vitest-nightwatch/src/components/WelcomeItem.vue
@@ -0,0 +1,87 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/playground/typescript-router-vitest-nightwatch/src/components/__tests__/HelloWorld.spec.ts b/playground/typescript-router-vitest-nightwatch/src/components/__tests__/HelloWorld.spec.ts
new file mode 100644
index 000000000..253320200
--- /dev/null
+++ b/playground/typescript-router-vitest-nightwatch/src/components/__tests__/HelloWorld.spec.ts
@@ -0,0 +1,11 @@
+import { describe, it, expect } from 'vitest'
+
+import { mount } from '@vue/test-utils'
+import HelloWorld from '../HelloWorld.vue'
+
+describe('HelloWorld', () => {
+ it('renders properly', () => {
+ const wrapper = mount(HelloWorld, { props: { msg: 'Hello Vitest' } })
+ expect(wrapper.text()).toContain('Hello Vitest')
+ })
+})
diff --git a/playground/typescript-router-vitest-nightwatch/src/components/icons/IconCommunity.vue b/playground/typescript-router-vitest-nightwatch/src/components/icons/IconCommunity.vue
new file mode 100644
index 000000000..2dc8b0552
--- /dev/null
+++ b/playground/typescript-router-vitest-nightwatch/src/components/icons/IconCommunity.vue
@@ -0,0 +1,7 @@
+
+
+
diff --git a/playground/typescript-router-vitest-nightwatch/src/components/icons/IconDocumentation.vue b/playground/typescript-router-vitest-nightwatch/src/components/icons/IconDocumentation.vue
new file mode 100644
index 000000000..6d4791cfb
--- /dev/null
+++ b/playground/typescript-router-vitest-nightwatch/src/components/icons/IconDocumentation.vue
@@ -0,0 +1,7 @@
+
+
+
diff --git a/playground/typescript-router-vitest-nightwatch/src/components/icons/IconEcosystem.vue b/playground/typescript-router-vitest-nightwatch/src/components/icons/IconEcosystem.vue
new file mode 100644
index 000000000..c3a4f078c
--- /dev/null
+++ b/playground/typescript-router-vitest-nightwatch/src/components/icons/IconEcosystem.vue
@@ -0,0 +1,7 @@
+
+
+
diff --git a/playground/typescript-router-vitest-nightwatch/src/components/icons/IconSupport.vue b/playground/typescript-router-vitest-nightwatch/src/components/icons/IconSupport.vue
new file mode 100644
index 000000000..7452834d3
--- /dev/null
+++ b/playground/typescript-router-vitest-nightwatch/src/components/icons/IconSupport.vue
@@ -0,0 +1,7 @@
+
+
+
diff --git a/playground/typescript-router-vitest-nightwatch/src/components/icons/IconTooling.vue b/playground/typescript-router-vitest-nightwatch/src/components/icons/IconTooling.vue
new file mode 100644
index 000000000..660598d7c
--- /dev/null
+++ b/playground/typescript-router-vitest-nightwatch/src/components/icons/IconTooling.vue
@@ -0,0 +1,19 @@
+
+
+
+
diff --git a/playground/typescript-router-vitest-nightwatch/src/main.ts b/playground/typescript-router-vitest-nightwatch/src/main.ts
new file mode 100644
index 000000000..5a5dbdba7
--- /dev/null
+++ b/playground/typescript-router-vitest-nightwatch/src/main.ts
@@ -0,0 +1,11 @@
+import './assets/main.css'
+
+import { createApp } from 'vue'
+import App from './App.vue'
+import router from './router'
+
+const app = createApp(App)
+
+app.use(router)
+
+app.mount('#app')
diff --git a/playground/typescript-router-vitest-nightwatch/src/router/index.ts b/playground/typescript-router-vitest-nightwatch/src/router/index.ts
new file mode 100644
index 000000000..a49ae507f
--- /dev/null
+++ b/playground/typescript-router-vitest-nightwatch/src/router/index.ts
@@ -0,0 +1,23 @@
+import { createRouter, createWebHistory } from 'vue-router'
+import HomeView from '../views/HomeView.vue'
+
+const router = createRouter({
+ history: createWebHistory(import.meta.env.BASE_URL),
+ routes: [
+ {
+ path: '/',
+ name: 'home',
+ component: HomeView
+ },
+ {
+ path: '/about',
+ name: 'about',
+ // route level code-splitting
+ // this generates a separate chunk (About.[hash].js) for this route
+ // which is lazy-loaded when the route is visited.
+ component: () => import('../views/AboutView.vue')
+ }
+ ]
+})
+
+export default router
diff --git a/playground/typescript-router-vitest-nightwatch/src/views/AboutView.vue b/playground/typescript-router-vitest-nightwatch/src/views/AboutView.vue
new file mode 100644
index 000000000..756ad2a17
--- /dev/null
+++ b/playground/typescript-router-vitest-nightwatch/src/views/AboutView.vue
@@ -0,0 +1,15 @@
+
+
+
This is an about page
+
+
+
+
diff --git a/playground/typescript-router-vitest-nightwatch/src/views/HomeView.vue b/playground/typescript-router-vitest-nightwatch/src/views/HomeView.vue
new file mode 100644
index 000000000..d5c0217e4
--- /dev/null
+++ b/playground/typescript-router-vitest-nightwatch/src/views/HomeView.vue
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
diff --git a/playground/typescript-router-vitest-nightwatch/tests/e2e/example.ts b/playground/typescript-router-vitest-nightwatch/tests/e2e/example.ts
new file mode 100644
index 000000000..43be3fce1
--- /dev/null
+++ b/playground/typescript-router-vitest-nightwatch/tests/e2e/example.ts
@@ -0,0 +1,11 @@
+describe('My First Test', function () {
+ before((browser) => {
+ browser.init()
+ })
+
+ it('visits the app root url', function () {
+ browser.assert.textContains('.green', 'You did it!')
+ })
+
+ after((browser) => browser.end())
+})
diff --git a/playground/typescript-router-vitest-nightwatch/tsconfig.app.json b/playground/typescript-router-vitest-nightwatch/tsconfig.app.json
new file mode 100644
index 000000000..e14c754d3
--- /dev/null
+++ b/playground/typescript-router-vitest-nightwatch/tsconfig.app.json
@@ -0,0 +1,14 @@
+{
+ "extends": "@vue/tsconfig/tsconfig.dom.json",
+ "include": ["env.d.ts", "src/**/*", "src/**/*.vue"],
+ "exclude": ["src/**/__tests__/*"],
+ "compilerOptions": {
+ "composite": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
+
+ "baseUrl": ".",
+ "paths": {
+ "@/*": ["./src/*"]
+ }
+ }
+}
diff --git a/playground/typescript-router-vitest-nightwatch/tsconfig.json b/playground/typescript-router-vitest-nightwatch/tsconfig.json
new file mode 100644
index 000000000..a5352e667
--- /dev/null
+++ b/playground/typescript-router-vitest-nightwatch/tsconfig.json
@@ -0,0 +1,17 @@
+{
+ "files": [],
+ "references": [
+ {
+ "path": "./tsconfig.node.json"
+ },
+ {
+ "path": "./tsconfig.app.json"
+ },
+ {
+ "path": "./tsconfig.vitest.json"
+ },
+ {
+ "path": "./nightwatch/tsconfig.json"
+ }
+ ]
+}
diff --git a/playground/typescript-router-vitest-nightwatch/tsconfig.node.json b/playground/typescript-router-vitest-nightwatch/tsconfig.node.json
new file mode 100644
index 000000000..f09406303
--- /dev/null
+++ b/playground/typescript-router-vitest-nightwatch/tsconfig.node.json
@@ -0,0 +1,19 @@
+{
+ "extends": "@tsconfig/node20/tsconfig.json",
+ "include": [
+ "vite.config.*",
+ "vitest.config.*",
+ "cypress.config.*",
+ "nightwatch.conf.*",
+ "playwright.config.*"
+ ],
+ "compilerOptions": {
+ "composite": true,
+ "noEmit": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
+
+ "module": "ESNext",
+ "moduleResolution": "Bundler",
+ "types": ["node"]
+ }
+}
diff --git a/playground/typescript-router-vitest-nightwatch/tsconfig.vitest.json b/playground/typescript-router-vitest-nightwatch/tsconfig.vitest.json
new file mode 100644
index 000000000..571995d11
--- /dev/null
+++ b/playground/typescript-router-vitest-nightwatch/tsconfig.vitest.json
@@ -0,0 +1,11 @@
+{
+ "extends": "./tsconfig.app.json",
+ "exclude": [],
+ "compilerOptions": {
+ "composite": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.vitest.tsbuildinfo",
+
+ "lib": [],
+ "types": ["node", "jsdom"]
+ }
+}
diff --git a/playground/typescript-router-vitest-nightwatch/vite.config.ts b/playground/typescript-router-vitest-nightwatch/vite.config.ts
new file mode 100644
index 000000000..be3cb9c57
--- /dev/null
+++ b/playground/typescript-router-vitest-nightwatch/vite.config.ts
@@ -0,0 +1,18 @@
+import { fileURLToPath, URL } from 'node:url'
+
+import { defineConfig } from 'vite'
+import vue from '@vitejs/plugin-vue'
+import nightwatchPlugin from 'vite-plugin-nightwatch'
+
+// https://vitejs.dev/config/
+export default defineConfig({
+ plugins: [
+ vue(),
+ nightwatchPlugin(),
+ ],
+ resolve: {
+ alias: {
+ '@': fileURLToPath(new URL('./src', import.meta.url))
+ }
+ }
+})
diff --git a/playground/typescript-router-vitest-nightwatch/vitest.config.ts b/playground/typescript-router-vitest-nightwatch/vitest.config.ts
new file mode 100644
index 000000000..10067d578
--- /dev/null
+++ b/playground/typescript-router-vitest-nightwatch/vitest.config.ts
@@ -0,0 +1,14 @@
+import { fileURLToPath } from 'node:url'
+import { mergeConfig, defineConfig, configDefaults } from 'vitest/config'
+import viteConfig from './vite.config'
+
+export default mergeConfig(
+ viteConfig,
+ defineConfig({
+ test: {
+ environment: 'jsdom',
+ exclude: [...configDefaults.exclude, 'e2e/*'],
+ root: fileURLToPath(new URL('./', import.meta.url))
+ }
+ })
+)
diff --git a/playground/typescript-router-vitest-playwright/.gitignore b/playground/typescript-router-vitest-playwright/.gitignore
new file mode 100644
index 000000000..aef72d03c
--- /dev/null
+++ b/playground/typescript-router-vitest-playwright/.gitignore
@@ -0,0 +1,33 @@
+# 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/
+
+# Editor directories and files
+.vscode/*
+!.vscode/extensions.json
+.idea
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?
+
+*.tsbuildinfo
+
+test-results/
+playwright-report/
diff --git a/playground/typescript-router-vitest-playwright/.vscode/extensions.json b/playground/typescript-router-vitest-playwright/.vscode/extensions.json
new file mode 100644
index 000000000..7b3f8bdae
--- /dev/null
+++ b/playground/typescript-router-vitest-playwright/.vscode/extensions.json
@@ -0,0 +1,3 @@
+{
+ "recommendations": ["ms-playwright.playwright"]
+}
diff --git a/playground/typescript-router-vitest-playwright/README.md b/playground/typescript-router-vitest-playwright/README.md
new file mode 100644
index 000000000..ab27a98ef
--- /dev/null
+++ b/playground/typescript-router-vitest-playwright/README.md
@@ -0,0 +1,65 @@
+# typescript-router-vitest-playwright
+
+This template should help get you started developing with Vue 3 in Vite.
+
+## Recommended IDE Setup
+
+[VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur) + [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin).
+
+## Type Support for `.vue` Imports in TS
+
+TypeScript cannot handle type information for `.vue` imports by default, so we replace the `tsc` CLI with `vue-tsc` for type checking. In editors, we need [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin) to make the TypeScript language service aware of `.vue` types.
+
+If the standalone TypeScript plugin doesn't feel fast enough to you, Volar has also implemented a [Take Over Mode](https://github.com/johnsoncodehk/volar/discussions/471#discussioncomment-1361669) that is more performant. You can enable it by the following steps:
+
+1. Disable the built-in TypeScript Extension
+ 1) Run `Extensions: Show Built-in Extensions` from VSCode's command palette
+ 2) Find `TypeScript and JavaScript Language Features`, right click and select `Disable (Workspace)`
+2. Reload the VSCode window by running `Developer: Reload Window` from the command palette.
+
+## Customize configuration
+
+See [Vite Configuration Reference](https://vitejs.dev/config/).
+
+## Project Setup
+
+```sh
+pnpm install
+```
+
+### Compile and Hot-Reload for Development
+
+```sh
+pnpm dev
+```
+
+### Type-Check, Compile and Minify for Production
+
+```sh
+pnpm build
+```
+
+### Run Unit Tests with [Vitest](https://vitest.dev/)
+
+```sh
+pnpm test:unit
+```
+
+### Run End-to-End Tests with [Playwright](https://playwright.dev)
+
+```sh
+# Install browsers for the first run
+npx playwright install
+
+# When testing on CI, must build the project first
+pnpm build
+
+# Runs the end-to-end tests
+pnpm test:e2e
+# Runs the tests only on Chromium
+pnpm test:e2e --project=chromium
+# Runs the tests of a specific file
+pnpm test:e2e tests/example.spec.ts
+# Runs the tests in debug mode
+pnpm test:e2e --debug
+```
diff --git a/playground/typescript-router-vitest-playwright/e2e/tsconfig.json b/playground/typescript-router-vitest-playwright/e2e/tsconfig.json
new file mode 100644
index 000000000..be3bbfc0e
--- /dev/null
+++ b/playground/typescript-router-vitest-playwright/e2e/tsconfig.json
@@ -0,0 +1,4 @@
+{
+ "extends": "@tsconfig/node20/tsconfig.json",
+ "include": ["./**/*"]
+}
diff --git a/playground/typescript-router-vitest-playwright/e2e/vue.spec.ts b/playground/typescript-router-vitest-playwright/e2e/vue.spec.ts
new file mode 100644
index 000000000..3e5a3d02d
--- /dev/null
+++ b/playground/typescript-router-vitest-playwright/e2e/vue.spec.ts
@@ -0,0 +1,8 @@
+import { test, expect } from '@playwright/test';
+
+// See here how to get started:
+// https://playwright.dev/docs/intro
+test('visits the app root url', async ({ page }) => {
+ await page.goto('/');
+ await expect(page.locator('div.greetings > h1')).toHaveText('You did it!');
+})
diff --git a/playground/typescript-router-vitest-playwright/env.d.ts b/playground/typescript-router-vitest-playwright/env.d.ts
new file mode 100644
index 000000000..11f02fe2a
--- /dev/null
+++ b/playground/typescript-router-vitest-playwright/env.d.ts
@@ -0,0 +1 @@
+///
diff --git a/playground/typescript-router-vitest-playwright/index.html b/playground/typescript-router-vitest-playwright/index.html
new file mode 100644
index 000000000..a88854489
--- /dev/null
+++ b/playground/typescript-router-vitest-playwright/index.html
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+ Vite App
+
+
+
+
+
+
diff --git a/playground/typescript-router-vitest-playwright/package.json b/playground/typescript-router-vitest-playwright/package.json
new file mode 100644
index 000000000..d331ae45e
--- /dev/null
+++ b/playground/typescript-router-vitest-playwright/package.json
@@ -0,0 +1,34 @@
+{
+ "name": "typescript-router-vitest-playwright",
+ "version": "0.0.0",
+ "private": true,
+ "type": "module",
+ "scripts": {
+ "dev": "vite",
+ "build": "run-p type-check \"build-only {@}\" --",
+ "preview": "vite preview",
+ "test:unit": "vitest",
+ "test:e2e": "playwright test",
+ "build-only": "vite build",
+ "type-check": "vue-tsc --build --force"
+ },
+ "dependencies": {
+ "vue": "^3.4.15",
+ "vue-router": "^4.2.5"
+ },
+ "devDependencies": {
+ "@playwright/test": "^1.41.2",
+ "@tsconfig/node20": "^20.1.2",
+ "@types/jsdom": "^21.1.6",
+ "@types/node": "^20.11.16",
+ "@vitejs/plugin-vue": "^5.0.3",
+ "@vue/test-utils": "^2.4.4",
+ "@vue/tsconfig": "^0.5.1",
+ "jsdom": "^24.0.0",
+ "npm-run-all2": "^6.1.2",
+ "typescript": "~5.3.0",
+ "vite": "^5.0.11",
+ "vitest": "^1.2.2",
+ "vue-tsc": "^1.8.27"
+ }
+}
diff --git a/playground/typescript-router-vitest-playwright/playwright.config.ts b/playground/typescript-router-vitest-playwright/playwright.config.ts
new file mode 100644
index 000000000..92075cc1b
--- /dev/null
+++ b/playground/typescript-router-vitest-playwright/playwright.config.ts
@@ -0,0 +1,110 @@
+import process from 'node:process'
+import { defineConfig, devices } from '@playwright/test'
+
+/**
+ * Read environment variables from file.
+ * https://github.com/motdotla/dotenv
+ */
+// require('dotenv').config();
+
+/**
+ * See https://playwright.dev/docs/test-configuration.
+ */
+export default defineConfig({
+ testDir: './e2e',
+ /* Maximum time one test can run for. */
+ timeout: 30 * 1000,
+ expect: {
+ /**
+ * Maximum time expect() should wait for the condition to be met.
+ * For example in `await expect(locator).toHaveText();`
+ */
+ timeout: 5000
+ },
+ /* Fail the build on CI if you accidentally left test.only in the source code. */
+ forbidOnly: !!process.env.CI,
+ /* Retry on CI only */
+ retries: process.env.CI ? 2 : 0,
+ /* Opt out of parallel tests on CI. */
+ workers: process.env.CI ? 1 : undefined,
+ /* Reporter to use. See https://playwright.dev/docs/test-reporters */
+ reporter: 'html',
+ /* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
+ use: {
+ /* Maximum time each action such as `click()` can take. Defaults to 0 (no limit). */
+ actionTimeout: 0,
+ /* Base URL to use in actions like `await page.goto('/')`. */
+ baseURL: 'http://localhost:5173',
+
+ /* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
+ trace: 'on-first-retry',
+
+ /* Only on CI systems run the tests headless */
+ headless: !!process.env.CI
+ },
+
+ /* Configure projects for major browsers */
+ projects: [
+ {
+ name: 'chromium',
+ use: {
+ ...devices['Desktop Chrome']
+ }
+ },
+ {
+ name: 'firefox',
+ use: {
+ ...devices['Desktop Firefox']
+ }
+ },
+ {
+ name: 'webkit',
+ use: {
+ ...devices['Desktop Safari']
+ }
+ }
+
+ /* Test against mobile viewports. */
+ // {
+ // name: 'Mobile Chrome',
+ // use: {
+ // ...devices['Pixel 5'],
+ // },
+ // },
+ // {
+ // name: 'Mobile Safari',
+ // use: {
+ // ...devices['iPhone 12'],
+ // },
+ // },
+
+ /* Test against branded browsers. */
+ // {
+ // name: 'Microsoft Edge',
+ // use: {
+ // channel: 'msedge',
+ // },
+ // },
+ // {
+ // name: 'Google Chrome',
+ // use: {
+ // channel: 'chrome',
+ // },
+ // },
+ ],
+
+ /* Folder for test artifacts such as screenshots, videos, traces, etc. */
+ // outputDir: 'test-results/',
+
+ /* Run your local dev server before starting the tests */
+ webServer: {
+ /**
+ * Use the dev server by default for faster feedback loop.
+ * Use the preview server on CI for more realistic testing.
+ * Playwright will re-use the local server if there is already a dev-server running.
+ */
+ command: process.env.CI ? 'vite preview --port 5173' : 'vite dev',
+ port: 5173,
+ reuseExistingServer: !process.env.CI
+ }
+})
diff --git a/playground/typescript-router-vitest-playwright/public/favicon.ico b/playground/typescript-router-vitest-playwright/public/favicon.ico
new file mode 100644
index 000000000..df36fcfb7
Binary files /dev/null and b/playground/typescript-router-vitest-playwright/public/favicon.ico differ
diff --git a/playground/typescript-router-vitest-playwright/src/App.vue b/playground/typescript-router-vitest-playwright/src/App.vue
new file mode 100644
index 000000000..7905b0516
--- /dev/null
+++ b/playground/typescript-router-vitest-playwright/src/App.vue
@@ -0,0 +1,85 @@
+
+
+
+
+
+
+
+ You’ve successfully created a project with
+ Vite +
+ Vue 3. What's next?
+
+
+
+
+
diff --git a/playground/typescript-router-vitest-playwright/src/components/TheWelcome.vue b/playground/typescript-router-vitest-playwright/src/components/TheWelcome.vue
new file mode 100644
index 000000000..49d8f7354
--- /dev/null
+++ b/playground/typescript-router-vitest-playwright/src/components/TheWelcome.vue
@@ -0,0 +1,88 @@
+
+
+
+
+
+
+
+ Documentation
+
+ Vue’s
+ official documentation
+ provides you with all information you need to get started.
+
+
+
+
+
+
+ Tooling
+
+ This project is served and bundled with
+ Vite. The
+ recommended IDE setup is
+ VSCode +
+ Volar. If
+ you need to test your components and web pages, check out
+ Cypress and
+ Cypress Component Testing.
+
+
+
+ More instructions are available in README.md.
+
+
+
+
+
+
+ Ecosystem
+
+ Get official tools and libraries for your project:
+ Pinia,
+ Vue Router,
+ Vue Test Utils, and
+ Vue Dev Tools. If
+ you need more resources, we suggest paying
+ Awesome Vue
+ a visit.
+
+
+
+
+
+
+ Community
+
+ Got stuck? Ask your question on
+ Vue Land, our official
+ Discord server, or
+ StackOverflow. You should also subscribe to
+ our mailing list and follow
+ the official
+ @vuejs
+ twitter account for latest news in the Vue world.
+
+
+
+
+
+
+ Support Vue
+
+ As an independent project, Vue relies on community backing for its sustainability. You can help
+ us by
+ becoming a sponsor.
+
+
diff --git a/playground/typescript-router-vitest-playwright/src/components/WelcomeItem.vue b/playground/typescript-router-vitest-playwright/src/components/WelcomeItem.vue
new file mode 100644
index 000000000..6d7086aea
--- /dev/null
+++ b/playground/typescript-router-vitest-playwright/src/components/WelcomeItem.vue
@@ -0,0 +1,87 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/playground/typescript-router-vitest-playwright/src/components/__tests__/HelloWorld.spec.ts b/playground/typescript-router-vitest-playwright/src/components/__tests__/HelloWorld.spec.ts
new file mode 100644
index 000000000..253320200
--- /dev/null
+++ b/playground/typescript-router-vitest-playwright/src/components/__tests__/HelloWorld.spec.ts
@@ -0,0 +1,11 @@
+import { describe, it, expect } from 'vitest'
+
+import { mount } from '@vue/test-utils'
+import HelloWorld from '../HelloWorld.vue'
+
+describe('HelloWorld', () => {
+ it('renders properly', () => {
+ const wrapper = mount(HelloWorld, { props: { msg: 'Hello Vitest' } })
+ expect(wrapper.text()).toContain('Hello Vitest')
+ })
+})
diff --git a/playground/typescript-router-vitest-playwright/src/components/icons/IconCommunity.vue b/playground/typescript-router-vitest-playwright/src/components/icons/IconCommunity.vue
new file mode 100644
index 000000000..2dc8b0552
--- /dev/null
+++ b/playground/typescript-router-vitest-playwright/src/components/icons/IconCommunity.vue
@@ -0,0 +1,7 @@
+
+
+
diff --git a/playground/typescript-router-vitest-playwright/src/components/icons/IconDocumentation.vue b/playground/typescript-router-vitest-playwright/src/components/icons/IconDocumentation.vue
new file mode 100644
index 000000000..6d4791cfb
--- /dev/null
+++ b/playground/typescript-router-vitest-playwright/src/components/icons/IconDocumentation.vue
@@ -0,0 +1,7 @@
+
+
+
diff --git a/playground/typescript-router-vitest-playwright/src/components/icons/IconEcosystem.vue b/playground/typescript-router-vitest-playwright/src/components/icons/IconEcosystem.vue
new file mode 100644
index 000000000..c3a4f078c
--- /dev/null
+++ b/playground/typescript-router-vitest-playwright/src/components/icons/IconEcosystem.vue
@@ -0,0 +1,7 @@
+
+
+
diff --git a/playground/typescript-router-vitest-playwright/src/components/icons/IconSupport.vue b/playground/typescript-router-vitest-playwright/src/components/icons/IconSupport.vue
new file mode 100644
index 000000000..7452834d3
--- /dev/null
+++ b/playground/typescript-router-vitest-playwright/src/components/icons/IconSupport.vue
@@ -0,0 +1,7 @@
+
+
+
diff --git a/playground/typescript-router-vitest-playwright/src/components/icons/IconTooling.vue b/playground/typescript-router-vitest-playwright/src/components/icons/IconTooling.vue
new file mode 100644
index 000000000..660598d7c
--- /dev/null
+++ b/playground/typescript-router-vitest-playwright/src/components/icons/IconTooling.vue
@@ -0,0 +1,19 @@
+
+
+
+
diff --git a/playground/typescript-router-vitest-playwright/src/main.ts b/playground/typescript-router-vitest-playwright/src/main.ts
new file mode 100644
index 000000000..5a5dbdba7
--- /dev/null
+++ b/playground/typescript-router-vitest-playwright/src/main.ts
@@ -0,0 +1,11 @@
+import './assets/main.css'
+
+import { createApp } from 'vue'
+import App from './App.vue'
+import router from './router'
+
+const app = createApp(App)
+
+app.use(router)
+
+app.mount('#app')
diff --git a/playground/typescript-router-vitest-playwright/src/router/index.ts b/playground/typescript-router-vitest-playwright/src/router/index.ts
new file mode 100644
index 000000000..a49ae507f
--- /dev/null
+++ b/playground/typescript-router-vitest-playwright/src/router/index.ts
@@ -0,0 +1,23 @@
+import { createRouter, createWebHistory } from 'vue-router'
+import HomeView from '../views/HomeView.vue'
+
+const router = createRouter({
+ history: createWebHistory(import.meta.env.BASE_URL),
+ routes: [
+ {
+ path: '/',
+ name: 'home',
+ component: HomeView
+ },
+ {
+ path: '/about',
+ name: 'about',
+ // route level code-splitting
+ // this generates a separate chunk (About.[hash].js) for this route
+ // which is lazy-loaded when the route is visited.
+ component: () => import('../views/AboutView.vue')
+ }
+ ]
+})
+
+export default router
diff --git a/playground/typescript-router-vitest-playwright/src/views/AboutView.vue b/playground/typescript-router-vitest-playwright/src/views/AboutView.vue
new file mode 100644
index 000000000..756ad2a17
--- /dev/null
+++ b/playground/typescript-router-vitest-playwright/src/views/AboutView.vue
@@ -0,0 +1,15 @@
+
+
+
This is an about page
+
+
+
+
diff --git a/playground/typescript-router-vitest-playwright/src/views/HomeView.vue b/playground/typescript-router-vitest-playwright/src/views/HomeView.vue
new file mode 100644
index 000000000..d5c0217e4
--- /dev/null
+++ b/playground/typescript-router-vitest-playwright/src/views/HomeView.vue
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
diff --git a/playground/typescript-router-vitest-playwright/tsconfig.app.json b/playground/typescript-router-vitest-playwright/tsconfig.app.json
new file mode 100644
index 000000000..e14c754d3
--- /dev/null
+++ b/playground/typescript-router-vitest-playwright/tsconfig.app.json
@@ -0,0 +1,14 @@
+{
+ "extends": "@vue/tsconfig/tsconfig.dom.json",
+ "include": ["env.d.ts", "src/**/*", "src/**/*.vue"],
+ "exclude": ["src/**/__tests__/*"],
+ "compilerOptions": {
+ "composite": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
+
+ "baseUrl": ".",
+ "paths": {
+ "@/*": ["./src/*"]
+ }
+ }
+}
diff --git a/playground/typescript-router-vitest-playwright/tsconfig.json b/playground/typescript-router-vitest-playwright/tsconfig.json
new file mode 100644
index 000000000..100cf6a8f
--- /dev/null
+++ b/playground/typescript-router-vitest-playwright/tsconfig.json
@@ -0,0 +1,14 @@
+{
+ "files": [],
+ "references": [
+ {
+ "path": "./tsconfig.node.json"
+ },
+ {
+ "path": "./tsconfig.app.json"
+ },
+ {
+ "path": "./tsconfig.vitest.json"
+ }
+ ]
+}
diff --git a/playground/typescript-router-vitest-playwright/tsconfig.node.json b/playground/typescript-router-vitest-playwright/tsconfig.node.json
new file mode 100644
index 000000000..f09406303
--- /dev/null
+++ b/playground/typescript-router-vitest-playwright/tsconfig.node.json
@@ -0,0 +1,19 @@
+{
+ "extends": "@tsconfig/node20/tsconfig.json",
+ "include": [
+ "vite.config.*",
+ "vitest.config.*",
+ "cypress.config.*",
+ "nightwatch.conf.*",
+ "playwright.config.*"
+ ],
+ "compilerOptions": {
+ "composite": true,
+ "noEmit": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
+
+ "module": "ESNext",
+ "moduleResolution": "Bundler",
+ "types": ["node"]
+ }
+}
diff --git a/playground/typescript-router-vitest-playwright/tsconfig.vitest.json b/playground/typescript-router-vitest-playwright/tsconfig.vitest.json
new file mode 100644
index 000000000..571995d11
--- /dev/null
+++ b/playground/typescript-router-vitest-playwright/tsconfig.vitest.json
@@ -0,0 +1,11 @@
+{
+ "extends": "./tsconfig.app.json",
+ "exclude": [],
+ "compilerOptions": {
+ "composite": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.vitest.tsbuildinfo",
+
+ "lib": [],
+ "types": ["node", "jsdom"]
+ }
+}
diff --git a/playground/typescript-router-vitest-playwright/vite.config.ts b/playground/typescript-router-vitest-playwright/vite.config.ts
new file mode 100644
index 000000000..5c45e1d9b
--- /dev/null
+++ b/playground/typescript-router-vitest-playwright/vite.config.ts
@@ -0,0 +1,16 @@
+import { fileURLToPath, URL } from 'node:url'
+
+import { defineConfig } from 'vite'
+import vue from '@vitejs/plugin-vue'
+
+// https://vitejs.dev/config/
+export default defineConfig({
+ plugins: [
+ vue(),
+ ],
+ resolve: {
+ alias: {
+ '@': fileURLToPath(new URL('./src', import.meta.url))
+ }
+ }
+})
diff --git a/playground/typescript-router-vitest-playwright/vitest.config.ts b/playground/typescript-router-vitest-playwright/vitest.config.ts
new file mode 100644
index 000000000..10067d578
--- /dev/null
+++ b/playground/typescript-router-vitest-playwright/vitest.config.ts
@@ -0,0 +1,14 @@
+import { fileURLToPath } from 'node:url'
+import { mergeConfig, defineConfig, configDefaults } from 'vitest/config'
+import viteConfig from './vite.config'
+
+export default mergeConfig(
+ viteConfig,
+ defineConfig({
+ test: {
+ environment: 'jsdom',
+ exclude: [...configDefaults.exclude, 'e2e/*'],
+ root: fileURLToPath(new URL('./', import.meta.url))
+ }
+ })
+)
diff --git a/playground/typescript-router-vitest/.gitignore b/playground/typescript-router-vitest/.gitignore
new file mode 100644
index 000000000..8ee54e8d3
--- /dev/null
+++ b/playground/typescript-router-vitest/.gitignore
@@ -0,0 +1,30 @@
+# 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/
+
+# Editor directories and files
+.vscode/*
+!.vscode/extensions.json
+.idea
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?
+
+*.tsbuildinfo
diff --git a/playground/typescript-router-vitest/README.md b/playground/typescript-router-vitest/README.md
new file mode 100644
index 000000000..730ad8fc1
--- /dev/null
+++ b/playground/typescript-router-vitest/README.md
@@ -0,0 +1,46 @@
+# typescript-router-vitest
+
+This template should help get you started developing with Vue 3 in Vite.
+
+## Recommended IDE Setup
+
+[VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur) + [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin).
+
+## Type Support for `.vue` Imports in TS
+
+TypeScript cannot handle type information for `.vue` imports by default, so we replace the `tsc` CLI with `vue-tsc` for type checking. In editors, we need [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin) to make the TypeScript language service aware of `.vue` types.
+
+If the standalone TypeScript plugin doesn't feel fast enough to you, Volar has also implemented a [Take Over Mode](https://github.com/johnsoncodehk/volar/discussions/471#discussioncomment-1361669) that is more performant. You can enable it by the following steps:
+
+1. Disable the built-in TypeScript Extension
+ 1) Run `Extensions: Show Built-in Extensions` from VSCode's command palette
+ 2) Find `TypeScript and JavaScript Language Features`, right click and select `Disable (Workspace)`
+2. Reload the VSCode window by running `Developer: Reload Window` from the command palette.
+
+## Customize configuration
+
+See [Vite Configuration Reference](https://vitejs.dev/config/).
+
+## Project Setup
+
+```sh
+pnpm install
+```
+
+### Compile and Hot-Reload for Development
+
+```sh
+pnpm dev
+```
+
+### Type-Check, Compile and Minify for Production
+
+```sh
+pnpm build
+```
+
+### Run Unit Tests with [Vitest](https://vitest.dev/)
+
+```sh
+pnpm test:unit
+```
diff --git a/playground/typescript-router-vitest/env.d.ts b/playground/typescript-router-vitest/env.d.ts
new file mode 100644
index 000000000..11f02fe2a
--- /dev/null
+++ b/playground/typescript-router-vitest/env.d.ts
@@ -0,0 +1 @@
+///
diff --git a/playground/typescript-router-vitest/index.html b/playground/typescript-router-vitest/index.html
new file mode 100644
index 000000000..a88854489
--- /dev/null
+++ b/playground/typescript-router-vitest/index.html
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+ Vite App
+
+
+
+
+
+
diff --git a/playground/typescript-router-vitest/package.json b/playground/typescript-router-vitest/package.json
new file mode 100644
index 000000000..78a6ba8d6
--- /dev/null
+++ b/playground/typescript-router-vitest/package.json
@@ -0,0 +1,32 @@
+{
+ "name": "typescript-router-vitest",
+ "version": "0.0.0",
+ "private": true,
+ "type": "module",
+ "scripts": {
+ "dev": "vite",
+ "build": "run-p type-check \"build-only {@}\" --",
+ "preview": "vite preview",
+ "test:unit": "vitest",
+ "build-only": "vite build",
+ "type-check": "vue-tsc --build --force"
+ },
+ "dependencies": {
+ "vue": "^3.4.15",
+ "vue-router": "^4.2.5"
+ },
+ "devDependencies": {
+ "@tsconfig/node20": "^20.1.2",
+ "@types/jsdom": "^21.1.6",
+ "@types/node": "^20.11.16",
+ "@vitejs/plugin-vue": "^5.0.3",
+ "@vue/test-utils": "^2.4.4",
+ "@vue/tsconfig": "^0.5.1",
+ "jsdom": "^24.0.0",
+ "npm-run-all2": "^6.1.2",
+ "typescript": "~5.3.0",
+ "vite": "^5.0.11",
+ "vitest": "^1.2.2",
+ "vue-tsc": "^1.8.27"
+ }
+}
diff --git a/playground/typescript-router-vitest/public/favicon.ico b/playground/typescript-router-vitest/public/favicon.ico
new file mode 100644
index 000000000..df36fcfb7
Binary files /dev/null and b/playground/typescript-router-vitest/public/favicon.ico differ
diff --git a/playground/typescript-router-vitest/src/App.vue b/playground/typescript-router-vitest/src/App.vue
new file mode 100644
index 000000000..7905b0516
--- /dev/null
+++ b/playground/typescript-router-vitest/src/App.vue
@@ -0,0 +1,85 @@
+
+
+
+
+
+
+
+ You’ve successfully created a project with
+ Vite +
+ Vue 3. What's next?
+
+
+
+
+
diff --git a/playground/typescript-router-vitest/src/components/TheWelcome.vue b/playground/typescript-router-vitest/src/components/TheWelcome.vue
new file mode 100644
index 000000000..49d8f7354
--- /dev/null
+++ b/playground/typescript-router-vitest/src/components/TheWelcome.vue
@@ -0,0 +1,88 @@
+
+
+
+
+
+
+
+ Documentation
+
+ Vue’s
+ official documentation
+ provides you with all information you need to get started.
+
+
+
+
+
+
+ Tooling
+
+ This project is served and bundled with
+ Vite. The
+ recommended IDE setup is
+ VSCode +
+ Volar. If
+ you need to test your components and web pages, check out
+ Cypress and
+ Cypress Component Testing.
+
+
+
+ More instructions are available in README.md.
+
+
+
+
+
+
+ Ecosystem
+
+ Get official tools and libraries for your project:
+ Pinia,
+ Vue Router,
+ Vue Test Utils, and
+ Vue Dev Tools. If
+ you need more resources, we suggest paying
+ Awesome Vue
+ a visit.
+
+
+
+
+
+
+ Community
+
+ Got stuck? Ask your question on
+ Vue Land, our official
+ Discord server, or
+ StackOverflow. You should also subscribe to
+ our mailing list and follow
+ the official
+ @vuejs
+ twitter account for latest news in the Vue world.
+
+
+
+
+
+
+ Support Vue
+
+ As an independent project, Vue relies on community backing for its sustainability. You can help
+ us by
+ becoming a sponsor.
+
+
diff --git a/playground/typescript-router-vitest/src/components/WelcomeItem.vue b/playground/typescript-router-vitest/src/components/WelcomeItem.vue
new file mode 100644
index 000000000..6d7086aea
--- /dev/null
+++ b/playground/typescript-router-vitest/src/components/WelcomeItem.vue
@@ -0,0 +1,87 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/playground/typescript-router-vitest/src/components/__tests__/HelloWorld.spec.ts b/playground/typescript-router-vitest/src/components/__tests__/HelloWorld.spec.ts
new file mode 100644
index 000000000..253320200
--- /dev/null
+++ b/playground/typescript-router-vitest/src/components/__tests__/HelloWorld.spec.ts
@@ -0,0 +1,11 @@
+import { describe, it, expect } from 'vitest'
+
+import { mount } from '@vue/test-utils'
+import HelloWorld from '../HelloWorld.vue'
+
+describe('HelloWorld', () => {
+ it('renders properly', () => {
+ const wrapper = mount(HelloWorld, { props: { msg: 'Hello Vitest' } })
+ expect(wrapper.text()).toContain('Hello Vitest')
+ })
+})
diff --git a/playground/typescript-router-vitest/src/components/icons/IconCommunity.vue b/playground/typescript-router-vitest/src/components/icons/IconCommunity.vue
new file mode 100644
index 000000000..2dc8b0552
--- /dev/null
+++ b/playground/typescript-router-vitest/src/components/icons/IconCommunity.vue
@@ -0,0 +1,7 @@
+
+
+
diff --git a/playground/typescript-router-vitest/src/components/icons/IconDocumentation.vue b/playground/typescript-router-vitest/src/components/icons/IconDocumentation.vue
new file mode 100644
index 000000000..6d4791cfb
--- /dev/null
+++ b/playground/typescript-router-vitest/src/components/icons/IconDocumentation.vue
@@ -0,0 +1,7 @@
+
+
+
diff --git a/playground/typescript-router-vitest/src/components/icons/IconEcosystem.vue b/playground/typescript-router-vitest/src/components/icons/IconEcosystem.vue
new file mode 100644
index 000000000..c3a4f078c
--- /dev/null
+++ b/playground/typescript-router-vitest/src/components/icons/IconEcosystem.vue
@@ -0,0 +1,7 @@
+
+
+
diff --git a/playground/typescript-router-vitest/src/components/icons/IconSupport.vue b/playground/typescript-router-vitest/src/components/icons/IconSupport.vue
new file mode 100644
index 000000000..7452834d3
--- /dev/null
+++ b/playground/typescript-router-vitest/src/components/icons/IconSupport.vue
@@ -0,0 +1,7 @@
+
+
+
diff --git a/playground/typescript-router-vitest/src/components/icons/IconTooling.vue b/playground/typescript-router-vitest/src/components/icons/IconTooling.vue
new file mode 100644
index 000000000..660598d7c
--- /dev/null
+++ b/playground/typescript-router-vitest/src/components/icons/IconTooling.vue
@@ -0,0 +1,19 @@
+
+
+
+
diff --git a/playground/typescript-router-vitest/src/main.ts b/playground/typescript-router-vitest/src/main.ts
new file mode 100644
index 000000000..5a5dbdba7
--- /dev/null
+++ b/playground/typescript-router-vitest/src/main.ts
@@ -0,0 +1,11 @@
+import './assets/main.css'
+
+import { createApp } from 'vue'
+import App from './App.vue'
+import router from './router'
+
+const app = createApp(App)
+
+app.use(router)
+
+app.mount('#app')
diff --git a/playground/typescript-router-vitest/src/router/index.ts b/playground/typescript-router-vitest/src/router/index.ts
new file mode 100644
index 000000000..a49ae507f
--- /dev/null
+++ b/playground/typescript-router-vitest/src/router/index.ts
@@ -0,0 +1,23 @@
+import { createRouter, createWebHistory } from 'vue-router'
+import HomeView from '../views/HomeView.vue'
+
+const router = createRouter({
+ history: createWebHistory(import.meta.env.BASE_URL),
+ routes: [
+ {
+ path: '/',
+ name: 'home',
+ component: HomeView
+ },
+ {
+ path: '/about',
+ name: 'about',
+ // route level code-splitting
+ // this generates a separate chunk (About.[hash].js) for this route
+ // which is lazy-loaded when the route is visited.
+ component: () => import('../views/AboutView.vue')
+ }
+ ]
+})
+
+export default router
diff --git a/playground/typescript-router-vitest/src/views/AboutView.vue b/playground/typescript-router-vitest/src/views/AboutView.vue
new file mode 100644
index 000000000..756ad2a17
--- /dev/null
+++ b/playground/typescript-router-vitest/src/views/AboutView.vue
@@ -0,0 +1,15 @@
+
+
+
This is an about page
+
+
+
+
diff --git a/playground/typescript-router-vitest/src/views/HomeView.vue b/playground/typescript-router-vitest/src/views/HomeView.vue
new file mode 100644
index 000000000..d5c0217e4
--- /dev/null
+++ b/playground/typescript-router-vitest/src/views/HomeView.vue
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
diff --git a/playground/typescript-router-vitest/tsconfig.app.json b/playground/typescript-router-vitest/tsconfig.app.json
new file mode 100644
index 000000000..e14c754d3
--- /dev/null
+++ b/playground/typescript-router-vitest/tsconfig.app.json
@@ -0,0 +1,14 @@
+{
+ "extends": "@vue/tsconfig/tsconfig.dom.json",
+ "include": ["env.d.ts", "src/**/*", "src/**/*.vue"],
+ "exclude": ["src/**/__tests__/*"],
+ "compilerOptions": {
+ "composite": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
+
+ "baseUrl": ".",
+ "paths": {
+ "@/*": ["./src/*"]
+ }
+ }
+}
diff --git a/playground/typescript-router-vitest/tsconfig.json b/playground/typescript-router-vitest/tsconfig.json
new file mode 100644
index 000000000..100cf6a8f
--- /dev/null
+++ b/playground/typescript-router-vitest/tsconfig.json
@@ -0,0 +1,14 @@
+{
+ "files": [],
+ "references": [
+ {
+ "path": "./tsconfig.node.json"
+ },
+ {
+ "path": "./tsconfig.app.json"
+ },
+ {
+ "path": "./tsconfig.vitest.json"
+ }
+ ]
+}
diff --git a/playground/typescript-router-vitest/tsconfig.node.json b/playground/typescript-router-vitest/tsconfig.node.json
new file mode 100644
index 000000000..f09406303
--- /dev/null
+++ b/playground/typescript-router-vitest/tsconfig.node.json
@@ -0,0 +1,19 @@
+{
+ "extends": "@tsconfig/node20/tsconfig.json",
+ "include": [
+ "vite.config.*",
+ "vitest.config.*",
+ "cypress.config.*",
+ "nightwatch.conf.*",
+ "playwright.config.*"
+ ],
+ "compilerOptions": {
+ "composite": true,
+ "noEmit": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
+
+ "module": "ESNext",
+ "moduleResolution": "Bundler",
+ "types": ["node"]
+ }
+}
diff --git a/playground/typescript-router-vitest/tsconfig.vitest.json b/playground/typescript-router-vitest/tsconfig.vitest.json
new file mode 100644
index 000000000..571995d11
--- /dev/null
+++ b/playground/typescript-router-vitest/tsconfig.vitest.json
@@ -0,0 +1,11 @@
+{
+ "extends": "./tsconfig.app.json",
+ "exclude": [],
+ "compilerOptions": {
+ "composite": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.vitest.tsbuildinfo",
+
+ "lib": [],
+ "types": ["node", "jsdom"]
+ }
+}
diff --git a/playground/typescript-router-vitest/vite.config.ts b/playground/typescript-router-vitest/vite.config.ts
new file mode 100644
index 000000000..5c45e1d9b
--- /dev/null
+++ b/playground/typescript-router-vitest/vite.config.ts
@@ -0,0 +1,16 @@
+import { fileURLToPath, URL } from 'node:url'
+
+import { defineConfig } from 'vite'
+import vue from '@vitejs/plugin-vue'
+
+// https://vitejs.dev/config/
+export default defineConfig({
+ plugins: [
+ vue(),
+ ],
+ resolve: {
+ alias: {
+ '@': fileURLToPath(new URL('./src', import.meta.url))
+ }
+ }
+})
diff --git a/playground/typescript-router-vitest/vitest.config.ts b/playground/typescript-router-vitest/vitest.config.ts
new file mode 100644
index 000000000..10067d578
--- /dev/null
+++ b/playground/typescript-router-vitest/vitest.config.ts
@@ -0,0 +1,14 @@
+import { fileURLToPath } from 'node:url'
+import { mergeConfig, defineConfig, configDefaults } from 'vitest/config'
+import viteConfig from './vite.config'
+
+export default mergeConfig(
+ viteConfig,
+ defineConfig({
+ test: {
+ environment: 'jsdom',
+ exclude: [...configDefaults.exclude, 'e2e/*'],
+ root: fileURLToPath(new URL('./', import.meta.url))
+ }
+ })
+)
diff --git a/playground/typescript-router-with-tests/.gitignore b/playground/typescript-router-with-tests/.gitignore
new file mode 100644
index 000000000..8ee54e8d3
--- /dev/null
+++ b/playground/typescript-router-with-tests/.gitignore
@@ -0,0 +1,30 @@
+# 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/
+
+# Editor directories and files
+.vscode/*
+!.vscode/extensions.json
+.idea
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?
+
+*.tsbuildinfo
diff --git a/playground/typescript-router-with-tests/README.md b/playground/typescript-router-with-tests/README.md
new file mode 100644
index 000000000..4b1d6d9db
--- /dev/null
+++ b/playground/typescript-router-with-tests/README.md
@@ -0,0 +1,62 @@
+# typescript-router-with-tests
+
+This template should help get you started developing with Vue 3 in Vite.
+
+## Recommended IDE Setup
+
+[VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur) + [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin).
+
+## Type Support for `.vue` Imports in TS
+
+TypeScript cannot handle type information for `.vue` imports by default, so we replace the `tsc` CLI with `vue-tsc` for type checking. In editors, we need [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin) to make the TypeScript language service aware of `.vue` types.
+
+If the standalone TypeScript plugin doesn't feel fast enough to you, Volar has also implemented a [Take Over Mode](https://github.com/johnsoncodehk/volar/discussions/471#discussioncomment-1361669) that is more performant. You can enable it by the following steps:
+
+1. Disable the built-in TypeScript Extension
+ 1) Run `Extensions: Show Built-in Extensions` from VSCode's command palette
+ 2) Find `TypeScript and JavaScript Language Features`, right click and select `Disable (Workspace)`
+2. Reload the VSCode window by running `Developer: Reload Window` from the command palette.
+
+## Customize configuration
+
+See [Vite Configuration Reference](https://vitejs.dev/config/).
+
+## Project Setup
+
+```sh
+pnpm install
+```
+
+### Compile and Hot-Reload for Development
+
+```sh
+pnpm dev
+```
+
+### Type-Check, Compile and Minify for Production
+
+```sh
+pnpm build
+```
+
+### Run Unit Tests with [Vitest](https://vitest.dev/)
+
+```sh
+pnpm test:unit
+```
+
+### Run End-to-End Tests with [Cypress](https://www.cypress.io/)
+
+```sh
+pnpm test:e2e:dev
+```
+
+This runs the end-to-end tests against the Vite development server.
+It is much faster than the production build.
+
+But it's still recommended to test the production build with `test:e2e` before deploying (e.g. in CI environments):
+
+```sh
+pnpm build
+pnpm test:e2e
+```
diff --git a/playground/typescript-router-with-tests/cypress.config.ts b/playground/typescript-router-with-tests/cypress.config.ts
new file mode 100644
index 000000000..0f66080fd
--- /dev/null
+++ b/playground/typescript-router-with-tests/cypress.config.ts
@@ -0,0 +1,8 @@
+import { defineConfig } from 'cypress'
+
+export default defineConfig({
+ e2e: {
+ specPattern: 'cypress/e2e/**/*.{cy,spec}.{js,jsx,ts,tsx}',
+ baseUrl: 'http://localhost:4173'
+ }
+})
diff --git a/playground/typescript-router-with-tests/cypress/e2e/example.cy.ts b/playground/typescript-router-with-tests/cypress/e2e/example.cy.ts
new file mode 100644
index 000000000..7554c35d8
--- /dev/null
+++ b/playground/typescript-router-with-tests/cypress/e2e/example.cy.ts
@@ -0,0 +1,8 @@
+// https://on.cypress.io/api
+
+describe('My First Test', () => {
+ it('visits the app root url', () => {
+ cy.visit('/')
+ cy.contains('h1', 'You did it!')
+ })
+})
diff --git a/playground/typescript-router-with-tests/cypress/e2e/tsconfig.json b/playground/typescript-router-with-tests/cypress/e2e/tsconfig.json
new file mode 100644
index 000000000..37748feb7
--- /dev/null
+++ b/playground/typescript-router-with-tests/cypress/e2e/tsconfig.json
@@ -0,0 +1,10 @@
+{
+ "extends": "@vue/tsconfig/tsconfig.dom.json",
+ "include": ["./**/*", "../support/**/*"],
+ "compilerOptions": {
+ "isolatedModules": false,
+ "target": "es5",
+ "lib": ["es5", "dom"],
+ "types": ["cypress"]
+ }
+}
diff --git a/playground/typescript-router-with-tests/cypress/fixtures/example.json b/playground/typescript-router-with-tests/cypress/fixtures/example.json
new file mode 100644
index 000000000..02e425437
--- /dev/null
+++ b/playground/typescript-router-with-tests/cypress/fixtures/example.json
@@ -0,0 +1,5 @@
+{
+ "name": "Using fixtures to represent data",
+ "email": "hello@cypress.io",
+ "body": "Fixtures are a great way to mock data for responses to routes"
+}
diff --git a/playground/typescript-router-with-tests/cypress/support/commands.ts b/playground/typescript-router-with-tests/cypress/support/commands.ts
new file mode 100644
index 000000000..9b7bb8e25
--- /dev/null
+++ b/playground/typescript-router-with-tests/cypress/support/commands.ts
@@ -0,0 +1,39 @@
+///
+// ***********************************************
+// This example commands.ts shows you how to
+// create various custom commands and overwrite
+// existing commands.
+//
+// For more comprehensive examples of custom
+// commands please read more here:
+// https://on.cypress.io/custom-commands
+// ***********************************************
+//
+//
+// -- This is a parent command --
+// Cypress.Commands.add('login', (email, password) => { ... })
+//
+//
+// -- This is a child command --
+// Cypress.Commands.add('drag', { prevSubject: 'element'}, (subject, options) => { ... })
+//
+//
+// -- This is a dual command --
+// Cypress.Commands.add('dismiss', { prevSubject: 'optional'}, (subject, options) => { ... })
+//
+//
+// -- This will overwrite an existing command --
+// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... })
+//
+// declare global {
+// namespace Cypress {
+// interface Chainable {
+// login(email: string, password: string): Chainable
+// drag(subject: string, options?: Partial): Chainable
+// dismiss(subject: string, options?: Partial): Chainable
+// visit(originalFn: CommandOriginalFn, url: string, options: Partial): Chainable
+// }
+// }
+// }
+
+export {}
diff --git a/playground/typescript-router-with-tests/cypress/support/e2e.ts b/playground/typescript-router-with-tests/cypress/support/e2e.ts
new file mode 100644
index 000000000..d68db96df
--- /dev/null
+++ b/playground/typescript-router-with-tests/cypress/support/e2e.ts
@@ -0,0 +1,20 @@
+// ***********************************************************
+// This example support/index.js is processed and
+// loaded automatically before your test files.
+//
+// This is a great place to put global configuration and
+// behavior that modifies Cypress.
+//
+// You can change the location of this file or turn off
+// automatically serving support files with the
+// 'supportFile' configuration option.
+//
+// You can read more here:
+// https://on.cypress.io/configuration
+// ***********************************************************
+
+// Import commands.js using ES2015 syntax:
+import './commands'
+
+// Alternatively you can use CommonJS syntax:
+// require('./commands')
diff --git a/playground/typescript-router-with-tests/env.d.ts b/playground/typescript-router-with-tests/env.d.ts
new file mode 100644
index 000000000..11f02fe2a
--- /dev/null
+++ b/playground/typescript-router-with-tests/env.d.ts
@@ -0,0 +1 @@
+///
diff --git a/playground/typescript-router-with-tests/index.html b/playground/typescript-router-with-tests/index.html
new file mode 100644
index 000000000..a88854489
--- /dev/null
+++ b/playground/typescript-router-with-tests/index.html
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+ Vite App
+
+
+
+
+
+
diff --git a/playground/typescript-router-with-tests/package.json b/playground/typescript-router-with-tests/package.json
new file mode 100644
index 000000000..935dfbea7
--- /dev/null
+++ b/playground/typescript-router-with-tests/package.json
@@ -0,0 +1,36 @@
+{
+ "name": "typescript-router-with-tests",
+ "version": "0.0.0",
+ "private": true,
+ "type": "module",
+ "scripts": {
+ "dev": "vite",
+ "build": "run-p type-check \"build-only {@}\" --",
+ "preview": "vite preview",
+ "test:unit": "vitest",
+ "test:e2e": "start-server-and-test preview http://localhost:4173 'cypress run --e2e'",
+ "test:e2e:dev": "start-server-and-test 'vite dev --port 4173' http://localhost:4173 'cypress open --e2e'",
+ "build-only": "vite build",
+ "type-check": "vue-tsc --build --force"
+ },
+ "dependencies": {
+ "vue": "^3.4.15",
+ "vue-router": "^4.2.5"
+ },
+ "devDependencies": {
+ "@tsconfig/node20": "^20.1.2",
+ "@types/jsdom": "^21.1.6",
+ "@types/node": "^20.11.16",
+ "@vitejs/plugin-vue": "^5.0.3",
+ "@vue/test-utils": "^2.4.4",
+ "@vue/tsconfig": "^0.5.1",
+ "cypress": "^13.6.4",
+ "jsdom": "^24.0.0",
+ "npm-run-all2": "^6.1.2",
+ "start-server-and-test": "^2.0.3",
+ "typescript": "~5.3.0",
+ "vite": "^5.0.11",
+ "vitest": "^1.2.2",
+ "vue-tsc": "^1.8.27"
+ }
+}
diff --git a/playground/typescript-router-with-tests/public/favicon.ico b/playground/typescript-router-with-tests/public/favicon.ico
new file mode 100644
index 000000000..df36fcfb7
Binary files /dev/null and b/playground/typescript-router-with-tests/public/favicon.ico differ
diff --git a/playground/typescript-router-with-tests/src/App.vue b/playground/typescript-router-with-tests/src/App.vue
new file mode 100644
index 000000000..7905b0516
--- /dev/null
+++ b/playground/typescript-router-with-tests/src/App.vue
@@ -0,0 +1,85 @@
+
+
+
+
+
+
+
+ You’ve successfully created a project with
+ Vite +
+ Vue 3. What's next?
+
+
+
+
+
diff --git a/playground/typescript-router-with-tests/src/components/TheWelcome.vue b/playground/typescript-router-with-tests/src/components/TheWelcome.vue
new file mode 100644
index 000000000..49d8f7354
--- /dev/null
+++ b/playground/typescript-router-with-tests/src/components/TheWelcome.vue
@@ -0,0 +1,88 @@
+
+
+
+
+
+
+
+ Documentation
+
+ Vue’s
+ official documentation
+ provides you with all information you need to get started.
+
+
+
+
+
+
+ Tooling
+
+ This project is served and bundled with
+ Vite. The
+ recommended IDE setup is
+ VSCode +
+ Volar. If
+ you need to test your components and web pages, check out
+ Cypress and
+ Cypress Component Testing.
+
+
+
+ More instructions are available in README.md.
+
+
+
+
+
+
+ Ecosystem
+
+ Get official tools and libraries for your project:
+ Pinia,
+ Vue Router,
+ Vue Test Utils, and
+ Vue Dev Tools. If
+ you need more resources, we suggest paying
+ Awesome Vue
+ a visit.
+
+
+
+
+
+
+ Community
+
+ Got stuck? Ask your question on
+ Vue Land, our official
+ Discord server, or
+ StackOverflow. You should also subscribe to
+ our mailing list and follow
+ the official
+ @vuejs
+ twitter account for latest news in the Vue world.
+
+
+
+
+
+
+ Support Vue
+
+ As an independent project, Vue relies on community backing for its sustainability. You can help
+ us by
+ becoming a sponsor.
+
+
diff --git a/playground/typescript-router-with-tests/src/components/WelcomeItem.vue b/playground/typescript-router-with-tests/src/components/WelcomeItem.vue
new file mode 100644
index 000000000..6d7086aea
--- /dev/null
+++ b/playground/typescript-router-with-tests/src/components/WelcomeItem.vue
@@ -0,0 +1,87 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/playground/typescript-router-with-tests/src/components/__tests__/HelloWorld.spec.ts b/playground/typescript-router-with-tests/src/components/__tests__/HelloWorld.spec.ts
new file mode 100644
index 000000000..253320200
--- /dev/null
+++ b/playground/typescript-router-with-tests/src/components/__tests__/HelloWorld.spec.ts
@@ -0,0 +1,11 @@
+import { describe, it, expect } from 'vitest'
+
+import { mount } from '@vue/test-utils'
+import HelloWorld from '../HelloWorld.vue'
+
+describe('HelloWorld', () => {
+ it('renders properly', () => {
+ const wrapper = mount(HelloWorld, { props: { msg: 'Hello Vitest' } })
+ expect(wrapper.text()).toContain('Hello Vitest')
+ })
+})
diff --git a/playground/typescript-router-with-tests/src/components/icons/IconCommunity.vue b/playground/typescript-router-with-tests/src/components/icons/IconCommunity.vue
new file mode 100644
index 000000000..2dc8b0552
--- /dev/null
+++ b/playground/typescript-router-with-tests/src/components/icons/IconCommunity.vue
@@ -0,0 +1,7 @@
+
+
+
diff --git a/playground/typescript-router-with-tests/src/components/icons/IconDocumentation.vue b/playground/typescript-router-with-tests/src/components/icons/IconDocumentation.vue
new file mode 100644
index 000000000..6d4791cfb
--- /dev/null
+++ b/playground/typescript-router-with-tests/src/components/icons/IconDocumentation.vue
@@ -0,0 +1,7 @@
+
+
+
diff --git a/playground/typescript-router-with-tests/src/components/icons/IconEcosystem.vue b/playground/typescript-router-with-tests/src/components/icons/IconEcosystem.vue
new file mode 100644
index 000000000..c3a4f078c
--- /dev/null
+++ b/playground/typescript-router-with-tests/src/components/icons/IconEcosystem.vue
@@ -0,0 +1,7 @@
+
+
+
diff --git a/playground/typescript-router-with-tests/src/components/icons/IconSupport.vue b/playground/typescript-router-with-tests/src/components/icons/IconSupport.vue
new file mode 100644
index 000000000..7452834d3
--- /dev/null
+++ b/playground/typescript-router-with-tests/src/components/icons/IconSupport.vue
@@ -0,0 +1,7 @@
+
+
+
diff --git a/playground/typescript-router-with-tests/src/components/icons/IconTooling.vue b/playground/typescript-router-with-tests/src/components/icons/IconTooling.vue
new file mode 100644
index 000000000..660598d7c
--- /dev/null
+++ b/playground/typescript-router-with-tests/src/components/icons/IconTooling.vue
@@ -0,0 +1,19 @@
+
+
+
+
diff --git a/playground/typescript-router-with-tests/src/main.ts b/playground/typescript-router-with-tests/src/main.ts
new file mode 100644
index 000000000..5a5dbdba7
--- /dev/null
+++ b/playground/typescript-router-with-tests/src/main.ts
@@ -0,0 +1,11 @@
+import './assets/main.css'
+
+import { createApp } from 'vue'
+import App from './App.vue'
+import router from './router'
+
+const app = createApp(App)
+
+app.use(router)
+
+app.mount('#app')
diff --git a/playground/typescript-router-with-tests/src/router/index.ts b/playground/typescript-router-with-tests/src/router/index.ts
new file mode 100644
index 000000000..a49ae507f
--- /dev/null
+++ b/playground/typescript-router-with-tests/src/router/index.ts
@@ -0,0 +1,23 @@
+import { createRouter, createWebHistory } from 'vue-router'
+import HomeView from '../views/HomeView.vue'
+
+const router = createRouter({
+ history: createWebHistory(import.meta.env.BASE_URL),
+ routes: [
+ {
+ path: '/',
+ name: 'home',
+ component: HomeView
+ },
+ {
+ path: '/about',
+ name: 'about',
+ // route level code-splitting
+ // this generates a separate chunk (About.[hash].js) for this route
+ // which is lazy-loaded when the route is visited.
+ component: () => import('../views/AboutView.vue')
+ }
+ ]
+})
+
+export default router
diff --git a/playground/typescript-router-with-tests/src/views/AboutView.vue b/playground/typescript-router-with-tests/src/views/AboutView.vue
new file mode 100644
index 000000000..756ad2a17
--- /dev/null
+++ b/playground/typescript-router-with-tests/src/views/AboutView.vue
@@ -0,0 +1,15 @@
+
+
+
This is an about page
+
+
+
+
diff --git a/playground/typescript-router-with-tests/src/views/HomeView.vue b/playground/typescript-router-with-tests/src/views/HomeView.vue
new file mode 100644
index 000000000..d5c0217e4
--- /dev/null
+++ b/playground/typescript-router-with-tests/src/views/HomeView.vue
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
diff --git a/playground/typescript-router-with-tests/tsconfig.app.json b/playground/typescript-router-with-tests/tsconfig.app.json
new file mode 100644
index 000000000..e14c754d3
--- /dev/null
+++ b/playground/typescript-router-with-tests/tsconfig.app.json
@@ -0,0 +1,14 @@
+{
+ "extends": "@vue/tsconfig/tsconfig.dom.json",
+ "include": ["env.d.ts", "src/**/*", "src/**/*.vue"],
+ "exclude": ["src/**/__tests__/*"],
+ "compilerOptions": {
+ "composite": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
+
+ "baseUrl": ".",
+ "paths": {
+ "@/*": ["./src/*"]
+ }
+ }
+}
diff --git a/playground/typescript-router-with-tests/tsconfig.json b/playground/typescript-router-with-tests/tsconfig.json
new file mode 100644
index 000000000..5304731b8
--- /dev/null
+++ b/playground/typescript-router-with-tests/tsconfig.json
@@ -0,0 +1,17 @@
+{
+ "files": [],
+ "references": [
+ {
+ "path": "./tsconfig.node.json"
+ },
+ {
+ "path": "./tsconfig.app.json"
+ },
+ {
+ "path": "./tsconfig.vitest.json"
+ }
+ ],
+ "compilerOptions": {
+ "module": "NodeNext"
+ }
+}
diff --git a/playground/typescript-router-with-tests/tsconfig.node.json b/playground/typescript-router-with-tests/tsconfig.node.json
new file mode 100644
index 000000000..f09406303
--- /dev/null
+++ b/playground/typescript-router-with-tests/tsconfig.node.json
@@ -0,0 +1,19 @@
+{
+ "extends": "@tsconfig/node20/tsconfig.json",
+ "include": [
+ "vite.config.*",
+ "vitest.config.*",
+ "cypress.config.*",
+ "nightwatch.conf.*",
+ "playwright.config.*"
+ ],
+ "compilerOptions": {
+ "composite": true,
+ "noEmit": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
+
+ "module": "ESNext",
+ "moduleResolution": "Bundler",
+ "types": ["node"]
+ }
+}
diff --git a/playground/typescript-router-with-tests/tsconfig.vitest.json b/playground/typescript-router-with-tests/tsconfig.vitest.json
new file mode 100644
index 000000000..571995d11
--- /dev/null
+++ b/playground/typescript-router-with-tests/tsconfig.vitest.json
@@ -0,0 +1,11 @@
+{
+ "extends": "./tsconfig.app.json",
+ "exclude": [],
+ "compilerOptions": {
+ "composite": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.vitest.tsbuildinfo",
+
+ "lib": [],
+ "types": ["node", "jsdom"]
+ }
+}
diff --git a/playground/typescript-router-with-tests/vite.config.ts b/playground/typescript-router-with-tests/vite.config.ts
new file mode 100644
index 000000000..5c45e1d9b
--- /dev/null
+++ b/playground/typescript-router-with-tests/vite.config.ts
@@ -0,0 +1,16 @@
+import { fileURLToPath, URL } from 'node:url'
+
+import { defineConfig } from 'vite'
+import vue from '@vitejs/plugin-vue'
+
+// https://vitejs.dev/config/
+export default defineConfig({
+ plugins: [
+ vue(),
+ ],
+ resolve: {
+ alias: {
+ '@': fileURLToPath(new URL('./src', import.meta.url))
+ }
+ }
+})
diff --git a/playground/typescript-router-with-tests/vitest.config.ts b/playground/typescript-router-with-tests/vitest.config.ts
new file mode 100644
index 000000000..10067d578
--- /dev/null
+++ b/playground/typescript-router-with-tests/vitest.config.ts
@@ -0,0 +1,14 @@
+import { fileURLToPath } from 'node:url'
+import { mergeConfig, defineConfig, configDefaults } from 'vitest/config'
+import viteConfig from './vite.config'
+
+export default mergeConfig(
+ viteConfig,
+ defineConfig({
+ test: {
+ environment: 'jsdom',
+ exclude: [...configDefaults.exclude, 'e2e/*'],
+ root: fileURLToPath(new URL('./', import.meta.url))
+ }
+ })
+)
diff --git a/playground/typescript-router/.gitignore b/playground/typescript-router/.gitignore
new file mode 100644
index 000000000..8ee54e8d3
--- /dev/null
+++ b/playground/typescript-router/.gitignore
@@ -0,0 +1,30 @@
+# 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/
+
+# Editor directories and files
+.vscode/*
+!.vscode/extensions.json
+.idea
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?
+
+*.tsbuildinfo
diff --git a/playground/typescript-router/README.md b/playground/typescript-router/README.md
new file mode 100644
index 000000000..3fd6ad110
--- /dev/null
+++ b/playground/typescript-router/README.md
@@ -0,0 +1,40 @@
+# typescript-router
+
+This template should help get you started developing with Vue 3 in Vite.
+
+## Recommended IDE Setup
+
+[VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur) + [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin).
+
+## Type Support for `.vue` Imports in TS
+
+TypeScript cannot handle type information for `.vue` imports by default, so we replace the `tsc` CLI with `vue-tsc` for type checking. In editors, we need [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin) to make the TypeScript language service aware of `.vue` types.
+
+If the standalone TypeScript plugin doesn't feel fast enough to you, Volar has also implemented a [Take Over Mode](https://github.com/johnsoncodehk/volar/discussions/471#discussioncomment-1361669) that is more performant. You can enable it by the following steps:
+
+1. Disable the built-in TypeScript Extension
+ 1) Run `Extensions: Show Built-in Extensions` from VSCode's command palette
+ 2) Find `TypeScript and JavaScript Language Features`, right click and select `Disable (Workspace)`
+2. Reload the VSCode window by running `Developer: Reload Window` from the command palette.
+
+## Customize configuration
+
+See [Vite Configuration Reference](https://vitejs.dev/config/).
+
+## Project Setup
+
+```sh
+pnpm install
+```
+
+### Compile and Hot-Reload for Development
+
+```sh
+pnpm dev
+```
+
+### Type-Check, Compile and Minify for Production
+
+```sh
+pnpm build
+```
diff --git a/playground/typescript-router/env.d.ts b/playground/typescript-router/env.d.ts
new file mode 100644
index 000000000..11f02fe2a
--- /dev/null
+++ b/playground/typescript-router/env.d.ts
@@ -0,0 +1 @@
+///
diff --git a/playground/typescript-router/index.html b/playground/typescript-router/index.html
new file mode 100644
index 000000000..a88854489
--- /dev/null
+++ b/playground/typescript-router/index.html
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+ Vite App
+
+
+
+
+
+
diff --git a/playground/typescript-router/package.json b/playground/typescript-router/package.json
new file mode 100644
index 000000000..ad7f7341b
--- /dev/null
+++ b/playground/typescript-router/package.json
@@ -0,0 +1,27 @@
+{
+ "name": "typescript-router",
+ "version": "0.0.0",
+ "private": true,
+ "type": "module",
+ "scripts": {
+ "dev": "vite",
+ "build": "run-p type-check \"build-only {@}\" --",
+ "preview": "vite preview",
+ "build-only": "vite build",
+ "type-check": "vue-tsc --build --force"
+ },
+ "dependencies": {
+ "vue": "^3.4.15",
+ "vue-router": "^4.2.5"
+ },
+ "devDependencies": {
+ "@tsconfig/node20": "^20.1.2",
+ "@types/node": "^20.11.16",
+ "@vitejs/plugin-vue": "^5.0.3",
+ "@vue/tsconfig": "^0.5.1",
+ "npm-run-all2": "^6.1.2",
+ "typescript": "~5.3.0",
+ "vite": "^5.0.11",
+ "vue-tsc": "^1.8.27"
+ }
+}
diff --git a/playground/typescript-router/public/favicon.ico b/playground/typescript-router/public/favicon.ico
new file mode 100644
index 000000000..df36fcfb7
Binary files /dev/null and b/playground/typescript-router/public/favicon.ico differ
diff --git a/playground/typescript-router/src/App.vue b/playground/typescript-router/src/App.vue
new file mode 100644
index 000000000..7905b0516
--- /dev/null
+++ b/playground/typescript-router/src/App.vue
@@ -0,0 +1,85 @@
+
+
+
+
+
+
+
+ You’ve successfully created a project with
+ Vite +
+ Vue 3. What's next?
+
+
+
+
+
diff --git a/playground/typescript-router/src/components/TheWelcome.vue b/playground/typescript-router/src/components/TheWelcome.vue
new file mode 100644
index 000000000..49d8f7354
--- /dev/null
+++ b/playground/typescript-router/src/components/TheWelcome.vue
@@ -0,0 +1,88 @@
+
+
+
+
+
+
+
+ Documentation
+
+ Vue’s
+ official documentation
+ provides you with all information you need to get started.
+
+
+
+
+
+
+ Tooling
+
+ This project is served and bundled with
+ Vite. The
+ recommended IDE setup is
+ VSCode +
+ Volar. If
+ you need to test your components and web pages, check out
+ Cypress and
+ Cypress Component Testing.
+
+
+
+ More instructions are available in README.md.
+
+
+
+
+
+
+ Ecosystem
+
+ Get official tools and libraries for your project:
+ Pinia,
+ Vue Router,
+ Vue Test Utils, and
+ Vue Dev Tools. If
+ you need more resources, we suggest paying
+ Awesome Vue
+ a visit.
+
+
+
+
+
+
+ Community
+
+ Got stuck? Ask your question on
+ Vue Land, our official
+ Discord server, or
+ StackOverflow. You should also subscribe to
+ our mailing list and follow
+ the official
+ @vuejs
+ twitter account for latest news in the Vue world.
+
+
+
+
+
+
+ Support Vue
+
+ As an independent project, Vue relies on community backing for its sustainability. You can help
+ us by
+ becoming a sponsor.
+
+
diff --git a/playground/typescript-router/src/components/WelcomeItem.vue b/playground/typescript-router/src/components/WelcomeItem.vue
new file mode 100644
index 000000000..6d7086aea
--- /dev/null
+++ b/playground/typescript-router/src/components/WelcomeItem.vue
@@ -0,0 +1,87 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/playground/typescript-router/src/components/icons/IconCommunity.vue b/playground/typescript-router/src/components/icons/IconCommunity.vue
new file mode 100644
index 000000000..2dc8b0552
--- /dev/null
+++ b/playground/typescript-router/src/components/icons/IconCommunity.vue
@@ -0,0 +1,7 @@
+
+
+
diff --git a/playground/typescript-router/src/components/icons/IconDocumentation.vue b/playground/typescript-router/src/components/icons/IconDocumentation.vue
new file mode 100644
index 000000000..6d4791cfb
--- /dev/null
+++ b/playground/typescript-router/src/components/icons/IconDocumentation.vue
@@ -0,0 +1,7 @@
+
+
+
diff --git a/playground/typescript-router/src/components/icons/IconEcosystem.vue b/playground/typescript-router/src/components/icons/IconEcosystem.vue
new file mode 100644
index 000000000..c3a4f078c
--- /dev/null
+++ b/playground/typescript-router/src/components/icons/IconEcosystem.vue
@@ -0,0 +1,7 @@
+
+
+
diff --git a/playground/typescript-router/src/components/icons/IconSupport.vue b/playground/typescript-router/src/components/icons/IconSupport.vue
new file mode 100644
index 000000000..7452834d3
--- /dev/null
+++ b/playground/typescript-router/src/components/icons/IconSupport.vue
@@ -0,0 +1,7 @@
+
+
+
diff --git a/playground/typescript-router/src/components/icons/IconTooling.vue b/playground/typescript-router/src/components/icons/IconTooling.vue
new file mode 100644
index 000000000..660598d7c
--- /dev/null
+++ b/playground/typescript-router/src/components/icons/IconTooling.vue
@@ -0,0 +1,19 @@
+
+
+
+
diff --git a/playground/typescript-router/src/main.ts b/playground/typescript-router/src/main.ts
new file mode 100644
index 000000000..5a5dbdba7
--- /dev/null
+++ b/playground/typescript-router/src/main.ts
@@ -0,0 +1,11 @@
+import './assets/main.css'
+
+import { createApp } from 'vue'
+import App from './App.vue'
+import router from './router'
+
+const app = createApp(App)
+
+app.use(router)
+
+app.mount('#app')
diff --git a/playground/typescript-router/src/router/index.ts b/playground/typescript-router/src/router/index.ts
new file mode 100644
index 000000000..a49ae507f
--- /dev/null
+++ b/playground/typescript-router/src/router/index.ts
@@ -0,0 +1,23 @@
+import { createRouter, createWebHistory } from 'vue-router'
+import HomeView from '../views/HomeView.vue'
+
+const router = createRouter({
+ history: createWebHistory(import.meta.env.BASE_URL),
+ routes: [
+ {
+ path: '/',
+ name: 'home',
+ component: HomeView
+ },
+ {
+ path: '/about',
+ name: 'about',
+ // route level code-splitting
+ // this generates a separate chunk (About.[hash].js) for this route
+ // which is lazy-loaded when the route is visited.
+ component: () => import('../views/AboutView.vue')
+ }
+ ]
+})
+
+export default router
diff --git a/playground/typescript-router/src/views/AboutView.vue b/playground/typescript-router/src/views/AboutView.vue
new file mode 100644
index 000000000..756ad2a17
--- /dev/null
+++ b/playground/typescript-router/src/views/AboutView.vue
@@ -0,0 +1,15 @@
+
+
+
This is an about page
+
+
+
+
diff --git a/playground/typescript-router/src/views/HomeView.vue b/playground/typescript-router/src/views/HomeView.vue
new file mode 100644
index 000000000..d5c0217e4
--- /dev/null
+++ b/playground/typescript-router/src/views/HomeView.vue
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
diff --git a/playground/typescript-router/tsconfig.app.json b/playground/typescript-router/tsconfig.app.json
new file mode 100644
index 000000000..e14c754d3
--- /dev/null
+++ b/playground/typescript-router/tsconfig.app.json
@@ -0,0 +1,14 @@
+{
+ "extends": "@vue/tsconfig/tsconfig.dom.json",
+ "include": ["env.d.ts", "src/**/*", "src/**/*.vue"],
+ "exclude": ["src/**/__tests__/*"],
+ "compilerOptions": {
+ "composite": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
+
+ "baseUrl": ".",
+ "paths": {
+ "@/*": ["./src/*"]
+ }
+ }
+}
diff --git a/playground/typescript-router/tsconfig.json b/playground/typescript-router/tsconfig.json
new file mode 100644
index 000000000..66b5e5703
--- /dev/null
+++ b/playground/typescript-router/tsconfig.json
@@ -0,0 +1,11 @@
+{
+ "files": [],
+ "references": [
+ {
+ "path": "./tsconfig.node.json"
+ },
+ {
+ "path": "./tsconfig.app.json"
+ }
+ ]
+}
diff --git a/playground/typescript-router/tsconfig.node.json b/playground/typescript-router/tsconfig.node.json
new file mode 100644
index 000000000..f09406303
--- /dev/null
+++ b/playground/typescript-router/tsconfig.node.json
@@ -0,0 +1,19 @@
+{
+ "extends": "@tsconfig/node20/tsconfig.json",
+ "include": [
+ "vite.config.*",
+ "vitest.config.*",
+ "cypress.config.*",
+ "nightwatch.conf.*",
+ "playwright.config.*"
+ ],
+ "compilerOptions": {
+ "composite": true,
+ "noEmit": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
+
+ "module": "ESNext",
+ "moduleResolution": "Bundler",
+ "types": ["node"]
+ }
+}
diff --git a/playground/typescript-router/vite.config.ts b/playground/typescript-router/vite.config.ts
new file mode 100644
index 000000000..5c45e1d9b
--- /dev/null
+++ b/playground/typescript-router/vite.config.ts
@@ -0,0 +1,16 @@
+import { fileURLToPath, URL } from 'node:url'
+
+import { defineConfig } from 'vite'
+import vue from '@vitejs/plugin-vue'
+
+// https://vitejs.dev/config/
+export default defineConfig({
+ plugins: [
+ vue(),
+ ],
+ resolve: {
+ alias: {
+ '@': fileURLToPath(new URL('./src', import.meta.url))
+ }
+ }
+})
diff --git a/playground/typescript-vitest-cypress/.gitignore b/playground/typescript-vitest-cypress/.gitignore
new file mode 100644
index 000000000..8ee54e8d3
--- /dev/null
+++ b/playground/typescript-vitest-cypress/.gitignore
@@ -0,0 +1,30 @@
+# 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/
+
+# Editor directories and files
+.vscode/*
+!.vscode/extensions.json
+.idea
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?
+
+*.tsbuildinfo
diff --git a/playground/typescript-vitest-cypress/README.md b/playground/typescript-vitest-cypress/README.md
new file mode 100644
index 000000000..03d30ecc0
--- /dev/null
+++ b/playground/typescript-vitest-cypress/README.md
@@ -0,0 +1,62 @@
+# typescript-vitest-cypress
+
+This template should help get you started developing with Vue 3 in Vite.
+
+## Recommended IDE Setup
+
+[VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur) + [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin).
+
+## Type Support for `.vue` Imports in TS
+
+TypeScript cannot handle type information for `.vue` imports by default, so we replace the `tsc` CLI with `vue-tsc` for type checking. In editors, we need [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin) to make the TypeScript language service aware of `.vue` types.
+
+If the standalone TypeScript plugin doesn't feel fast enough to you, Volar has also implemented a [Take Over Mode](https://github.com/johnsoncodehk/volar/discussions/471#discussioncomment-1361669) that is more performant. You can enable it by the following steps:
+
+1. Disable the built-in TypeScript Extension
+ 1) Run `Extensions: Show Built-in Extensions` from VSCode's command palette
+ 2) Find `TypeScript and JavaScript Language Features`, right click and select `Disable (Workspace)`
+2. Reload the VSCode window by running `Developer: Reload Window` from the command palette.
+
+## Customize configuration
+
+See [Vite Configuration Reference](https://vitejs.dev/config/).
+
+## Project Setup
+
+```sh
+pnpm install
+```
+
+### Compile and Hot-Reload for Development
+
+```sh
+pnpm dev
+```
+
+### Type-Check, Compile and Minify for Production
+
+```sh
+pnpm build
+```
+
+### Run Unit Tests with [Vitest](https://vitest.dev/)
+
+```sh
+pnpm test:unit
+```
+
+### Run End-to-End Tests with [Cypress](https://www.cypress.io/)
+
+```sh
+pnpm test:e2e:dev
+```
+
+This runs the end-to-end tests against the Vite development server.
+It is much faster than the production build.
+
+But it's still recommended to test the production build with `test:e2e` before deploying (e.g. in CI environments):
+
+```sh
+pnpm build
+pnpm test:e2e
+```
diff --git a/playground/typescript-vitest-cypress/cypress.config.ts b/playground/typescript-vitest-cypress/cypress.config.ts
new file mode 100644
index 000000000..0f66080fd
--- /dev/null
+++ b/playground/typescript-vitest-cypress/cypress.config.ts
@@ -0,0 +1,8 @@
+import { defineConfig } from 'cypress'
+
+export default defineConfig({
+ e2e: {
+ specPattern: 'cypress/e2e/**/*.{cy,spec}.{js,jsx,ts,tsx}',
+ baseUrl: 'http://localhost:4173'
+ }
+})
diff --git a/playground/typescript-vitest-cypress/cypress/e2e/example.cy.ts b/playground/typescript-vitest-cypress/cypress/e2e/example.cy.ts
new file mode 100644
index 000000000..7554c35d8
--- /dev/null
+++ b/playground/typescript-vitest-cypress/cypress/e2e/example.cy.ts
@@ -0,0 +1,8 @@
+// https://on.cypress.io/api
+
+describe('My First Test', () => {
+ it('visits the app root url', () => {
+ cy.visit('/')
+ cy.contains('h1', 'You did it!')
+ })
+})
diff --git a/playground/typescript-vitest-cypress/cypress/e2e/tsconfig.json b/playground/typescript-vitest-cypress/cypress/e2e/tsconfig.json
new file mode 100644
index 000000000..37748feb7
--- /dev/null
+++ b/playground/typescript-vitest-cypress/cypress/e2e/tsconfig.json
@@ -0,0 +1,10 @@
+{
+ "extends": "@vue/tsconfig/tsconfig.dom.json",
+ "include": ["./**/*", "../support/**/*"],
+ "compilerOptions": {
+ "isolatedModules": false,
+ "target": "es5",
+ "lib": ["es5", "dom"],
+ "types": ["cypress"]
+ }
+}
diff --git a/playground/typescript-vitest-cypress/cypress/fixtures/example.json b/playground/typescript-vitest-cypress/cypress/fixtures/example.json
new file mode 100644
index 000000000..02e425437
--- /dev/null
+++ b/playground/typescript-vitest-cypress/cypress/fixtures/example.json
@@ -0,0 +1,5 @@
+{
+ "name": "Using fixtures to represent data",
+ "email": "hello@cypress.io",
+ "body": "Fixtures are a great way to mock data for responses to routes"
+}
diff --git a/playground/typescript-vitest-cypress/cypress/support/commands.ts b/playground/typescript-vitest-cypress/cypress/support/commands.ts
new file mode 100644
index 000000000..9b7bb8e25
--- /dev/null
+++ b/playground/typescript-vitest-cypress/cypress/support/commands.ts
@@ -0,0 +1,39 @@
+///
+// ***********************************************
+// This example commands.ts shows you how to
+// create various custom commands and overwrite
+// existing commands.
+//
+// For more comprehensive examples of custom
+// commands please read more here:
+// https://on.cypress.io/custom-commands
+// ***********************************************
+//
+//
+// -- This is a parent command --
+// Cypress.Commands.add('login', (email, password) => { ... })
+//
+//
+// -- This is a child command --
+// Cypress.Commands.add('drag', { prevSubject: 'element'}, (subject, options) => { ... })
+//
+//
+// -- This is a dual command --
+// Cypress.Commands.add('dismiss', { prevSubject: 'optional'}, (subject, options) => { ... })
+//
+//
+// -- This will overwrite an existing command --
+// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... })
+//
+// declare global {
+// namespace Cypress {
+// interface Chainable {
+// login(email: string, password: string): Chainable
+// drag(subject: string, options?: Partial): Chainable
+// dismiss(subject: string, options?: Partial): Chainable
+// visit(originalFn: CommandOriginalFn, url: string, options: Partial): Chainable
+// }
+// }
+// }
+
+export {}
diff --git a/playground/typescript-vitest-cypress/cypress/support/e2e.ts b/playground/typescript-vitest-cypress/cypress/support/e2e.ts
new file mode 100644
index 000000000..d68db96df
--- /dev/null
+++ b/playground/typescript-vitest-cypress/cypress/support/e2e.ts
@@ -0,0 +1,20 @@
+// ***********************************************************
+// This example support/index.js is processed and
+// loaded automatically before your test files.
+//
+// This is a great place to put global configuration and
+// behavior that modifies Cypress.
+//
+// You can change the location of this file or turn off
+// automatically serving support files with the
+// 'supportFile' configuration option.
+//
+// You can read more here:
+// https://on.cypress.io/configuration
+// ***********************************************************
+
+// Import commands.js using ES2015 syntax:
+import './commands'
+
+// Alternatively you can use CommonJS syntax:
+// require('./commands')
diff --git a/playground/typescript-vitest-cypress/env.d.ts b/playground/typescript-vitest-cypress/env.d.ts
new file mode 100644
index 000000000..11f02fe2a
--- /dev/null
+++ b/playground/typescript-vitest-cypress/env.d.ts
@@ -0,0 +1 @@
+///
diff --git a/playground/typescript-vitest-cypress/index.html b/playground/typescript-vitest-cypress/index.html
new file mode 100644
index 000000000..a88854489
--- /dev/null
+++ b/playground/typescript-vitest-cypress/index.html
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+ Vite App
+
+
+
+
+
+
diff --git a/playground/typescript-vitest-cypress/package.json b/playground/typescript-vitest-cypress/package.json
new file mode 100644
index 000000000..da4f4df97
--- /dev/null
+++ b/playground/typescript-vitest-cypress/package.json
@@ -0,0 +1,35 @@
+{
+ "name": "typescript-vitest-cypress",
+ "version": "0.0.0",
+ "private": true,
+ "type": "module",
+ "scripts": {
+ "dev": "vite",
+ "build": "run-p type-check \"build-only {@}\" --",
+ "preview": "vite preview",
+ "test:unit": "vitest",
+ "test:e2e": "start-server-and-test preview http://localhost:4173 'cypress run --e2e'",
+ "test:e2e:dev": "start-server-and-test 'vite dev --port 4173' http://localhost:4173 'cypress open --e2e'",
+ "build-only": "vite build",
+ "type-check": "vue-tsc --build --force"
+ },
+ "dependencies": {
+ "vue": "^3.4.15"
+ },
+ "devDependencies": {
+ "@tsconfig/node20": "^20.1.2",
+ "@types/jsdom": "^21.1.6",
+ "@types/node": "^20.11.16",
+ "@vitejs/plugin-vue": "^5.0.3",
+ "@vue/test-utils": "^2.4.4",
+ "@vue/tsconfig": "^0.5.1",
+ "cypress": "^13.6.4",
+ "jsdom": "^24.0.0",
+ "npm-run-all2": "^6.1.2",
+ "start-server-and-test": "^2.0.3",
+ "typescript": "~5.3.0",
+ "vite": "^5.0.11",
+ "vitest": "^1.2.2",
+ "vue-tsc": "^1.8.27"
+ }
+}
diff --git a/playground/typescript-vitest-cypress/public/favicon.ico b/playground/typescript-vitest-cypress/public/favicon.ico
new file mode 100644
index 000000000..df36fcfb7
Binary files /dev/null and b/playground/typescript-vitest-cypress/public/favicon.ico differ
diff --git a/playground/typescript-vitest-cypress/src/App.vue b/playground/typescript-vitest-cypress/src/App.vue
new file mode 100644
index 000000000..69f32f91f
--- /dev/null
+++ b/playground/typescript-vitest-cypress/src/App.vue
@@ -0,0 +1,10 @@
+
+ app
+
+
+
+
+
diff --git a/playground/typescript-vitest-cypress/src/assets/logo.svg b/playground/typescript-vitest-cypress/src/assets/logo.svg
new file mode 100644
index 000000000..756566035
--- /dev/null
+++ b/playground/typescript-vitest-cypress/src/assets/logo.svg
@@ -0,0 +1 @@
+
diff --git a/playground/typescript-vitest-cypress/src/assets/main.css b/playground/typescript-vitest-cypress/src/assets/main.css
new file mode 100644
index 000000000..5aadc6ceb
--- /dev/null
+++ b/playground/typescript-vitest-cypress/src/assets/main.css
@@ -0,0 +1,6 @@
+html, body, #app {
+ width: 100%;
+ height: 100%;
+ padding: 0;
+ margin: 0;
+}
diff --git a/playground/typescript-vitest-cypress/src/components/__tests__/HelloWorld.spec.ts b/playground/typescript-vitest-cypress/src/components/__tests__/HelloWorld.spec.ts
new file mode 100644
index 000000000..253320200
--- /dev/null
+++ b/playground/typescript-vitest-cypress/src/components/__tests__/HelloWorld.spec.ts
@@ -0,0 +1,11 @@
+import { describe, it, expect } from 'vitest'
+
+import { mount } from '@vue/test-utils'
+import HelloWorld from '../HelloWorld.vue'
+
+describe('HelloWorld', () => {
+ it('renders properly', () => {
+ const wrapper = mount(HelloWorld, { props: { msg: 'Hello Vitest' } })
+ expect(wrapper.text()).toContain('Hello Vitest')
+ })
+})
diff --git a/playground/typescript-vitest-cypress/src/main.ts b/playground/typescript-vitest-cypress/src/main.ts
new file mode 100644
index 000000000..0ac3a5ff0
--- /dev/null
+++ b/playground/typescript-vitest-cypress/src/main.ts
@@ -0,0 +1,6 @@
+import './assets/main.css'
+
+import { createApp } from 'vue'
+import App from './App.vue'
+
+createApp(App).mount('#app')
diff --git a/playground/typescript-vitest-cypress/tsconfig.app.json b/playground/typescript-vitest-cypress/tsconfig.app.json
new file mode 100644
index 000000000..e14c754d3
--- /dev/null
+++ b/playground/typescript-vitest-cypress/tsconfig.app.json
@@ -0,0 +1,14 @@
+{
+ "extends": "@vue/tsconfig/tsconfig.dom.json",
+ "include": ["env.d.ts", "src/**/*", "src/**/*.vue"],
+ "exclude": ["src/**/__tests__/*"],
+ "compilerOptions": {
+ "composite": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
+
+ "baseUrl": ".",
+ "paths": {
+ "@/*": ["./src/*"]
+ }
+ }
+}
diff --git a/playground/typescript-vitest-cypress/tsconfig.json b/playground/typescript-vitest-cypress/tsconfig.json
new file mode 100644
index 000000000..5304731b8
--- /dev/null
+++ b/playground/typescript-vitest-cypress/tsconfig.json
@@ -0,0 +1,17 @@
+{
+ "files": [],
+ "references": [
+ {
+ "path": "./tsconfig.node.json"
+ },
+ {
+ "path": "./tsconfig.app.json"
+ },
+ {
+ "path": "./tsconfig.vitest.json"
+ }
+ ],
+ "compilerOptions": {
+ "module": "NodeNext"
+ }
+}
diff --git a/playground/typescript-vitest-cypress/tsconfig.node.json b/playground/typescript-vitest-cypress/tsconfig.node.json
new file mode 100644
index 000000000..f09406303
--- /dev/null
+++ b/playground/typescript-vitest-cypress/tsconfig.node.json
@@ -0,0 +1,19 @@
+{
+ "extends": "@tsconfig/node20/tsconfig.json",
+ "include": [
+ "vite.config.*",
+ "vitest.config.*",
+ "cypress.config.*",
+ "nightwatch.conf.*",
+ "playwright.config.*"
+ ],
+ "compilerOptions": {
+ "composite": true,
+ "noEmit": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
+
+ "module": "ESNext",
+ "moduleResolution": "Bundler",
+ "types": ["node"]
+ }
+}
diff --git a/playground/typescript-vitest-cypress/tsconfig.vitest.json b/playground/typescript-vitest-cypress/tsconfig.vitest.json
new file mode 100644
index 000000000..571995d11
--- /dev/null
+++ b/playground/typescript-vitest-cypress/tsconfig.vitest.json
@@ -0,0 +1,11 @@
+{
+ "extends": "./tsconfig.app.json",
+ "exclude": [],
+ "compilerOptions": {
+ "composite": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.vitest.tsbuildinfo",
+
+ "lib": [],
+ "types": ["node", "jsdom"]
+ }
+}
diff --git a/playground/typescript-vitest-cypress/vite.config.ts b/playground/typescript-vitest-cypress/vite.config.ts
new file mode 100644
index 000000000..5c45e1d9b
--- /dev/null
+++ b/playground/typescript-vitest-cypress/vite.config.ts
@@ -0,0 +1,16 @@
+import { fileURLToPath, URL } from 'node:url'
+
+import { defineConfig } from 'vite'
+import vue from '@vitejs/plugin-vue'
+
+// https://vitejs.dev/config/
+export default defineConfig({
+ plugins: [
+ vue(),
+ ],
+ resolve: {
+ alias: {
+ '@': fileURLToPath(new URL('./src', import.meta.url))
+ }
+ }
+})
diff --git a/playground/typescript-vitest-cypress/vitest.config.ts b/playground/typescript-vitest-cypress/vitest.config.ts
new file mode 100644
index 000000000..10067d578
--- /dev/null
+++ b/playground/typescript-vitest-cypress/vitest.config.ts
@@ -0,0 +1,14 @@
+import { fileURLToPath } from 'node:url'
+import { mergeConfig, defineConfig, configDefaults } from 'vitest/config'
+import viteConfig from './vite.config'
+
+export default mergeConfig(
+ viteConfig,
+ defineConfig({
+ test: {
+ environment: 'jsdom',
+ exclude: [...configDefaults.exclude, 'e2e/*'],
+ root: fileURLToPath(new URL('./', import.meta.url))
+ }
+ })
+)
diff --git a/playground/typescript-vitest-nightwatch/.gitignore b/playground/typescript-vitest-nightwatch/.gitignore
new file mode 100644
index 000000000..0b938f131
--- /dev/null
+++ b/playground/typescript-vitest-nightwatch/.gitignore
@@ -0,0 +1,33 @@
+# 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/
+
+# Editor directories and files
+.vscode/*
+!.vscode/extensions.json
+.idea
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?
+
+*.tsbuildinfo
+
+logs/
+tests_output/
diff --git a/playground/typescript-vitest-nightwatch/.vscode/extensions.json b/playground/typescript-vitest-nightwatch/.vscode/extensions.json
new file mode 100644
index 000000000..dd9668a5c
--- /dev/null
+++ b/playground/typescript-vitest-nightwatch/.vscode/extensions.json
@@ -0,0 +1,3 @@
+{
+ "recommendations": ["browserstackcom.nightwatch"]
+}
diff --git a/playground/typescript-vitest-nightwatch/README.md b/playground/typescript-vitest-nightwatch/README.md
new file mode 100644
index 000000000..f4abca0db
--- /dev/null
+++ b/playground/typescript-vitest-nightwatch/README.md
@@ -0,0 +1,69 @@
+# typescript-vitest-nightwatch
+
+This template should help get you started developing with Vue 3 in Vite.
+
+## Recommended IDE Setup
+
+[VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur) + [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin).
+
+## Type Support for `.vue` Imports in TS
+
+TypeScript cannot handle type information for `.vue` imports by default, so we replace the `tsc` CLI with `vue-tsc` for type checking. In editors, we need [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin) to make the TypeScript language service aware of `.vue` types.
+
+If the standalone TypeScript plugin doesn't feel fast enough to you, Volar has also implemented a [Take Over Mode](https://github.com/johnsoncodehk/volar/discussions/471#discussioncomment-1361669) that is more performant. You can enable it by the following steps:
+
+1. Disable the built-in TypeScript Extension
+ 1) Run `Extensions: Show Built-in Extensions` from VSCode's command palette
+ 2) Find `TypeScript and JavaScript Language Features`, right click and select `Disable (Workspace)`
+2. Reload the VSCode window by running `Developer: Reload Window` from the command palette.
+
+## Customize configuration
+
+See [Vite Configuration Reference](https://vitejs.dev/config/).
+
+## Project Setup
+
+```sh
+pnpm install
+```
+
+### Compile and Hot-Reload for Development
+
+```sh
+pnpm dev
+```
+
+### Type-Check, Compile and Minify for Production
+
+```sh
+pnpm build
+```
+
+### Run Unit Tests with [Vitest](https://vitest.dev/)
+
+```sh
+pnpm test:unit
+```
+
+### Run End-to-End Tests with [Nightwatch](https://nightwatchjs.org/)
+
+```sh
+# When using CI, the project must be built first.
+pnpm build
+
+# Runs the end-to-end tests
+pnpm test:e2e
+# Runs the tests only on Chrome
+pnpm test:e2e --env chrome
+# Runs the tests of a specific file
+pnpm test:e2e tests/e2e/example.ts
+# Runs the tests in debug mode
+pnpm test:e2e --debug
+```
+
+### Run Headed Component Tests with [Nightwatch Component Testing](https://nightwatchjs.org/guide/component-testing/introduction.html)
+
+```sh
+pnpm test:unit
+pnpm test:unit -- --headless # for headless testing
+```
diff --git a/playground/typescript-vitest-nightwatch/env.d.ts b/playground/typescript-vitest-nightwatch/env.d.ts
new file mode 100644
index 000000000..11f02fe2a
--- /dev/null
+++ b/playground/typescript-vitest-nightwatch/env.d.ts
@@ -0,0 +1 @@
+///
diff --git a/playground/typescript-vitest-nightwatch/index.html b/playground/typescript-vitest-nightwatch/index.html
new file mode 100644
index 000000000..a88854489
--- /dev/null
+++ b/playground/typescript-vitest-nightwatch/index.html
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+ Vite App
+
+
+
+
+
+
diff --git a/playground/typescript-vitest-nightwatch/nightwatch.conf.cjs b/playground/typescript-vitest-nightwatch/nightwatch.conf.cjs
new file mode 100644
index 000000000..542647e5e
--- /dev/null
+++ b/playground/typescript-vitest-nightwatch/nightwatch.conf.cjs
@@ -0,0 +1,153 @@
+//
+// Refer to the online docs for more details:
+// https://nightwatchjs.org/guide/configuration/nightwatch-configuration-file.html
+//
+// _ _ _ _ _ _ _
+// | \ | |(_) | | | | | | | |
+// | \| | _ __ _ | |__ | |_ __ __ __ _ | |_ ___ | |__
+// | . ` || | / _` || '_ \ | __|\ \ /\ / / / _` || __| / __|| '_ \
+// | |\ || || (_| || | | || |_ \ V V / | (_| || |_ | (__ | | | |
+// \_| \_/|_| \__, ||_| |_| \__| \_/\_/ \__,_| \__| \___||_| |_|
+// __/ |
+// |___/
+//
+
+module.exports = {
+ // An array of folders (excluding subfolders) where your tests are located;
+ // if this is not specified, the test source must be passed as the second argument to the test runner.
+ src_folders: [],
+
+ // See https://nightwatchjs.org/guide/concepts/page-object-model.html
+ page_objects_path: [],
+
+ // See https://nightwatchjs.org/guide/extending-nightwatch/adding-custom-commands.html
+ custom_commands_path: [],
+
+ // See https://nightwatchjs.org/guide/extending-nightwatch/adding-custom-assertions.html
+ custom_assertions_path: [],
+
+ // See https://nightwatchjs.org/guide/extending-nightwatch/adding-plugins.html
+ plugins: ['@nightwatch/vue'],
+
+ // See https://nightwatchjs.org/guide/concepts/test-globals.html#external-test-globals
+ globals_path: '',
+
+ vite_dev_server: {
+ start_vite: true,
+ port: process.env.CI ? 4173 : 5173
+ },
+
+ webdriver: {},
+
+ test_workers: {
+ enabled: true,
+ workers: 'auto'
+ },
+
+ test_settings: {
+ default: {
+ disable_error_log: false,
+ launch_url: `http://localhost:${process.env.CI ? '4173' : '5173'}`,
+
+ screenshots: {
+ enabled: false,
+ path: 'screens',
+ on_failure: true
+ },
+
+ desiredCapabilities: {
+ browserName: 'firefox'
+ },
+
+ webdriver: {
+ start_process: true,
+ server_path: ''
+ }
+ },
+
+ safari: {
+ desiredCapabilities: {
+ browserName: 'safari',
+ alwaysMatch: {
+ acceptInsecureCerts: false
+ }
+ },
+ webdriver: {
+ start_process: true,
+ server_path: ''
+ }
+ },
+
+ firefox: {
+ desiredCapabilities: {
+ browserName: 'firefox',
+ alwaysMatch: {
+ acceptInsecureCerts: true,
+ 'moz:firefoxOptions': {
+ args: [
+ // '-headless',
+ // '-verbose'
+ ]
+ }
+ }
+ },
+ webdriver: {
+ start_process: true,
+ server_path: '',
+ cli_args: [
+ // very verbose geckodriver logs
+ // '-vv'
+ ]
+ }
+ },
+
+ chrome: {
+ desiredCapabilities: {
+ browserName: 'chrome',
+ 'goog:chromeOptions': {
+ // More info on Chromedriver: https://sites.google.com/a/chromium.org/chromedriver/
+ //
+ // w3c:false tells Chromedriver to run using the legacy JSONWire protocol (not required in Chrome 78)
+ w3c: true,
+ args: [
+ //'--no-sandbox',
+ //'--ignore-certificate-errors',
+ //'--allow-insecure-localhost',
+ //'--headless'
+ ]
+ }
+ },
+
+ webdriver: {
+ start_process: true,
+ server_path: '',
+ cli_args: [
+ // --verbose
+ ]
+ }
+ },
+
+ edge: {
+ desiredCapabilities: {
+ browserName: 'MicrosoftEdge',
+ 'ms:edgeOptions': {
+ w3c: true,
+ // More info on EdgeDriver: https://docs.microsoft.com/en-us/microsoft-edge/webdriver-chromium/capabilities-edge-options
+ args: [
+ //'--headless'
+ ]
+ }
+ },
+
+ webdriver: {
+ start_process: true,
+ // Download msedgedriver from https://docs.microsoft.com/en-us/microsoft-edge/webdriver-chromium/
+ // and set the location below:
+ server_path: '',
+ cli_args: [
+ // --verbose
+ ]
+ }
+ }
+ }
+}
diff --git a/playground/typescript-vitest-nightwatch/nightwatch/nightwatch.d.ts b/playground/typescript-vitest-nightwatch/nightwatch/nightwatch.d.ts
new file mode 100644
index 000000000..616e63f9f
--- /dev/null
+++ b/playground/typescript-vitest-nightwatch/nightwatch/nightwatch.d.ts
@@ -0,0 +1,13 @@
+import { NightwatchCustomAssertions, NightwatchCustomCommands } from 'nightwatch'
+
+declare module 'nightwatch' {
+ interface NightwatchCustomAssertions {
+ // Add your custom assertions' types here
+ // elementHasCount: (selector: string, count: number) => NightwatchBrowser
+ }
+
+ interface NightwatchCustomCommands {
+ // Add your custom commands' types here
+ // strictClick: (selector: string) => NightwatchBrowser
+ }
+}
diff --git a/playground/typescript-vitest-nightwatch/nightwatch/tsconfig.json b/playground/typescript-vitest-nightwatch/nightwatch/tsconfig.json
new file mode 100644
index 000000000..8cd7ca1da
--- /dev/null
+++ b/playground/typescript-vitest-nightwatch/nightwatch/tsconfig.json
@@ -0,0 +1,20 @@
+{
+ "extends": "@tsconfig/node20/tsconfig.json",
+ "compilerOptions": {
+ "composite": true,
+ "noEmit": true,
+ "tsBuildInfoFile": "../node_modules/.tmp/tsconfig.nightwatch.tsbuildinfo",
+
+ "target": "ESNext",
+ "module": "commonjs",
+ "moduleResolution": "node",
+ "rootDir": "../",
+ "lib": ["ESNext", "dom"],
+ "types": ["nightwatch"]
+ },
+ "include": ["../node_modules/@nightwatch/**/*", "../src/components/**/*", "../tests/e2e/**/*"],
+ "ts-node": {
+ "transpileOnly": true
+ },
+ "files": ["nightwatch.d.ts"]
+}
diff --git a/playground/typescript-vitest-nightwatch/package.json b/playground/typescript-vitest-nightwatch/package.json
new file mode 100644
index 000000000..1522712ec
--- /dev/null
+++ b/playground/typescript-vitest-nightwatch/package.json
@@ -0,0 +1,38 @@
+{
+ "name": "typescript-vitest-nightwatch",
+ "version": "0.0.0",
+ "private": true,
+ "type": "module",
+ "scripts": {
+ "dev": "vite",
+ "build": "run-p type-check \"build-only {@}\" --",
+ "preview": "vite preview",
+ "test:unit": "vitest",
+ "test:e2e": "nightwatch tests/e2e/*",
+ "build-only": "vite build",
+ "type-check": "vue-tsc --build --force"
+ },
+ "dependencies": {
+ "vue": "^3.4.15"
+ },
+ "devDependencies": {
+ "@nightwatch/vue": "^3.1.0",
+ "@tsconfig/node20": "^20.1.2",
+ "@types/jsdom": "^21.1.6",
+ "@types/node": "^20.11.16",
+ "@vitejs/plugin-vue": "^5.0.3",
+ "@vue/test-utils": "^2.4.4",
+ "@vue/tsconfig": "^0.5.1",
+ "chromedriver": "^121.0.0",
+ "geckodriver": "^4.3.2",
+ "jsdom": "^24.0.0",
+ "nightwatch": "^3.4.0",
+ "npm-run-all2": "^6.1.2",
+ "ts-node": "^10.9.2",
+ "typescript": "~5.3.0",
+ "vite": "^5.0.11",
+ "vite-plugin-nightwatch": "^0.4.6",
+ "vitest": "^1.2.2",
+ "vue-tsc": "^1.8.27"
+ }
+}
diff --git a/playground/typescript-vitest-nightwatch/public/favicon.ico b/playground/typescript-vitest-nightwatch/public/favicon.ico
new file mode 100644
index 000000000..df36fcfb7
Binary files /dev/null and b/playground/typescript-vitest-nightwatch/public/favicon.ico differ
diff --git a/playground/typescript-vitest-nightwatch/src/App.vue b/playground/typescript-vitest-nightwatch/src/App.vue
new file mode 100644
index 000000000..69f32f91f
--- /dev/null
+++ b/playground/typescript-vitest-nightwatch/src/App.vue
@@ -0,0 +1,10 @@
+
+ app
+
+
+
+
+
diff --git a/playground/typescript-vitest-nightwatch/src/assets/logo.svg b/playground/typescript-vitest-nightwatch/src/assets/logo.svg
new file mode 100644
index 000000000..756566035
--- /dev/null
+++ b/playground/typescript-vitest-nightwatch/src/assets/logo.svg
@@ -0,0 +1 @@
+
diff --git a/playground/typescript-vitest-nightwatch/src/assets/main.css b/playground/typescript-vitest-nightwatch/src/assets/main.css
new file mode 100644
index 000000000..5aadc6ceb
--- /dev/null
+++ b/playground/typescript-vitest-nightwatch/src/assets/main.css
@@ -0,0 +1,6 @@
+html, body, #app {
+ width: 100%;
+ height: 100%;
+ padding: 0;
+ margin: 0;
+}
diff --git a/playground/typescript-vitest-nightwatch/src/components/__tests__/HelloWorld.spec.ts b/playground/typescript-vitest-nightwatch/src/components/__tests__/HelloWorld.spec.ts
new file mode 100644
index 000000000..253320200
--- /dev/null
+++ b/playground/typescript-vitest-nightwatch/src/components/__tests__/HelloWorld.spec.ts
@@ -0,0 +1,11 @@
+import { describe, it, expect } from 'vitest'
+
+import { mount } from '@vue/test-utils'
+import HelloWorld from '../HelloWorld.vue'
+
+describe('HelloWorld', () => {
+ it('renders properly', () => {
+ const wrapper = mount(HelloWorld, { props: { msg: 'Hello Vitest' } })
+ expect(wrapper.text()).toContain('Hello Vitest')
+ })
+})
diff --git a/playground/typescript-vitest-nightwatch/src/main.ts b/playground/typescript-vitest-nightwatch/src/main.ts
new file mode 100644
index 000000000..0ac3a5ff0
--- /dev/null
+++ b/playground/typescript-vitest-nightwatch/src/main.ts
@@ -0,0 +1,6 @@
+import './assets/main.css'
+
+import { createApp } from 'vue'
+import App from './App.vue'
+
+createApp(App).mount('#app')
diff --git a/playground/typescript-vitest-nightwatch/tests/e2e/example.ts b/playground/typescript-vitest-nightwatch/tests/e2e/example.ts
new file mode 100644
index 000000000..43be3fce1
--- /dev/null
+++ b/playground/typescript-vitest-nightwatch/tests/e2e/example.ts
@@ -0,0 +1,11 @@
+describe('My First Test', function () {
+ before((browser) => {
+ browser.init()
+ })
+
+ it('visits the app root url', function () {
+ browser.assert.textContains('.green', 'You did it!')
+ })
+
+ after((browser) => browser.end())
+})
diff --git a/playground/typescript-vitest-nightwatch/tsconfig.app.json b/playground/typescript-vitest-nightwatch/tsconfig.app.json
new file mode 100644
index 000000000..e14c754d3
--- /dev/null
+++ b/playground/typescript-vitest-nightwatch/tsconfig.app.json
@@ -0,0 +1,14 @@
+{
+ "extends": "@vue/tsconfig/tsconfig.dom.json",
+ "include": ["env.d.ts", "src/**/*", "src/**/*.vue"],
+ "exclude": ["src/**/__tests__/*"],
+ "compilerOptions": {
+ "composite": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
+
+ "baseUrl": ".",
+ "paths": {
+ "@/*": ["./src/*"]
+ }
+ }
+}
diff --git a/playground/typescript-vitest-nightwatch/tsconfig.json b/playground/typescript-vitest-nightwatch/tsconfig.json
new file mode 100644
index 000000000..a5352e667
--- /dev/null
+++ b/playground/typescript-vitest-nightwatch/tsconfig.json
@@ -0,0 +1,17 @@
+{
+ "files": [],
+ "references": [
+ {
+ "path": "./tsconfig.node.json"
+ },
+ {
+ "path": "./tsconfig.app.json"
+ },
+ {
+ "path": "./tsconfig.vitest.json"
+ },
+ {
+ "path": "./nightwatch/tsconfig.json"
+ }
+ ]
+}
diff --git a/playground/typescript-vitest-nightwatch/tsconfig.node.json b/playground/typescript-vitest-nightwatch/tsconfig.node.json
new file mode 100644
index 000000000..f09406303
--- /dev/null
+++ b/playground/typescript-vitest-nightwatch/tsconfig.node.json
@@ -0,0 +1,19 @@
+{
+ "extends": "@tsconfig/node20/tsconfig.json",
+ "include": [
+ "vite.config.*",
+ "vitest.config.*",
+ "cypress.config.*",
+ "nightwatch.conf.*",
+ "playwright.config.*"
+ ],
+ "compilerOptions": {
+ "composite": true,
+ "noEmit": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
+
+ "module": "ESNext",
+ "moduleResolution": "Bundler",
+ "types": ["node"]
+ }
+}
diff --git a/playground/typescript-vitest-nightwatch/tsconfig.vitest.json b/playground/typescript-vitest-nightwatch/tsconfig.vitest.json
new file mode 100644
index 000000000..571995d11
--- /dev/null
+++ b/playground/typescript-vitest-nightwatch/tsconfig.vitest.json
@@ -0,0 +1,11 @@
+{
+ "extends": "./tsconfig.app.json",
+ "exclude": [],
+ "compilerOptions": {
+ "composite": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.vitest.tsbuildinfo",
+
+ "lib": [],
+ "types": ["node", "jsdom"]
+ }
+}
diff --git a/playground/typescript-vitest-nightwatch/vite.config.ts b/playground/typescript-vitest-nightwatch/vite.config.ts
new file mode 100644
index 000000000..be3cb9c57
--- /dev/null
+++ b/playground/typescript-vitest-nightwatch/vite.config.ts
@@ -0,0 +1,18 @@
+import { fileURLToPath, URL } from 'node:url'
+
+import { defineConfig } from 'vite'
+import vue from '@vitejs/plugin-vue'
+import nightwatchPlugin from 'vite-plugin-nightwatch'
+
+// https://vitejs.dev/config/
+export default defineConfig({
+ plugins: [
+ vue(),
+ nightwatchPlugin(),
+ ],
+ resolve: {
+ alias: {
+ '@': fileURLToPath(new URL('./src', import.meta.url))
+ }
+ }
+})
diff --git a/playground/typescript-vitest-nightwatch/vitest.config.ts b/playground/typescript-vitest-nightwatch/vitest.config.ts
new file mode 100644
index 000000000..10067d578
--- /dev/null
+++ b/playground/typescript-vitest-nightwatch/vitest.config.ts
@@ -0,0 +1,14 @@
+import { fileURLToPath } from 'node:url'
+import { mergeConfig, defineConfig, configDefaults } from 'vitest/config'
+import viteConfig from './vite.config'
+
+export default mergeConfig(
+ viteConfig,
+ defineConfig({
+ test: {
+ environment: 'jsdom',
+ exclude: [...configDefaults.exclude, 'e2e/*'],
+ root: fileURLToPath(new URL('./', import.meta.url))
+ }
+ })
+)
diff --git a/playground/typescript-vitest-playwright/.gitignore b/playground/typescript-vitest-playwright/.gitignore
new file mode 100644
index 000000000..aef72d03c
--- /dev/null
+++ b/playground/typescript-vitest-playwright/.gitignore
@@ -0,0 +1,33 @@
+# 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/
+
+# Editor directories and files
+.vscode/*
+!.vscode/extensions.json
+.idea
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?
+
+*.tsbuildinfo
+
+test-results/
+playwright-report/
diff --git a/playground/typescript-vitest-playwright/.vscode/extensions.json b/playground/typescript-vitest-playwright/.vscode/extensions.json
new file mode 100644
index 000000000..7b3f8bdae
--- /dev/null
+++ b/playground/typescript-vitest-playwright/.vscode/extensions.json
@@ -0,0 +1,3 @@
+{
+ "recommendations": ["ms-playwright.playwright"]
+}
diff --git a/playground/typescript-vitest-playwright/README.md b/playground/typescript-vitest-playwright/README.md
new file mode 100644
index 000000000..cdad7621b
--- /dev/null
+++ b/playground/typescript-vitest-playwright/README.md
@@ -0,0 +1,65 @@
+# typescript-vitest-playwright
+
+This template should help get you started developing with Vue 3 in Vite.
+
+## Recommended IDE Setup
+
+[VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur) + [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin).
+
+## Type Support for `.vue` Imports in TS
+
+TypeScript cannot handle type information for `.vue` imports by default, so we replace the `tsc` CLI with `vue-tsc` for type checking. In editors, we need [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin) to make the TypeScript language service aware of `.vue` types.
+
+If the standalone TypeScript plugin doesn't feel fast enough to you, Volar has also implemented a [Take Over Mode](https://github.com/johnsoncodehk/volar/discussions/471#discussioncomment-1361669) that is more performant. You can enable it by the following steps:
+
+1. Disable the built-in TypeScript Extension
+ 1) Run `Extensions: Show Built-in Extensions` from VSCode's command palette
+ 2) Find `TypeScript and JavaScript Language Features`, right click and select `Disable (Workspace)`
+2. Reload the VSCode window by running `Developer: Reload Window` from the command palette.
+
+## Customize configuration
+
+See [Vite Configuration Reference](https://vitejs.dev/config/).
+
+## Project Setup
+
+```sh
+pnpm install
+```
+
+### Compile and Hot-Reload for Development
+
+```sh
+pnpm dev
+```
+
+### Type-Check, Compile and Minify for Production
+
+```sh
+pnpm build
+```
+
+### Run Unit Tests with [Vitest](https://vitest.dev/)
+
+```sh
+pnpm test:unit
+```
+
+### Run End-to-End Tests with [Playwright](https://playwright.dev)
+
+```sh
+# Install browsers for the first run
+npx playwright install
+
+# When testing on CI, must build the project first
+pnpm build
+
+# Runs the end-to-end tests
+pnpm test:e2e
+# Runs the tests only on Chromium
+pnpm test:e2e --project=chromium
+# Runs the tests of a specific file
+pnpm test:e2e tests/example.spec.ts
+# Runs the tests in debug mode
+pnpm test:e2e --debug
+```
diff --git a/playground/typescript-vitest-playwright/e2e/tsconfig.json b/playground/typescript-vitest-playwright/e2e/tsconfig.json
new file mode 100644
index 000000000..be3bbfc0e
--- /dev/null
+++ b/playground/typescript-vitest-playwright/e2e/tsconfig.json
@@ -0,0 +1,4 @@
+{
+ "extends": "@tsconfig/node20/tsconfig.json",
+ "include": ["./**/*"]
+}
diff --git a/playground/typescript-vitest-playwright/e2e/vue.spec.ts b/playground/typescript-vitest-playwright/e2e/vue.spec.ts
new file mode 100644
index 000000000..3e5a3d02d
--- /dev/null
+++ b/playground/typescript-vitest-playwright/e2e/vue.spec.ts
@@ -0,0 +1,8 @@
+import { test, expect } from '@playwright/test';
+
+// See here how to get started:
+// https://playwright.dev/docs/intro
+test('visits the app root url', async ({ page }) => {
+ await page.goto('/');
+ await expect(page.locator('div.greetings > h1')).toHaveText('You did it!');
+})
diff --git a/playground/typescript-vitest-playwright/env.d.ts b/playground/typescript-vitest-playwright/env.d.ts
new file mode 100644
index 000000000..11f02fe2a
--- /dev/null
+++ b/playground/typescript-vitest-playwright/env.d.ts
@@ -0,0 +1 @@
+///
diff --git a/playground/typescript-vitest-playwright/index.html b/playground/typescript-vitest-playwright/index.html
new file mode 100644
index 000000000..a88854489
--- /dev/null
+++ b/playground/typescript-vitest-playwright/index.html
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+ Vite App
+
+
+
+
+
+
diff --git a/playground/typescript-vitest-playwright/package.json b/playground/typescript-vitest-playwright/package.json
new file mode 100644
index 000000000..d8b6030cf
--- /dev/null
+++ b/playground/typescript-vitest-playwright/package.json
@@ -0,0 +1,33 @@
+{
+ "name": "typescript-vitest-playwright",
+ "version": "0.0.0",
+ "private": true,
+ "type": "module",
+ "scripts": {
+ "dev": "vite",
+ "build": "run-p type-check \"build-only {@}\" --",
+ "preview": "vite preview",
+ "test:unit": "vitest",
+ "test:e2e": "playwright test",
+ "build-only": "vite build",
+ "type-check": "vue-tsc --build --force"
+ },
+ "dependencies": {
+ "vue": "^3.4.15"
+ },
+ "devDependencies": {
+ "@playwright/test": "^1.41.2",
+ "@tsconfig/node20": "^20.1.2",
+ "@types/jsdom": "^21.1.6",
+ "@types/node": "^20.11.16",
+ "@vitejs/plugin-vue": "^5.0.3",
+ "@vue/test-utils": "^2.4.4",
+ "@vue/tsconfig": "^0.5.1",
+ "jsdom": "^24.0.0",
+ "npm-run-all2": "^6.1.2",
+ "typescript": "~5.3.0",
+ "vite": "^5.0.11",
+ "vitest": "^1.2.2",
+ "vue-tsc": "^1.8.27"
+ }
+}
diff --git a/playground/typescript-vitest-playwright/playwright.config.ts b/playground/typescript-vitest-playwright/playwright.config.ts
new file mode 100644
index 000000000..92075cc1b
--- /dev/null
+++ b/playground/typescript-vitest-playwright/playwright.config.ts
@@ -0,0 +1,110 @@
+import process from 'node:process'
+import { defineConfig, devices } from '@playwright/test'
+
+/**
+ * Read environment variables from file.
+ * https://github.com/motdotla/dotenv
+ */
+// require('dotenv').config();
+
+/**
+ * See https://playwright.dev/docs/test-configuration.
+ */
+export default defineConfig({
+ testDir: './e2e',
+ /* Maximum time one test can run for. */
+ timeout: 30 * 1000,
+ expect: {
+ /**
+ * Maximum time expect() should wait for the condition to be met.
+ * For example in `await expect(locator).toHaveText();`
+ */
+ timeout: 5000
+ },
+ /* Fail the build on CI if you accidentally left test.only in the source code. */
+ forbidOnly: !!process.env.CI,
+ /* Retry on CI only */
+ retries: process.env.CI ? 2 : 0,
+ /* Opt out of parallel tests on CI. */
+ workers: process.env.CI ? 1 : undefined,
+ /* Reporter to use. See https://playwright.dev/docs/test-reporters */
+ reporter: 'html',
+ /* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
+ use: {
+ /* Maximum time each action such as `click()` can take. Defaults to 0 (no limit). */
+ actionTimeout: 0,
+ /* Base URL to use in actions like `await page.goto('/')`. */
+ baseURL: 'http://localhost:5173',
+
+ /* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
+ trace: 'on-first-retry',
+
+ /* Only on CI systems run the tests headless */
+ headless: !!process.env.CI
+ },
+
+ /* Configure projects for major browsers */
+ projects: [
+ {
+ name: 'chromium',
+ use: {
+ ...devices['Desktop Chrome']
+ }
+ },
+ {
+ name: 'firefox',
+ use: {
+ ...devices['Desktop Firefox']
+ }
+ },
+ {
+ name: 'webkit',
+ use: {
+ ...devices['Desktop Safari']
+ }
+ }
+
+ /* Test against mobile viewports. */
+ // {
+ // name: 'Mobile Chrome',
+ // use: {
+ // ...devices['Pixel 5'],
+ // },
+ // },
+ // {
+ // name: 'Mobile Safari',
+ // use: {
+ // ...devices['iPhone 12'],
+ // },
+ // },
+
+ /* Test against branded browsers. */
+ // {
+ // name: 'Microsoft Edge',
+ // use: {
+ // channel: 'msedge',
+ // },
+ // },
+ // {
+ // name: 'Google Chrome',
+ // use: {
+ // channel: 'chrome',
+ // },
+ // },
+ ],
+
+ /* Folder for test artifacts such as screenshots, videos, traces, etc. */
+ // outputDir: 'test-results/',
+
+ /* Run your local dev server before starting the tests */
+ webServer: {
+ /**
+ * Use the dev server by default for faster feedback loop.
+ * Use the preview server on CI for more realistic testing.
+ * Playwright will re-use the local server if there is already a dev-server running.
+ */
+ command: process.env.CI ? 'vite preview --port 5173' : 'vite dev',
+ port: 5173,
+ reuseExistingServer: !process.env.CI
+ }
+})
diff --git a/playground/typescript-vitest-playwright/public/favicon.ico b/playground/typescript-vitest-playwright/public/favicon.ico
new file mode 100644
index 000000000..df36fcfb7
Binary files /dev/null and b/playground/typescript-vitest-playwright/public/favicon.ico differ
diff --git a/playground/typescript-vitest-playwright/src/App.vue b/playground/typescript-vitest-playwright/src/App.vue
new file mode 100644
index 000000000..69f32f91f
--- /dev/null
+++ b/playground/typescript-vitest-playwright/src/App.vue
@@ -0,0 +1,10 @@
+
+ app
+
+
+
+
+
diff --git a/playground/typescript-vitest-playwright/src/assets/logo.svg b/playground/typescript-vitest-playwright/src/assets/logo.svg
new file mode 100644
index 000000000..756566035
--- /dev/null
+++ b/playground/typescript-vitest-playwright/src/assets/logo.svg
@@ -0,0 +1 @@
+
diff --git a/playground/typescript-vitest-playwright/src/assets/main.css b/playground/typescript-vitest-playwright/src/assets/main.css
new file mode 100644
index 000000000..5aadc6ceb
--- /dev/null
+++ b/playground/typescript-vitest-playwright/src/assets/main.css
@@ -0,0 +1,6 @@
+html, body, #app {
+ width: 100%;
+ height: 100%;
+ padding: 0;
+ margin: 0;
+}
diff --git a/playground/typescript-vitest-playwright/src/components/__tests__/HelloWorld.spec.ts b/playground/typescript-vitest-playwright/src/components/__tests__/HelloWorld.spec.ts
new file mode 100644
index 000000000..253320200
--- /dev/null
+++ b/playground/typescript-vitest-playwright/src/components/__tests__/HelloWorld.spec.ts
@@ -0,0 +1,11 @@
+import { describe, it, expect } from 'vitest'
+
+import { mount } from '@vue/test-utils'
+import HelloWorld from '../HelloWorld.vue'
+
+describe('HelloWorld', () => {
+ it('renders properly', () => {
+ const wrapper = mount(HelloWorld, { props: { msg: 'Hello Vitest' } })
+ expect(wrapper.text()).toContain('Hello Vitest')
+ })
+})
diff --git a/playground/typescript-vitest-playwright/src/main.ts b/playground/typescript-vitest-playwright/src/main.ts
new file mode 100644
index 000000000..0ac3a5ff0
--- /dev/null
+++ b/playground/typescript-vitest-playwright/src/main.ts
@@ -0,0 +1,6 @@
+import './assets/main.css'
+
+import { createApp } from 'vue'
+import App from './App.vue'
+
+createApp(App).mount('#app')
diff --git a/playground/typescript-vitest-playwright/tsconfig.app.json b/playground/typescript-vitest-playwright/tsconfig.app.json
new file mode 100644
index 000000000..e14c754d3
--- /dev/null
+++ b/playground/typescript-vitest-playwright/tsconfig.app.json
@@ -0,0 +1,14 @@
+{
+ "extends": "@vue/tsconfig/tsconfig.dom.json",
+ "include": ["env.d.ts", "src/**/*", "src/**/*.vue"],
+ "exclude": ["src/**/__tests__/*"],
+ "compilerOptions": {
+ "composite": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
+
+ "baseUrl": ".",
+ "paths": {
+ "@/*": ["./src/*"]
+ }
+ }
+}
diff --git a/playground/typescript-vitest-playwright/tsconfig.json b/playground/typescript-vitest-playwright/tsconfig.json
new file mode 100644
index 000000000..100cf6a8f
--- /dev/null
+++ b/playground/typescript-vitest-playwright/tsconfig.json
@@ -0,0 +1,14 @@
+{
+ "files": [],
+ "references": [
+ {
+ "path": "./tsconfig.node.json"
+ },
+ {
+ "path": "./tsconfig.app.json"
+ },
+ {
+ "path": "./tsconfig.vitest.json"
+ }
+ ]
+}
diff --git a/playground/typescript-vitest-playwright/tsconfig.node.json b/playground/typescript-vitest-playwright/tsconfig.node.json
new file mode 100644
index 000000000..f09406303
--- /dev/null
+++ b/playground/typescript-vitest-playwright/tsconfig.node.json
@@ -0,0 +1,19 @@
+{
+ "extends": "@tsconfig/node20/tsconfig.json",
+ "include": [
+ "vite.config.*",
+ "vitest.config.*",
+ "cypress.config.*",
+ "nightwatch.conf.*",
+ "playwright.config.*"
+ ],
+ "compilerOptions": {
+ "composite": true,
+ "noEmit": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
+
+ "module": "ESNext",
+ "moduleResolution": "Bundler",
+ "types": ["node"]
+ }
+}
diff --git a/playground/typescript-vitest-playwright/tsconfig.vitest.json b/playground/typescript-vitest-playwright/tsconfig.vitest.json
new file mode 100644
index 000000000..571995d11
--- /dev/null
+++ b/playground/typescript-vitest-playwright/tsconfig.vitest.json
@@ -0,0 +1,11 @@
+{
+ "extends": "./tsconfig.app.json",
+ "exclude": [],
+ "compilerOptions": {
+ "composite": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.vitest.tsbuildinfo",
+
+ "lib": [],
+ "types": ["node", "jsdom"]
+ }
+}
diff --git a/playground/typescript-vitest-playwright/vite.config.ts b/playground/typescript-vitest-playwright/vite.config.ts
new file mode 100644
index 000000000..5c45e1d9b
--- /dev/null
+++ b/playground/typescript-vitest-playwright/vite.config.ts
@@ -0,0 +1,16 @@
+import { fileURLToPath, URL } from 'node:url'
+
+import { defineConfig } from 'vite'
+import vue from '@vitejs/plugin-vue'
+
+// https://vitejs.dev/config/
+export default defineConfig({
+ plugins: [
+ vue(),
+ ],
+ resolve: {
+ alias: {
+ '@': fileURLToPath(new URL('./src', import.meta.url))
+ }
+ }
+})
diff --git a/playground/typescript-vitest-playwright/vitest.config.ts b/playground/typescript-vitest-playwright/vitest.config.ts
new file mode 100644
index 000000000..10067d578
--- /dev/null
+++ b/playground/typescript-vitest-playwright/vitest.config.ts
@@ -0,0 +1,14 @@
+import { fileURLToPath } from 'node:url'
+import { mergeConfig, defineConfig, configDefaults } from 'vitest/config'
+import viteConfig from './vite.config'
+
+export default mergeConfig(
+ viteConfig,
+ defineConfig({
+ test: {
+ environment: 'jsdom',
+ exclude: [...configDefaults.exclude, 'e2e/*'],
+ root: fileURLToPath(new URL('./', import.meta.url))
+ }
+ })
+)
diff --git a/playground/typescript-vitest/.gitignore b/playground/typescript-vitest/.gitignore
new file mode 100644
index 000000000..8ee54e8d3
--- /dev/null
+++ b/playground/typescript-vitest/.gitignore
@@ -0,0 +1,30 @@
+# 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/
+
+# Editor directories and files
+.vscode/*
+!.vscode/extensions.json
+.idea
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?
+
+*.tsbuildinfo
diff --git a/playground/typescript-vitest/README.md b/playground/typescript-vitest/README.md
new file mode 100644
index 000000000..1a8cd39b1
--- /dev/null
+++ b/playground/typescript-vitest/README.md
@@ -0,0 +1,46 @@
+# typescript-vitest
+
+This template should help get you started developing with Vue 3 in Vite.
+
+## Recommended IDE Setup
+
+[VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur) + [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin).
+
+## Type Support for `.vue` Imports in TS
+
+TypeScript cannot handle type information for `.vue` imports by default, so we replace the `tsc` CLI with `vue-tsc` for type checking. In editors, we need [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin) to make the TypeScript language service aware of `.vue` types.
+
+If the standalone TypeScript plugin doesn't feel fast enough to you, Volar has also implemented a [Take Over Mode](https://github.com/johnsoncodehk/volar/discussions/471#discussioncomment-1361669) that is more performant. You can enable it by the following steps:
+
+1. Disable the built-in TypeScript Extension
+ 1) Run `Extensions: Show Built-in Extensions` from VSCode's command palette
+ 2) Find `TypeScript and JavaScript Language Features`, right click and select `Disable (Workspace)`
+2. Reload the VSCode window by running `Developer: Reload Window` from the command palette.
+
+## Customize configuration
+
+See [Vite Configuration Reference](https://vitejs.dev/config/).
+
+## Project Setup
+
+```sh
+pnpm install
+```
+
+### Compile and Hot-Reload for Development
+
+```sh
+pnpm dev
+```
+
+### Type-Check, Compile and Minify for Production
+
+```sh
+pnpm build
+```
+
+### Run Unit Tests with [Vitest](https://vitest.dev/)
+
+```sh
+pnpm test:unit
+```
diff --git a/playground/typescript-vitest/env.d.ts b/playground/typescript-vitest/env.d.ts
new file mode 100644
index 000000000..11f02fe2a
--- /dev/null
+++ b/playground/typescript-vitest/env.d.ts
@@ -0,0 +1 @@
+///
diff --git a/playground/typescript-vitest/index.html b/playground/typescript-vitest/index.html
new file mode 100644
index 000000000..a88854489
--- /dev/null
+++ b/playground/typescript-vitest/index.html
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+ Vite App
+
+
+
+
+
+
diff --git a/playground/typescript-vitest/package.json b/playground/typescript-vitest/package.json
new file mode 100644
index 000000000..7fe9c424b
--- /dev/null
+++ b/playground/typescript-vitest/package.json
@@ -0,0 +1,31 @@
+{
+ "name": "typescript-vitest",
+ "version": "0.0.0",
+ "private": true,
+ "type": "module",
+ "scripts": {
+ "dev": "vite",
+ "build": "run-p type-check \"build-only {@}\" --",
+ "preview": "vite preview",
+ "test:unit": "vitest",
+ "build-only": "vite build",
+ "type-check": "vue-tsc --build --force"
+ },
+ "dependencies": {
+ "vue": "^3.4.15"
+ },
+ "devDependencies": {
+ "@tsconfig/node20": "^20.1.2",
+ "@types/jsdom": "^21.1.6",
+ "@types/node": "^20.11.16",
+ "@vitejs/plugin-vue": "^5.0.3",
+ "@vue/test-utils": "^2.4.4",
+ "@vue/tsconfig": "^0.5.1",
+ "jsdom": "^24.0.0",
+ "npm-run-all2": "^6.1.2",
+ "typescript": "~5.3.0",
+ "vite": "^5.0.11",
+ "vitest": "^1.2.2",
+ "vue-tsc": "^1.8.27"
+ }
+}
diff --git a/playground/typescript-vitest/public/favicon.ico b/playground/typescript-vitest/public/favicon.ico
new file mode 100644
index 000000000..df36fcfb7
Binary files /dev/null and b/playground/typescript-vitest/public/favicon.ico differ
diff --git a/playground/typescript-vitest/src/App.vue b/playground/typescript-vitest/src/App.vue
new file mode 100644
index 000000000..69f32f91f
--- /dev/null
+++ b/playground/typescript-vitest/src/App.vue
@@ -0,0 +1,10 @@
+
+ app
+
+
+
+
+
diff --git a/playground/typescript-vitest/src/assets/logo.svg b/playground/typescript-vitest/src/assets/logo.svg
new file mode 100644
index 000000000..756566035
--- /dev/null
+++ b/playground/typescript-vitest/src/assets/logo.svg
@@ -0,0 +1 @@
+
diff --git a/playground/typescript-vitest/src/assets/main.css b/playground/typescript-vitest/src/assets/main.css
new file mode 100644
index 000000000..5aadc6ceb
--- /dev/null
+++ b/playground/typescript-vitest/src/assets/main.css
@@ -0,0 +1,6 @@
+html, body, #app {
+ width: 100%;
+ height: 100%;
+ padding: 0;
+ margin: 0;
+}
diff --git a/playground/typescript-vitest/src/components/__tests__/HelloWorld.spec.ts b/playground/typescript-vitest/src/components/__tests__/HelloWorld.spec.ts
new file mode 100644
index 000000000..253320200
--- /dev/null
+++ b/playground/typescript-vitest/src/components/__tests__/HelloWorld.spec.ts
@@ -0,0 +1,11 @@
+import { describe, it, expect } from 'vitest'
+
+import { mount } from '@vue/test-utils'
+import HelloWorld from '../HelloWorld.vue'
+
+describe('HelloWorld', () => {
+ it('renders properly', () => {
+ const wrapper = mount(HelloWorld, { props: { msg: 'Hello Vitest' } })
+ expect(wrapper.text()).toContain('Hello Vitest')
+ })
+})
diff --git a/playground/typescript-vitest/src/main.ts b/playground/typescript-vitest/src/main.ts
new file mode 100644
index 000000000..0ac3a5ff0
--- /dev/null
+++ b/playground/typescript-vitest/src/main.ts
@@ -0,0 +1,6 @@
+import './assets/main.css'
+
+import { createApp } from 'vue'
+import App from './App.vue'
+
+createApp(App).mount('#app')
diff --git a/playground/typescript-vitest/tsconfig.app.json b/playground/typescript-vitest/tsconfig.app.json
new file mode 100644
index 000000000..e14c754d3
--- /dev/null
+++ b/playground/typescript-vitest/tsconfig.app.json
@@ -0,0 +1,14 @@
+{
+ "extends": "@vue/tsconfig/tsconfig.dom.json",
+ "include": ["env.d.ts", "src/**/*", "src/**/*.vue"],
+ "exclude": ["src/**/__tests__/*"],
+ "compilerOptions": {
+ "composite": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
+
+ "baseUrl": ".",
+ "paths": {
+ "@/*": ["./src/*"]
+ }
+ }
+}
diff --git a/playground/typescript-vitest/tsconfig.json b/playground/typescript-vitest/tsconfig.json
new file mode 100644
index 000000000..100cf6a8f
--- /dev/null
+++ b/playground/typescript-vitest/tsconfig.json
@@ -0,0 +1,14 @@
+{
+ "files": [],
+ "references": [
+ {
+ "path": "./tsconfig.node.json"
+ },
+ {
+ "path": "./tsconfig.app.json"
+ },
+ {
+ "path": "./tsconfig.vitest.json"
+ }
+ ]
+}
diff --git a/playground/typescript-vitest/tsconfig.node.json b/playground/typescript-vitest/tsconfig.node.json
new file mode 100644
index 000000000..f09406303
--- /dev/null
+++ b/playground/typescript-vitest/tsconfig.node.json
@@ -0,0 +1,19 @@
+{
+ "extends": "@tsconfig/node20/tsconfig.json",
+ "include": [
+ "vite.config.*",
+ "vitest.config.*",
+ "cypress.config.*",
+ "nightwatch.conf.*",
+ "playwright.config.*"
+ ],
+ "compilerOptions": {
+ "composite": true,
+ "noEmit": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
+
+ "module": "ESNext",
+ "moduleResolution": "Bundler",
+ "types": ["node"]
+ }
+}
diff --git a/playground/typescript-vitest/tsconfig.vitest.json b/playground/typescript-vitest/tsconfig.vitest.json
new file mode 100644
index 000000000..571995d11
--- /dev/null
+++ b/playground/typescript-vitest/tsconfig.vitest.json
@@ -0,0 +1,11 @@
+{
+ "extends": "./tsconfig.app.json",
+ "exclude": [],
+ "compilerOptions": {
+ "composite": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.vitest.tsbuildinfo",
+
+ "lib": [],
+ "types": ["node", "jsdom"]
+ }
+}
diff --git a/playground/typescript-vitest/vite.config.ts b/playground/typescript-vitest/vite.config.ts
new file mode 100644
index 000000000..5c45e1d9b
--- /dev/null
+++ b/playground/typescript-vitest/vite.config.ts
@@ -0,0 +1,16 @@
+import { fileURLToPath, URL } from 'node:url'
+
+import { defineConfig } from 'vite'
+import vue from '@vitejs/plugin-vue'
+
+// https://vitejs.dev/config/
+export default defineConfig({
+ plugins: [
+ vue(),
+ ],
+ resolve: {
+ alias: {
+ '@': fileURLToPath(new URL('./src', import.meta.url))
+ }
+ }
+})
diff --git a/playground/typescript-vitest/vitest.config.ts b/playground/typescript-vitest/vitest.config.ts
new file mode 100644
index 000000000..10067d578
--- /dev/null
+++ b/playground/typescript-vitest/vitest.config.ts
@@ -0,0 +1,14 @@
+import { fileURLToPath } from 'node:url'
+import { mergeConfig, defineConfig, configDefaults } from 'vitest/config'
+import viteConfig from './vite.config'
+
+export default mergeConfig(
+ viteConfig,
+ defineConfig({
+ test: {
+ environment: 'jsdom',
+ exclude: [...configDefaults.exclude, 'e2e/*'],
+ root: fileURLToPath(new URL('./', import.meta.url))
+ }
+ })
+)
diff --git a/playground/typescript-with-tests/.gitignore b/playground/typescript-with-tests/.gitignore
new file mode 100644
index 000000000..8ee54e8d3
--- /dev/null
+++ b/playground/typescript-with-tests/.gitignore
@@ -0,0 +1,30 @@
+# 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/
+
+# Editor directories and files
+.vscode/*
+!.vscode/extensions.json
+.idea
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?
+
+*.tsbuildinfo
diff --git a/playground/typescript-with-tests/README.md b/playground/typescript-with-tests/README.md
new file mode 100644
index 000000000..feca9e189
--- /dev/null
+++ b/playground/typescript-with-tests/README.md
@@ -0,0 +1,62 @@
+# typescript-with-tests
+
+This template should help get you started developing with Vue 3 in Vite.
+
+## Recommended IDE Setup
+
+[VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur) + [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin).
+
+## Type Support for `.vue` Imports in TS
+
+TypeScript cannot handle type information for `.vue` imports by default, so we replace the `tsc` CLI with `vue-tsc` for type checking. In editors, we need [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin) to make the TypeScript language service aware of `.vue` types.
+
+If the standalone TypeScript plugin doesn't feel fast enough to you, Volar has also implemented a [Take Over Mode](https://github.com/johnsoncodehk/volar/discussions/471#discussioncomment-1361669) that is more performant. You can enable it by the following steps:
+
+1. Disable the built-in TypeScript Extension
+ 1) Run `Extensions: Show Built-in Extensions` from VSCode's command palette
+ 2) Find `TypeScript and JavaScript Language Features`, right click and select `Disable (Workspace)`
+2. Reload the VSCode window by running `Developer: Reload Window` from the command palette.
+
+## Customize configuration
+
+See [Vite Configuration Reference](https://vitejs.dev/config/).
+
+## Project Setup
+
+```sh
+pnpm install
+```
+
+### Compile and Hot-Reload for Development
+
+```sh
+pnpm dev
+```
+
+### Type-Check, Compile and Minify for Production
+
+```sh
+pnpm build
+```
+
+### Run Unit Tests with [Vitest](https://vitest.dev/)
+
+```sh
+pnpm test:unit
+```
+
+### Run End-to-End Tests with [Cypress](https://www.cypress.io/)
+
+```sh
+pnpm test:e2e:dev
+```
+
+This runs the end-to-end tests against the Vite development server.
+It is much faster than the production build.
+
+But it's still recommended to test the production build with `test:e2e` before deploying (e.g. in CI environments):
+
+```sh
+pnpm build
+pnpm test:e2e
+```
diff --git a/playground/typescript-with-tests/cypress.config.ts b/playground/typescript-with-tests/cypress.config.ts
new file mode 100644
index 000000000..0f66080fd
--- /dev/null
+++ b/playground/typescript-with-tests/cypress.config.ts
@@ -0,0 +1,8 @@
+import { defineConfig } from 'cypress'
+
+export default defineConfig({
+ e2e: {
+ specPattern: 'cypress/e2e/**/*.{cy,spec}.{js,jsx,ts,tsx}',
+ baseUrl: 'http://localhost:4173'
+ }
+})
diff --git a/playground/typescript-with-tests/cypress/e2e/example.cy.ts b/playground/typescript-with-tests/cypress/e2e/example.cy.ts
new file mode 100644
index 000000000..7554c35d8
--- /dev/null
+++ b/playground/typescript-with-tests/cypress/e2e/example.cy.ts
@@ -0,0 +1,8 @@
+// https://on.cypress.io/api
+
+describe('My First Test', () => {
+ it('visits the app root url', () => {
+ cy.visit('/')
+ cy.contains('h1', 'You did it!')
+ })
+})
diff --git a/playground/typescript-with-tests/cypress/e2e/tsconfig.json b/playground/typescript-with-tests/cypress/e2e/tsconfig.json
new file mode 100644
index 000000000..37748feb7
--- /dev/null
+++ b/playground/typescript-with-tests/cypress/e2e/tsconfig.json
@@ -0,0 +1,10 @@
+{
+ "extends": "@vue/tsconfig/tsconfig.dom.json",
+ "include": ["./**/*", "../support/**/*"],
+ "compilerOptions": {
+ "isolatedModules": false,
+ "target": "es5",
+ "lib": ["es5", "dom"],
+ "types": ["cypress"]
+ }
+}
diff --git a/playground/typescript-with-tests/cypress/fixtures/example.json b/playground/typescript-with-tests/cypress/fixtures/example.json
new file mode 100644
index 000000000..02e425437
--- /dev/null
+++ b/playground/typescript-with-tests/cypress/fixtures/example.json
@@ -0,0 +1,5 @@
+{
+ "name": "Using fixtures to represent data",
+ "email": "hello@cypress.io",
+ "body": "Fixtures are a great way to mock data for responses to routes"
+}
diff --git a/playground/typescript-with-tests/cypress/support/commands.ts b/playground/typescript-with-tests/cypress/support/commands.ts
new file mode 100644
index 000000000..9b7bb8e25
--- /dev/null
+++ b/playground/typescript-with-tests/cypress/support/commands.ts
@@ -0,0 +1,39 @@
+///
+// ***********************************************
+// This example commands.ts shows you how to
+// create various custom commands and overwrite
+// existing commands.
+//
+// For more comprehensive examples of custom
+// commands please read more here:
+// https://on.cypress.io/custom-commands
+// ***********************************************
+//
+//
+// -- This is a parent command --
+// Cypress.Commands.add('login', (email, password) => { ... })
+//
+//
+// -- This is a child command --
+// Cypress.Commands.add('drag', { prevSubject: 'element'}, (subject, options) => { ... })
+//
+//
+// -- This is a dual command --
+// Cypress.Commands.add('dismiss', { prevSubject: 'optional'}, (subject, options) => { ... })
+//
+//
+// -- This will overwrite an existing command --
+// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... })
+//
+// declare global {
+// namespace Cypress {
+// interface Chainable {
+// login(email: string, password: string): Chainable
+// drag(subject: string, options?: Partial): Chainable
+// dismiss(subject: string, options?: Partial): Chainable
+// visit(originalFn: CommandOriginalFn, url: string, options: Partial): Chainable
+// }
+// }
+// }
+
+export {}
diff --git a/playground/typescript-with-tests/cypress/support/e2e.ts b/playground/typescript-with-tests/cypress/support/e2e.ts
new file mode 100644
index 000000000..d68db96df
--- /dev/null
+++ b/playground/typescript-with-tests/cypress/support/e2e.ts
@@ -0,0 +1,20 @@
+// ***********************************************************
+// This example support/index.js is processed and
+// loaded automatically before your test files.
+//
+// This is a great place to put global configuration and
+// behavior that modifies Cypress.
+//
+// You can change the location of this file or turn off
+// automatically serving support files with the
+// 'supportFile' configuration option.
+//
+// You can read more here:
+// https://on.cypress.io/configuration
+// ***********************************************************
+
+// Import commands.js using ES2015 syntax:
+import './commands'
+
+// Alternatively you can use CommonJS syntax:
+// require('./commands')
diff --git a/playground/typescript-with-tests/env.d.ts b/playground/typescript-with-tests/env.d.ts
new file mode 100644
index 000000000..11f02fe2a
--- /dev/null
+++ b/playground/typescript-with-tests/env.d.ts
@@ -0,0 +1 @@
+///
diff --git a/playground/typescript-with-tests/index.html b/playground/typescript-with-tests/index.html
new file mode 100644
index 000000000..a88854489
--- /dev/null
+++ b/playground/typescript-with-tests/index.html
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+ Vite App
+
+
+
+
+
+
diff --git a/playground/typescript-with-tests/package.json b/playground/typescript-with-tests/package.json
new file mode 100644
index 000000000..abc144c37
--- /dev/null
+++ b/playground/typescript-with-tests/package.json
@@ -0,0 +1,35 @@
+{
+ "name": "typescript-with-tests",
+ "version": "0.0.0",
+ "private": true,
+ "type": "module",
+ "scripts": {
+ "dev": "vite",
+ "build": "run-p type-check \"build-only {@}\" --",
+ "preview": "vite preview",
+ "test:unit": "vitest",
+ "test:e2e": "start-server-and-test preview http://localhost:4173 'cypress run --e2e'",
+ "test:e2e:dev": "start-server-and-test 'vite dev --port 4173' http://localhost:4173 'cypress open --e2e'",
+ "build-only": "vite build",
+ "type-check": "vue-tsc --build --force"
+ },
+ "dependencies": {
+ "vue": "^3.4.15"
+ },
+ "devDependencies": {
+ "@tsconfig/node20": "^20.1.2",
+ "@types/jsdom": "^21.1.6",
+ "@types/node": "^20.11.16",
+ "@vitejs/plugin-vue": "^5.0.3",
+ "@vue/test-utils": "^2.4.4",
+ "@vue/tsconfig": "^0.5.1",
+ "cypress": "^13.6.4",
+ "jsdom": "^24.0.0",
+ "npm-run-all2": "^6.1.2",
+ "start-server-and-test": "^2.0.3",
+ "typescript": "~5.3.0",
+ "vite": "^5.0.11",
+ "vitest": "^1.2.2",
+ "vue-tsc": "^1.8.27"
+ }
+}
diff --git a/playground/typescript-with-tests/public/favicon.ico b/playground/typescript-with-tests/public/favicon.ico
new file mode 100644
index 000000000..df36fcfb7
Binary files /dev/null and b/playground/typescript-with-tests/public/favicon.ico differ
diff --git a/playground/typescript-with-tests/src/App.vue b/playground/typescript-with-tests/src/App.vue
new file mode 100644
index 000000000..69f32f91f
--- /dev/null
+++ b/playground/typescript-with-tests/src/App.vue
@@ -0,0 +1,10 @@
+
+ app
+
+
+
+
+
diff --git a/playground/typescript-with-tests/src/assets/logo.svg b/playground/typescript-with-tests/src/assets/logo.svg
new file mode 100644
index 000000000..756566035
--- /dev/null
+++ b/playground/typescript-with-tests/src/assets/logo.svg
@@ -0,0 +1 @@
+
diff --git a/playground/typescript-with-tests/src/assets/main.css b/playground/typescript-with-tests/src/assets/main.css
new file mode 100644
index 000000000..5aadc6ceb
--- /dev/null
+++ b/playground/typescript-with-tests/src/assets/main.css
@@ -0,0 +1,6 @@
+html, body, #app {
+ width: 100%;
+ height: 100%;
+ padding: 0;
+ margin: 0;
+}
diff --git a/playground/typescript-with-tests/src/components/__tests__/HelloWorld.spec.ts b/playground/typescript-with-tests/src/components/__tests__/HelloWorld.spec.ts
new file mode 100644
index 000000000..253320200
--- /dev/null
+++ b/playground/typescript-with-tests/src/components/__tests__/HelloWorld.spec.ts
@@ -0,0 +1,11 @@
+import { describe, it, expect } from 'vitest'
+
+import { mount } from '@vue/test-utils'
+import HelloWorld from '../HelloWorld.vue'
+
+describe('HelloWorld', () => {
+ it('renders properly', () => {
+ const wrapper = mount(HelloWorld, { props: { msg: 'Hello Vitest' } })
+ expect(wrapper.text()).toContain('Hello Vitest')
+ })
+})
diff --git a/playground/typescript-with-tests/src/main.ts b/playground/typescript-with-tests/src/main.ts
new file mode 100644
index 000000000..0ac3a5ff0
--- /dev/null
+++ b/playground/typescript-with-tests/src/main.ts
@@ -0,0 +1,6 @@
+import './assets/main.css'
+
+import { createApp } from 'vue'
+import App from './App.vue'
+
+createApp(App).mount('#app')
diff --git a/playground/typescript-with-tests/tsconfig.app.json b/playground/typescript-with-tests/tsconfig.app.json
new file mode 100644
index 000000000..e14c754d3
--- /dev/null
+++ b/playground/typescript-with-tests/tsconfig.app.json
@@ -0,0 +1,14 @@
+{
+ "extends": "@vue/tsconfig/tsconfig.dom.json",
+ "include": ["env.d.ts", "src/**/*", "src/**/*.vue"],
+ "exclude": ["src/**/__tests__/*"],
+ "compilerOptions": {
+ "composite": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
+
+ "baseUrl": ".",
+ "paths": {
+ "@/*": ["./src/*"]
+ }
+ }
+}
diff --git a/playground/typescript-with-tests/tsconfig.json b/playground/typescript-with-tests/tsconfig.json
new file mode 100644
index 000000000..5304731b8
--- /dev/null
+++ b/playground/typescript-with-tests/tsconfig.json
@@ -0,0 +1,17 @@
+{
+ "files": [],
+ "references": [
+ {
+ "path": "./tsconfig.node.json"
+ },
+ {
+ "path": "./tsconfig.app.json"
+ },
+ {
+ "path": "./tsconfig.vitest.json"
+ }
+ ],
+ "compilerOptions": {
+ "module": "NodeNext"
+ }
+}
diff --git a/playground/typescript-with-tests/tsconfig.node.json b/playground/typescript-with-tests/tsconfig.node.json
new file mode 100644
index 000000000..f09406303
--- /dev/null
+++ b/playground/typescript-with-tests/tsconfig.node.json
@@ -0,0 +1,19 @@
+{
+ "extends": "@tsconfig/node20/tsconfig.json",
+ "include": [
+ "vite.config.*",
+ "vitest.config.*",
+ "cypress.config.*",
+ "nightwatch.conf.*",
+ "playwright.config.*"
+ ],
+ "compilerOptions": {
+ "composite": true,
+ "noEmit": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
+
+ "module": "ESNext",
+ "moduleResolution": "Bundler",
+ "types": ["node"]
+ }
+}
diff --git a/playground/typescript-with-tests/tsconfig.vitest.json b/playground/typescript-with-tests/tsconfig.vitest.json
new file mode 100644
index 000000000..571995d11
--- /dev/null
+++ b/playground/typescript-with-tests/tsconfig.vitest.json
@@ -0,0 +1,11 @@
+{
+ "extends": "./tsconfig.app.json",
+ "exclude": [],
+ "compilerOptions": {
+ "composite": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.vitest.tsbuildinfo",
+
+ "lib": [],
+ "types": ["node", "jsdom"]
+ }
+}
diff --git a/playground/typescript-with-tests/vite.config.ts b/playground/typescript-with-tests/vite.config.ts
new file mode 100644
index 000000000..5c45e1d9b
--- /dev/null
+++ b/playground/typescript-with-tests/vite.config.ts
@@ -0,0 +1,16 @@
+import { fileURLToPath, URL } from 'node:url'
+
+import { defineConfig } from 'vite'
+import vue from '@vitejs/plugin-vue'
+
+// https://vitejs.dev/config/
+export default defineConfig({
+ plugins: [
+ vue(),
+ ],
+ resolve: {
+ alias: {
+ '@': fileURLToPath(new URL('./src', import.meta.url))
+ }
+ }
+})
diff --git a/playground/typescript-with-tests/vitest.config.ts b/playground/typescript-with-tests/vitest.config.ts
new file mode 100644
index 000000000..10067d578
--- /dev/null
+++ b/playground/typescript-with-tests/vitest.config.ts
@@ -0,0 +1,14 @@
+import { fileURLToPath } from 'node:url'
+import { mergeConfig, defineConfig, configDefaults } from 'vitest/config'
+import viteConfig from './vite.config'
+
+export default mergeConfig(
+ viteConfig,
+ defineConfig({
+ test: {
+ environment: 'jsdom',
+ exclude: [...configDefaults.exclude, 'e2e/*'],
+ root: fileURLToPath(new URL('./', import.meta.url))
+ }
+ })
+)
diff --git a/playground/typescript/.gitignore b/playground/typescript/.gitignore
new file mode 100644
index 000000000..8ee54e8d3
--- /dev/null
+++ b/playground/typescript/.gitignore
@@ -0,0 +1,30 @@
+# 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/
+
+# Editor directories and files
+.vscode/*
+!.vscode/extensions.json
+.idea
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?
+
+*.tsbuildinfo
diff --git a/playground/typescript/README.md b/playground/typescript/README.md
new file mode 100644
index 000000000..734ce2d16
--- /dev/null
+++ b/playground/typescript/README.md
@@ -0,0 +1,40 @@
+# typescript
+
+This template should help get you started developing with Vue 3 in Vite.
+
+## Recommended IDE Setup
+
+[VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur) + [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin).
+
+## Type Support for `.vue` Imports in TS
+
+TypeScript cannot handle type information for `.vue` imports by default, so we replace the `tsc` CLI with `vue-tsc` for type checking. In editors, we need [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin) to make the TypeScript language service aware of `.vue` types.
+
+If the standalone TypeScript plugin doesn't feel fast enough to you, Volar has also implemented a [Take Over Mode](https://github.com/johnsoncodehk/volar/discussions/471#discussioncomment-1361669) that is more performant. You can enable it by the following steps:
+
+1. Disable the built-in TypeScript Extension
+ 1) Run `Extensions: Show Built-in Extensions` from VSCode's command palette
+ 2) Find `TypeScript and JavaScript Language Features`, right click and select `Disable (Workspace)`
+2. Reload the VSCode window by running `Developer: Reload Window` from the command palette.
+
+## Customize configuration
+
+See [Vite Configuration Reference](https://vitejs.dev/config/).
+
+## Project Setup
+
+```sh
+pnpm install
+```
+
+### Compile and Hot-Reload for Development
+
+```sh
+pnpm dev
+```
+
+### Type-Check, Compile and Minify for Production
+
+```sh
+pnpm build
+```
diff --git a/playground/typescript/env.d.ts b/playground/typescript/env.d.ts
new file mode 100644
index 000000000..11f02fe2a
--- /dev/null
+++ b/playground/typescript/env.d.ts
@@ -0,0 +1 @@
+///
diff --git a/playground/typescript/index.html b/playground/typescript/index.html
new file mode 100644
index 000000000..a88854489
--- /dev/null
+++ b/playground/typescript/index.html
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+ Vite App
+
+
+
+
+
+
diff --git a/playground/typescript/package.json b/playground/typescript/package.json
new file mode 100644
index 000000000..bf0b73354
--- /dev/null
+++ b/playground/typescript/package.json
@@ -0,0 +1,26 @@
+{
+ "name": "typescript",
+ "version": "0.0.0",
+ "private": true,
+ "type": "module",
+ "scripts": {
+ "dev": "vite",
+ "build": "run-p type-check \"build-only {@}\" --",
+ "preview": "vite preview",
+ "build-only": "vite build",
+ "type-check": "vue-tsc --build --force"
+ },
+ "dependencies": {
+ "vue": "^3.4.15"
+ },
+ "devDependencies": {
+ "@tsconfig/node20": "^20.1.2",
+ "@types/node": "^20.11.16",
+ "@vitejs/plugin-vue": "^5.0.3",
+ "@vue/tsconfig": "^0.5.1",
+ "npm-run-all2": "^6.1.2",
+ "typescript": "~5.3.0",
+ "vite": "^5.0.11",
+ "vue-tsc": "^1.8.27"
+ }
+}
diff --git a/playground/typescript/public/favicon.ico b/playground/typescript/public/favicon.ico
new file mode 100644
index 000000000..df36fcfb7
Binary files /dev/null and b/playground/typescript/public/favicon.ico differ
diff --git a/playground/typescript/src/App.vue b/playground/typescript/src/App.vue
new file mode 100644
index 000000000..69f32f91f
--- /dev/null
+++ b/playground/typescript/src/App.vue
@@ -0,0 +1,10 @@
+
+ app
+
+
+
+
+
diff --git a/playground/typescript/src/assets/logo.svg b/playground/typescript/src/assets/logo.svg
new file mode 100644
index 000000000..756566035
--- /dev/null
+++ b/playground/typescript/src/assets/logo.svg
@@ -0,0 +1 @@
+
diff --git a/playground/typescript/src/assets/main.css b/playground/typescript/src/assets/main.css
new file mode 100644
index 000000000..5aadc6ceb
--- /dev/null
+++ b/playground/typescript/src/assets/main.css
@@ -0,0 +1,6 @@
+html, body, #app {
+ width: 100%;
+ height: 100%;
+ padding: 0;
+ margin: 0;
+}
diff --git a/playground/typescript/src/main.ts b/playground/typescript/src/main.ts
new file mode 100644
index 000000000..0ac3a5ff0
--- /dev/null
+++ b/playground/typescript/src/main.ts
@@ -0,0 +1,6 @@
+import './assets/main.css'
+
+import { createApp } from 'vue'
+import App from './App.vue'
+
+createApp(App).mount('#app')
diff --git a/playground/typescript/tsconfig.app.json b/playground/typescript/tsconfig.app.json
new file mode 100644
index 000000000..e14c754d3
--- /dev/null
+++ b/playground/typescript/tsconfig.app.json
@@ -0,0 +1,14 @@
+{
+ "extends": "@vue/tsconfig/tsconfig.dom.json",
+ "include": ["env.d.ts", "src/**/*", "src/**/*.vue"],
+ "exclude": ["src/**/__tests__/*"],
+ "compilerOptions": {
+ "composite": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
+
+ "baseUrl": ".",
+ "paths": {
+ "@/*": ["./src/*"]
+ }
+ }
+}
diff --git a/playground/typescript/tsconfig.json b/playground/typescript/tsconfig.json
new file mode 100644
index 000000000..66b5e5703
--- /dev/null
+++ b/playground/typescript/tsconfig.json
@@ -0,0 +1,11 @@
+{
+ "files": [],
+ "references": [
+ {
+ "path": "./tsconfig.node.json"
+ },
+ {
+ "path": "./tsconfig.app.json"
+ }
+ ]
+}
diff --git a/playground/typescript/tsconfig.node.json b/playground/typescript/tsconfig.node.json
new file mode 100644
index 000000000..f09406303
--- /dev/null
+++ b/playground/typescript/tsconfig.node.json
@@ -0,0 +1,19 @@
+{
+ "extends": "@tsconfig/node20/tsconfig.json",
+ "include": [
+ "vite.config.*",
+ "vitest.config.*",
+ "cypress.config.*",
+ "nightwatch.conf.*",
+ "playwright.config.*"
+ ],
+ "compilerOptions": {
+ "composite": true,
+ "noEmit": true,
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
+
+ "module": "ESNext",
+ "moduleResolution": "Bundler",
+ "types": ["node"]
+ }
+}
diff --git a/playground/typescript/vite.config.ts b/playground/typescript/vite.config.ts
new file mode 100644
index 000000000..5c45e1d9b
--- /dev/null
+++ b/playground/typescript/vite.config.ts
@@ -0,0 +1,16 @@
+import { fileURLToPath, URL } from 'node:url'
+
+import { defineConfig } from 'vite'
+import vue from '@vitejs/plugin-vue'
+
+// https://vitejs.dev/config/
+export default defineConfig({
+ plugins: [
+ vue(),
+ ],
+ resolve: {
+ alias: {
+ '@': fileURLToPath(new URL('./src', import.meta.url))
+ }
+ }
+})
diff --git a/playground/vitest-cypress/.gitignore b/playground/vitest-cypress/.gitignore
new file mode 100644
index 000000000..8ee54e8d3
--- /dev/null
+++ b/playground/vitest-cypress/.gitignore
@@ -0,0 +1,30 @@
+# 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/
+
+# Editor directories and files
+.vscode/*
+!.vscode/extensions.json
+.idea
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?
+
+*.tsbuildinfo
diff --git a/playground/vitest-cypress/README.md b/playground/vitest-cypress/README.md
new file mode 100644
index 000000000..e02686273
--- /dev/null
+++ b/playground/vitest-cypress/README.md
@@ -0,0 +1,51 @@
+# vitest-cypress
+
+This template should help get you started developing with Vue 3 in Vite.
+
+## Recommended IDE Setup
+
+[VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur) + [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin).
+
+## Customize configuration
+
+See [Vite Configuration Reference](https://vitejs.dev/config/).
+
+## Project Setup
+
+```sh
+pnpm install
+```
+
+### Compile and Hot-Reload for Development
+
+```sh
+pnpm dev
+```
+
+### Compile and Minify for Production
+
+```sh
+pnpm build
+```
+
+### Run Unit Tests with [Vitest](https://vitest.dev/)
+
+```sh
+pnpm test:unit
+```
+
+### Run End-to-End Tests with [Cypress](https://www.cypress.io/)
+
+```sh
+pnpm test:e2e:dev
+```
+
+This runs the end-to-end tests against the Vite development server.
+It is much faster than the production build.
+
+But it's still recommended to test the production build with `test:e2e` before deploying (e.g. in CI environments):
+
+```sh
+pnpm build
+pnpm test:e2e
+```
diff --git a/playground/vitest-cypress/cypress.config.js b/playground/vitest-cypress/cypress.config.js
new file mode 100644
index 000000000..0f66080fd
--- /dev/null
+++ b/playground/vitest-cypress/cypress.config.js
@@ -0,0 +1,8 @@
+import { defineConfig } from 'cypress'
+
+export default defineConfig({
+ e2e: {
+ specPattern: 'cypress/e2e/**/*.{cy,spec}.{js,jsx,ts,tsx}',
+ baseUrl: 'http://localhost:4173'
+ }
+})
diff --git a/playground/vitest-cypress/cypress/e2e/example.cy.js b/playground/vitest-cypress/cypress/e2e/example.cy.js
new file mode 100644
index 000000000..7554c35d8
--- /dev/null
+++ b/playground/vitest-cypress/cypress/e2e/example.cy.js
@@ -0,0 +1,8 @@
+// https://on.cypress.io/api
+
+describe('My First Test', () => {
+ it('visits the app root url', () => {
+ cy.visit('/')
+ cy.contains('h1', 'You did it!')
+ })
+})
diff --git a/playground/vitest-cypress/cypress/e2e/jsconfig.json b/playground/vitest-cypress/cypress/e2e/jsconfig.json
new file mode 100644
index 000000000..c790a70d6
--- /dev/null
+++ b/playground/vitest-cypress/cypress/e2e/jsconfig.json
@@ -0,0 +1,8 @@
+{
+ "compilerOptions": {
+ "target": "es5",
+ "lib": ["es5", "dom"],
+ "types": ["cypress"]
+ },
+ "include": ["./**/*", "../support/**/*"]
+}
diff --git a/playground/vitest-cypress/cypress/fixtures/example.json b/playground/vitest-cypress/cypress/fixtures/example.json
new file mode 100644
index 000000000..02e425437
--- /dev/null
+++ b/playground/vitest-cypress/cypress/fixtures/example.json
@@ -0,0 +1,5 @@
+{
+ "name": "Using fixtures to represent data",
+ "email": "hello@cypress.io",
+ "body": "Fixtures are a great way to mock data for responses to routes"
+}
diff --git a/playground/vitest-cypress/cypress/support/commands.js b/playground/vitest-cypress/cypress/support/commands.js
new file mode 100644
index 000000000..119ab03f7
--- /dev/null
+++ b/playground/vitest-cypress/cypress/support/commands.js
@@ -0,0 +1,25 @@
+// ***********************************************
+// This example commands.js shows you how to
+// create various custom commands and overwrite
+// existing commands.
+//
+// For more comprehensive examples of custom
+// commands please read more here:
+// https://on.cypress.io/custom-commands
+// ***********************************************
+//
+//
+// -- This is a parent command --
+// Cypress.Commands.add('login', (email, password) => { ... })
+//
+//
+// -- This is a child command --
+// Cypress.Commands.add('drag', { prevSubject: 'element'}, (subject, options) => { ... })
+//
+//
+// -- This is a dual command --
+// Cypress.Commands.add('dismiss', { prevSubject: 'optional'}, (subject, options) => { ... })
+//
+//
+// -- This will overwrite an existing command --
+// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... })
diff --git a/playground/vitest-cypress/cypress/support/e2e.js b/playground/vitest-cypress/cypress/support/e2e.js
new file mode 100644
index 000000000..d68db96df
--- /dev/null
+++ b/playground/vitest-cypress/cypress/support/e2e.js
@@ -0,0 +1,20 @@
+// ***********************************************************
+// This example support/index.js is processed and
+// loaded automatically before your test files.
+//
+// This is a great place to put global configuration and
+// behavior that modifies Cypress.
+//
+// You can change the location of this file or turn off
+// automatically serving support files with the
+// 'supportFile' configuration option.
+//
+// You can read more here:
+// https://on.cypress.io/configuration
+// ***********************************************************
+
+// Import commands.js using ES2015 syntax:
+import './commands'
+
+// Alternatively you can use CommonJS syntax:
+// require('./commands')
diff --git a/playground/vitest-cypress/index.html b/playground/vitest-cypress/index.html
new file mode 100644
index 000000000..99f583aa2
--- /dev/null
+++ b/playground/vitest-cypress/index.html
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+ Vite App
+
+
+
+
+
+
diff --git a/playground/vitest-cypress/jsconfig.json b/playground/vitest-cypress/jsconfig.json
new file mode 100644
index 000000000..5a1f2d222
--- /dev/null
+++ b/playground/vitest-cypress/jsconfig.json
@@ -0,0 +1,8 @@
+{
+ "compilerOptions": {
+ "paths": {
+ "@/*": ["./src/*"]
+ }
+ },
+ "exclude": ["node_modules", "dist"]
+}
diff --git a/playground/vitest-cypress/package.json b/playground/vitest-cypress/package.json
new file mode 100644
index 000000000..9aae6fe3d
--- /dev/null
+++ b/playground/vitest-cypress/package.json
@@ -0,0 +1,26 @@
+{
+ "name": "vitest-cypress",
+ "version": "0.0.0",
+ "private": true,
+ "type": "module",
+ "scripts": {
+ "dev": "vite",
+ "build": "vite build",
+ "preview": "vite preview",
+ "test:unit": "vitest",
+ "test:e2e": "start-server-and-test preview http://localhost:4173 'cypress run --e2e'",
+ "test:e2e:dev": "start-server-and-test 'vite dev --port 4173' http://localhost:4173 'cypress open --e2e'"
+ },
+ "dependencies": {
+ "vue": "^3.4.15"
+ },
+ "devDependencies": {
+ "@vitejs/plugin-vue": "^5.0.3",
+ "@vue/test-utils": "^2.4.4",
+ "cypress": "^13.6.4",
+ "jsdom": "^24.0.0",
+ "start-server-and-test": "^2.0.3",
+ "vite": "^5.0.11",
+ "vitest": "^1.2.2"
+ }
+}
diff --git a/playground/vitest-cypress/public/favicon.ico b/playground/vitest-cypress/public/favicon.ico
new file mode 100644
index 000000000..df36fcfb7
Binary files /dev/null and b/playground/vitest-cypress/public/favicon.ico differ
diff --git a/playground/vitest-cypress/src/App.vue b/playground/vitest-cypress/src/App.vue
new file mode 100644
index 000000000..b6f965e35
--- /dev/null
+++ b/playground/vitest-cypress/src/App.vue
@@ -0,0 +1,9 @@
+
+
+
+
+
+
diff --git a/playground/vitest-cypress/src/assets/logo.svg b/playground/vitest-cypress/src/assets/logo.svg
new file mode 100644
index 000000000..756566035
--- /dev/null
+++ b/playground/vitest-cypress/src/assets/logo.svg
@@ -0,0 +1 @@
+
diff --git a/playground/vitest-cypress/src/assets/main.css b/playground/vitest-cypress/src/assets/main.css
new file mode 100644
index 000000000..5aadc6ceb
--- /dev/null
+++ b/playground/vitest-cypress/src/assets/main.css
@@ -0,0 +1,6 @@
+html, body, #app {
+ width: 100%;
+ height: 100%;
+ padding: 0;
+ margin: 0;
+}
diff --git a/playground/vitest-cypress/src/components/__tests__/HelloWorld.spec.js b/playground/vitest-cypress/src/components/__tests__/HelloWorld.spec.js
new file mode 100644
index 000000000..253320200
--- /dev/null
+++ b/playground/vitest-cypress/src/components/__tests__/HelloWorld.spec.js
@@ -0,0 +1,11 @@
+import { describe, it, expect } from 'vitest'
+
+import { mount } from '@vue/test-utils'
+import HelloWorld from '../HelloWorld.vue'
+
+describe('HelloWorld', () => {
+ it('renders properly', () => {
+ const wrapper = mount(HelloWorld, { props: { msg: 'Hello Vitest' } })
+ expect(wrapper.text()).toContain('Hello Vitest')
+ })
+})
diff --git a/playground/vitest-cypress/src/main.js b/playground/vitest-cypress/src/main.js
new file mode 100644
index 000000000..0ac3a5ff0
--- /dev/null
+++ b/playground/vitest-cypress/src/main.js
@@ -0,0 +1,6 @@
+import './assets/main.css'
+
+import { createApp } from 'vue'
+import App from './App.vue'
+
+createApp(App).mount('#app')
diff --git a/playground/vitest-cypress/vite.config.js b/playground/vitest-cypress/vite.config.js
new file mode 100644
index 000000000..5c45e1d9b
--- /dev/null
+++ b/playground/vitest-cypress/vite.config.js
@@ -0,0 +1,16 @@
+import { fileURLToPath, URL } from 'node:url'
+
+import { defineConfig } from 'vite'
+import vue from '@vitejs/plugin-vue'
+
+// https://vitejs.dev/config/
+export default defineConfig({
+ plugins: [
+ vue(),
+ ],
+ resolve: {
+ alias: {
+ '@': fileURLToPath(new URL('./src', import.meta.url))
+ }
+ }
+})
diff --git a/playground/vitest-cypress/vitest.config.js b/playground/vitest-cypress/vitest.config.js
new file mode 100644
index 000000000..10067d578
--- /dev/null
+++ b/playground/vitest-cypress/vitest.config.js
@@ -0,0 +1,14 @@
+import { fileURLToPath } from 'node:url'
+import { mergeConfig, defineConfig, configDefaults } from 'vitest/config'
+import viteConfig from './vite.config'
+
+export default mergeConfig(
+ viteConfig,
+ defineConfig({
+ test: {
+ environment: 'jsdom',
+ exclude: [...configDefaults.exclude, 'e2e/*'],
+ root: fileURLToPath(new URL('./', import.meta.url))
+ }
+ })
+)
diff --git a/playground/vitest-nightwatch/.gitignore b/playground/vitest-nightwatch/.gitignore
new file mode 100644
index 000000000..0b938f131
--- /dev/null
+++ b/playground/vitest-nightwatch/.gitignore
@@ -0,0 +1,33 @@
+# 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/
+
+# Editor directories and files
+.vscode/*
+!.vscode/extensions.json
+.idea
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?
+
+*.tsbuildinfo
+
+logs/
+tests_output/
diff --git a/playground/vitest-nightwatch/.vscode/extensions.json b/playground/vitest-nightwatch/.vscode/extensions.json
new file mode 100644
index 000000000..dd9668a5c
--- /dev/null
+++ b/playground/vitest-nightwatch/.vscode/extensions.json
@@ -0,0 +1,3 @@
+{
+ "recommendations": ["browserstackcom.nightwatch"]
+}
diff --git a/playground/vitest-nightwatch/README.md b/playground/vitest-nightwatch/README.md
new file mode 100644
index 000000000..626767450
--- /dev/null
+++ b/playground/vitest-nightwatch/README.md
@@ -0,0 +1,58 @@
+# vitest-nightwatch
+
+This template should help get you started developing with Vue 3 in Vite.
+
+## Recommended IDE Setup
+
+[VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur) + [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin).
+
+## Customize configuration
+
+See [Vite Configuration Reference](https://vitejs.dev/config/).
+
+## Project Setup
+
+```sh
+pnpm install
+```
+
+### Compile and Hot-Reload for Development
+
+```sh
+pnpm dev
+```
+
+### Compile and Minify for Production
+
+```sh
+pnpm build
+```
+
+### Run Unit Tests with [Vitest](https://vitest.dev/)
+
+```sh
+pnpm test:unit
+```
+
+### Run End-to-End Tests with [Nightwatch](https://nightwatchjs.org/)
+
+```sh
+# When using CI, the project must be built first.
+pnpm build
+
+# Runs the end-to-end tests
+pnpm test:e2e
+# Runs the tests only on Chrome
+pnpm test:e2e --env chrome
+# Runs the tests of a specific file
+pnpm test:e2e tests/e2e/example.js
+# Runs the tests in debug mode
+pnpm test:e2e --debug
+```
+
+### Run Headed Component Tests with [Nightwatch Component Testing](https://nightwatchjs.org/guide/component-testing/introduction.html)
+
+```sh
+pnpm test:unit
+pnpm test:unit -- --headless # for headless testing
+```
diff --git a/playground/vitest-nightwatch/index.html b/playground/vitest-nightwatch/index.html
new file mode 100644
index 000000000..99f583aa2
--- /dev/null
+++ b/playground/vitest-nightwatch/index.html
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+ Vite App
+
+
+
+
+
+
diff --git a/playground/vitest-nightwatch/jsconfig.json b/playground/vitest-nightwatch/jsconfig.json
new file mode 100644
index 000000000..5a1f2d222
--- /dev/null
+++ b/playground/vitest-nightwatch/jsconfig.json
@@ -0,0 +1,8 @@
+{
+ "compilerOptions": {
+ "paths": {
+ "@/*": ["./src/*"]
+ }
+ },
+ "exclude": ["node_modules", "dist"]
+}
diff --git a/playground/vitest-nightwatch/nightwatch.conf.cjs b/playground/vitest-nightwatch/nightwatch.conf.cjs
new file mode 100644
index 000000000..542647e5e
--- /dev/null
+++ b/playground/vitest-nightwatch/nightwatch.conf.cjs
@@ -0,0 +1,153 @@
+//
+// Refer to the online docs for more details:
+// https://nightwatchjs.org/guide/configuration/nightwatch-configuration-file.html
+//
+// _ _ _ _ _ _ _
+// | \ | |(_) | | | | | | | |
+// | \| | _ __ _ | |__ | |_ __ __ __ _ | |_ ___ | |__
+// | . ` || | / _` || '_ \ | __|\ \ /\ / / / _` || __| / __|| '_ \
+// | |\ || || (_| || | | || |_ \ V V / | (_| || |_ | (__ | | | |
+// \_| \_/|_| \__, ||_| |_| \__| \_/\_/ \__,_| \__| \___||_| |_|
+// __/ |
+// |___/
+//
+
+module.exports = {
+ // An array of folders (excluding subfolders) where your tests are located;
+ // if this is not specified, the test source must be passed as the second argument to the test runner.
+ src_folders: [],
+
+ // See https://nightwatchjs.org/guide/concepts/page-object-model.html
+ page_objects_path: [],
+
+ // See https://nightwatchjs.org/guide/extending-nightwatch/adding-custom-commands.html
+ custom_commands_path: [],
+
+ // See https://nightwatchjs.org/guide/extending-nightwatch/adding-custom-assertions.html
+ custom_assertions_path: [],
+
+ // See https://nightwatchjs.org/guide/extending-nightwatch/adding-plugins.html
+ plugins: ['@nightwatch/vue'],
+
+ // See https://nightwatchjs.org/guide/concepts/test-globals.html#external-test-globals
+ globals_path: '',
+
+ vite_dev_server: {
+ start_vite: true,
+ port: process.env.CI ? 4173 : 5173
+ },
+
+ webdriver: {},
+
+ test_workers: {
+ enabled: true,
+ workers: 'auto'
+ },
+
+ test_settings: {
+ default: {
+ disable_error_log: false,
+ launch_url: `http://localhost:${process.env.CI ? '4173' : '5173'}`,
+
+ screenshots: {
+ enabled: false,
+ path: 'screens',
+ on_failure: true
+ },
+
+ desiredCapabilities: {
+ browserName: 'firefox'
+ },
+
+ webdriver: {
+ start_process: true,
+ server_path: ''
+ }
+ },
+
+ safari: {
+ desiredCapabilities: {
+ browserName: 'safari',
+ alwaysMatch: {
+ acceptInsecureCerts: false
+ }
+ },
+ webdriver: {
+ start_process: true,
+ server_path: ''
+ }
+ },
+
+ firefox: {
+ desiredCapabilities: {
+ browserName: 'firefox',
+ alwaysMatch: {
+ acceptInsecureCerts: true,
+ 'moz:firefoxOptions': {
+ args: [
+ // '-headless',
+ // '-verbose'
+ ]
+ }
+ }
+ },
+ webdriver: {
+ start_process: true,
+ server_path: '',
+ cli_args: [
+ // very verbose geckodriver logs
+ // '-vv'
+ ]
+ }
+ },
+
+ chrome: {
+ desiredCapabilities: {
+ browserName: 'chrome',
+ 'goog:chromeOptions': {
+ // More info on Chromedriver: https://sites.google.com/a/chromium.org/chromedriver/
+ //
+ // w3c:false tells Chromedriver to run using the legacy JSONWire protocol (not required in Chrome 78)
+ w3c: true,
+ args: [
+ //'--no-sandbox',
+ //'--ignore-certificate-errors',
+ //'--allow-insecure-localhost',
+ //'--headless'
+ ]
+ }
+ },
+
+ webdriver: {
+ start_process: true,
+ server_path: '',
+ cli_args: [
+ // --verbose
+ ]
+ }
+ },
+
+ edge: {
+ desiredCapabilities: {
+ browserName: 'MicrosoftEdge',
+ 'ms:edgeOptions': {
+ w3c: true,
+ // More info on EdgeDriver: https://docs.microsoft.com/en-us/microsoft-edge/webdriver-chromium/capabilities-edge-options
+ args: [
+ //'--headless'
+ ]
+ }
+ },
+
+ webdriver: {
+ start_process: true,
+ // Download msedgedriver from https://docs.microsoft.com/en-us/microsoft-edge/webdriver-chromium/
+ // and set the location below:
+ server_path: '',
+ cli_args: [
+ // --verbose
+ ]
+ }
+ }
+ }
+}
diff --git a/playground/vitest-nightwatch/package.json b/playground/vitest-nightwatch/package.json
new file mode 100644
index 000000000..24879046f
--- /dev/null
+++ b/playground/vitest-nightwatch/package.json
@@ -0,0 +1,29 @@
+{
+ "name": "vitest-nightwatch",
+ "version": "0.0.0",
+ "private": true,
+ "type": "module",
+ "scripts": {
+ "dev": "vite",
+ "build": "vite build",
+ "preview": "vite preview",
+ "test:unit": "vitest",
+ "test:e2e": "nightwatch tests/e2e/*"
+ },
+ "dependencies": {
+ "vue": "^3.4.15"
+ },
+ "devDependencies": {
+ "@nightwatch/vue": "^3.1.0",
+ "@vitejs/plugin-vue": "^5.0.3",
+ "@vue/test-utils": "^2.4.4",
+ "chromedriver": "^121.0.0",
+ "geckodriver": "^4.3.2",
+ "jsdom": "^24.0.0",
+ "nightwatch": "^3.4.0",
+ "ts-node": "^10.9.2",
+ "vite": "^5.0.11",
+ "vite-plugin-nightwatch": "^0.4.6",
+ "vitest": "^1.2.2"
+ }
+}
diff --git a/playground/vitest-nightwatch/public/favicon.ico b/playground/vitest-nightwatch/public/favicon.ico
new file mode 100644
index 000000000..df36fcfb7
Binary files /dev/null and b/playground/vitest-nightwatch/public/favicon.ico differ
diff --git a/playground/vitest-nightwatch/src/App.vue b/playground/vitest-nightwatch/src/App.vue
new file mode 100644
index 000000000..b6f965e35
--- /dev/null
+++ b/playground/vitest-nightwatch/src/App.vue
@@ -0,0 +1,9 @@
+
+
+
+
+
+
diff --git a/playground/vitest-nightwatch/src/assets/logo.svg b/playground/vitest-nightwatch/src/assets/logo.svg
new file mode 100644
index 000000000..756566035
--- /dev/null
+++ b/playground/vitest-nightwatch/src/assets/logo.svg
@@ -0,0 +1 @@
+
diff --git a/playground/vitest-nightwatch/src/assets/main.css b/playground/vitest-nightwatch/src/assets/main.css
new file mode 100644
index 000000000..5aadc6ceb
--- /dev/null
+++ b/playground/vitest-nightwatch/src/assets/main.css
@@ -0,0 +1,6 @@
+html, body, #app {
+ width: 100%;
+ height: 100%;
+ padding: 0;
+ margin: 0;
+}
diff --git a/playground/vitest-nightwatch/src/components/__tests__/HelloWorld.spec.js b/playground/vitest-nightwatch/src/components/__tests__/HelloWorld.spec.js
new file mode 100644
index 000000000..253320200
--- /dev/null
+++ b/playground/vitest-nightwatch/src/components/__tests__/HelloWorld.spec.js
@@ -0,0 +1,11 @@
+import { describe, it, expect } from 'vitest'
+
+import { mount } from '@vue/test-utils'
+import HelloWorld from '../HelloWorld.vue'
+
+describe('HelloWorld', () => {
+ it('renders properly', () => {
+ const wrapper = mount(HelloWorld, { props: { msg: 'Hello Vitest' } })
+ expect(wrapper.text()).toContain('Hello Vitest')
+ })
+})
diff --git a/playground/vitest-nightwatch/src/main.js b/playground/vitest-nightwatch/src/main.js
new file mode 100644
index 000000000..0ac3a5ff0
--- /dev/null
+++ b/playground/vitest-nightwatch/src/main.js
@@ -0,0 +1,6 @@
+import './assets/main.css'
+
+import { createApp } from 'vue'
+import App from './App.vue'
+
+createApp(App).mount('#app')
diff --git a/playground/vitest-nightwatch/tests/e2e/example.js b/playground/vitest-nightwatch/tests/e2e/example.js
new file mode 100644
index 000000000..43be3fce1
--- /dev/null
+++ b/playground/vitest-nightwatch/tests/e2e/example.js
@@ -0,0 +1,11 @@
+describe('My First Test', function () {
+ before((browser) => {
+ browser.init()
+ })
+
+ it('visits the app root url', function () {
+ browser.assert.textContains('.green', 'You did it!')
+ })
+
+ after((browser) => browser.end())
+})
diff --git a/playground/vitest-nightwatch/vite.config.js b/playground/vitest-nightwatch/vite.config.js
new file mode 100644
index 000000000..be3cb9c57
--- /dev/null
+++ b/playground/vitest-nightwatch/vite.config.js
@@ -0,0 +1,18 @@
+import { fileURLToPath, URL } from 'node:url'
+
+import { defineConfig } from 'vite'
+import vue from '@vitejs/plugin-vue'
+import nightwatchPlugin from 'vite-plugin-nightwatch'
+
+// https://vitejs.dev/config/
+export default defineConfig({
+ plugins: [
+ vue(),
+ nightwatchPlugin(),
+ ],
+ resolve: {
+ alias: {
+ '@': fileURLToPath(new URL('./src', import.meta.url))
+ }
+ }
+})
diff --git a/playground/vitest-nightwatch/vitest.config.js b/playground/vitest-nightwatch/vitest.config.js
new file mode 100644
index 000000000..10067d578
--- /dev/null
+++ b/playground/vitest-nightwatch/vitest.config.js
@@ -0,0 +1,14 @@
+import { fileURLToPath } from 'node:url'
+import { mergeConfig, defineConfig, configDefaults } from 'vitest/config'
+import viteConfig from './vite.config'
+
+export default mergeConfig(
+ viteConfig,
+ defineConfig({
+ test: {
+ environment: 'jsdom',
+ exclude: [...configDefaults.exclude, 'e2e/*'],
+ root: fileURLToPath(new URL('./', import.meta.url))
+ }
+ })
+)
diff --git a/playground/vitest-playwright/.gitignore b/playground/vitest-playwright/.gitignore
new file mode 100644
index 000000000..aef72d03c
--- /dev/null
+++ b/playground/vitest-playwright/.gitignore
@@ -0,0 +1,33 @@
+# 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/
+
+# Editor directories and files
+.vscode/*
+!.vscode/extensions.json
+.idea
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?
+
+*.tsbuildinfo
+
+test-results/
+playwright-report/
diff --git a/playground/vitest-playwright/.vscode/extensions.json b/playground/vitest-playwright/.vscode/extensions.json
new file mode 100644
index 000000000..7b3f8bdae
--- /dev/null
+++ b/playground/vitest-playwright/.vscode/extensions.json
@@ -0,0 +1,3 @@
+{
+ "recommendations": ["ms-playwright.playwright"]
+}
diff --git a/playground/vitest-playwright/README.md b/playground/vitest-playwright/README.md
new file mode 100644
index 000000000..ba4197ffa
--- /dev/null
+++ b/playground/vitest-playwright/README.md
@@ -0,0 +1,54 @@
+# vitest-playwright
+
+This template should help get you started developing with Vue 3 in Vite.
+
+## Recommended IDE Setup
+
+[VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur) + [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin).
+
+## Customize configuration
+
+See [Vite Configuration Reference](https://vitejs.dev/config/).
+
+## Project Setup
+
+```sh
+pnpm install
+```
+
+### Compile and Hot-Reload for Development
+
+```sh
+pnpm dev
+```
+
+### Compile and Minify for Production
+
+```sh
+pnpm build
+```
+
+### Run Unit Tests with [Vitest](https://vitest.dev/)
+
+```sh
+pnpm test:unit
+```
+
+### Run End-to-End Tests with [Playwright](https://playwright.dev)
+
+```sh
+# Install browsers for the first run
+npx playwright install
+
+# When testing on CI, must build the project first
+pnpm build
+
+# Runs the end-to-end tests
+pnpm test:e2e
+# Runs the tests only on Chromium
+pnpm test:e2e --project=chromium
+# Runs the tests of a specific file
+pnpm test:e2e tests/example.spec.ts
+# Runs the tests in debug mode
+pnpm test:e2e --debug
+```
diff --git a/playground/vitest-playwright/e2e/vue.spec.js b/playground/vitest-playwright/e2e/vue.spec.js
new file mode 100644
index 000000000..3e5a3d02d
--- /dev/null
+++ b/playground/vitest-playwright/e2e/vue.spec.js
@@ -0,0 +1,8 @@
+import { test, expect } from '@playwright/test';
+
+// See here how to get started:
+// https://playwright.dev/docs/intro
+test('visits the app root url', async ({ page }) => {
+ await page.goto('/');
+ await expect(page.locator('div.greetings > h1')).toHaveText('You did it!');
+})
diff --git a/playground/vitest-playwright/index.html b/playground/vitest-playwright/index.html
new file mode 100644
index 000000000..99f583aa2
--- /dev/null
+++ b/playground/vitest-playwright/index.html
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+ Vite App
+
+
+
+
+
+
diff --git a/playground/vitest-playwright/jsconfig.json b/playground/vitest-playwright/jsconfig.json
new file mode 100644
index 000000000..5a1f2d222
--- /dev/null
+++ b/playground/vitest-playwright/jsconfig.json
@@ -0,0 +1,8 @@
+{
+ "compilerOptions": {
+ "paths": {
+ "@/*": ["./src/*"]
+ }
+ },
+ "exclude": ["node_modules", "dist"]
+}
diff --git a/playground/vitest-playwright/package.json b/playground/vitest-playwright/package.json
new file mode 100644
index 000000000..1e3ea03d5
--- /dev/null
+++ b/playground/vitest-playwright/package.json
@@ -0,0 +1,24 @@
+{
+ "name": "vitest-playwright",
+ "version": "0.0.0",
+ "private": true,
+ "type": "module",
+ "scripts": {
+ "dev": "vite",
+ "build": "vite build",
+ "preview": "vite preview",
+ "test:unit": "vitest",
+ "test:e2e": "playwright test"
+ },
+ "dependencies": {
+ "vue": "^3.4.15"
+ },
+ "devDependencies": {
+ "@playwright/test": "^1.41.2",
+ "@vitejs/plugin-vue": "^5.0.3",
+ "@vue/test-utils": "^2.4.4",
+ "jsdom": "^24.0.0",
+ "vite": "^5.0.11",
+ "vitest": "^1.2.2"
+ }
+}
diff --git a/playground/vitest-playwright/playwright.config.js b/playground/vitest-playwright/playwright.config.js
new file mode 100644
index 000000000..92075cc1b
--- /dev/null
+++ b/playground/vitest-playwright/playwright.config.js
@@ -0,0 +1,110 @@
+import process from 'node:process'
+import { defineConfig, devices } from '@playwright/test'
+
+/**
+ * Read environment variables from file.
+ * https://github.com/motdotla/dotenv
+ */
+// require('dotenv').config();
+
+/**
+ * See https://playwright.dev/docs/test-configuration.
+ */
+export default defineConfig({
+ testDir: './e2e',
+ /* Maximum time one test can run for. */
+ timeout: 30 * 1000,
+ expect: {
+ /**
+ * Maximum time expect() should wait for the condition to be met.
+ * For example in `await expect(locator).toHaveText();`
+ */
+ timeout: 5000
+ },
+ /* Fail the build on CI if you accidentally left test.only in the source code. */
+ forbidOnly: !!process.env.CI,
+ /* Retry on CI only */
+ retries: process.env.CI ? 2 : 0,
+ /* Opt out of parallel tests on CI. */
+ workers: process.env.CI ? 1 : undefined,
+ /* Reporter to use. See https://playwright.dev/docs/test-reporters */
+ reporter: 'html',
+ /* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
+ use: {
+ /* Maximum time each action such as `click()` can take. Defaults to 0 (no limit). */
+ actionTimeout: 0,
+ /* Base URL to use in actions like `await page.goto('/')`. */
+ baseURL: 'http://localhost:5173',
+
+ /* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
+ trace: 'on-first-retry',
+
+ /* Only on CI systems run the tests headless */
+ headless: !!process.env.CI
+ },
+
+ /* Configure projects for major browsers */
+ projects: [
+ {
+ name: 'chromium',
+ use: {
+ ...devices['Desktop Chrome']
+ }
+ },
+ {
+ name: 'firefox',
+ use: {
+ ...devices['Desktop Firefox']
+ }
+ },
+ {
+ name: 'webkit',
+ use: {
+ ...devices['Desktop Safari']
+ }
+ }
+
+ /* Test against mobile viewports. */
+ // {
+ // name: 'Mobile Chrome',
+ // use: {
+ // ...devices['Pixel 5'],
+ // },
+ // },
+ // {
+ // name: 'Mobile Safari',
+ // use: {
+ // ...devices['iPhone 12'],
+ // },
+ // },
+
+ /* Test against branded browsers. */
+ // {
+ // name: 'Microsoft Edge',
+ // use: {
+ // channel: 'msedge',
+ // },
+ // },
+ // {
+ // name: 'Google Chrome',
+ // use: {
+ // channel: 'chrome',
+ // },
+ // },
+ ],
+
+ /* Folder for test artifacts such as screenshots, videos, traces, etc. */
+ // outputDir: 'test-results/',
+
+ /* Run your local dev server before starting the tests */
+ webServer: {
+ /**
+ * Use the dev server by default for faster feedback loop.
+ * Use the preview server on CI for more realistic testing.
+ * Playwright will re-use the local server if there is already a dev-server running.
+ */
+ command: process.env.CI ? 'vite preview --port 5173' : 'vite dev',
+ port: 5173,
+ reuseExistingServer: !process.env.CI
+ }
+})
diff --git a/playground/vitest-playwright/public/favicon.ico b/playground/vitest-playwright/public/favicon.ico
new file mode 100644
index 000000000..df36fcfb7
Binary files /dev/null and b/playground/vitest-playwright/public/favicon.ico differ
diff --git a/playground/vitest-playwright/src/App.vue b/playground/vitest-playwright/src/App.vue
new file mode 100644
index 000000000..b6f965e35
--- /dev/null
+++ b/playground/vitest-playwright/src/App.vue
@@ -0,0 +1,9 @@
+
+
+
+
+
+
diff --git a/playground/vitest-playwright/src/assets/logo.svg b/playground/vitest-playwright/src/assets/logo.svg
new file mode 100644
index 000000000..756566035
--- /dev/null
+++ b/playground/vitest-playwright/src/assets/logo.svg
@@ -0,0 +1 @@
+
diff --git a/playground/vitest-playwright/src/assets/main.css b/playground/vitest-playwright/src/assets/main.css
new file mode 100644
index 000000000..5aadc6ceb
--- /dev/null
+++ b/playground/vitest-playwright/src/assets/main.css
@@ -0,0 +1,6 @@
+html, body, #app {
+ width: 100%;
+ height: 100%;
+ padding: 0;
+ margin: 0;
+}
diff --git a/playground/vitest-playwright/src/components/__tests__/HelloWorld.spec.js b/playground/vitest-playwright/src/components/__tests__/HelloWorld.spec.js
new file mode 100644
index 000000000..253320200
--- /dev/null
+++ b/playground/vitest-playwright/src/components/__tests__/HelloWorld.spec.js
@@ -0,0 +1,11 @@
+import { describe, it, expect } from 'vitest'
+
+import { mount } from '@vue/test-utils'
+import HelloWorld from '../HelloWorld.vue'
+
+describe('HelloWorld', () => {
+ it('renders properly', () => {
+ const wrapper = mount(HelloWorld, { props: { msg: 'Hello Vitest' } })
+ expect(wrapper.text()).toContain('Hello Vitest')
+ })
+})
diff --git a/playground/vitest-playwright/src/main.js b/playground/vitest-playwright/src/main.js
new file mode 100644
index 000000000..0ac3a5ff0
--- /dev/null
+++ b/playground/vitest-playwright/src/main.js
@@ -0,0 +1,6 @@
+import './assets/main.css'
+
+import { createApp } from 'vue'
+import App from './App.vue'
+
+createApp(App).mount('#app')
diff --git a/playground/vitest-playwright/vite.config.js b/playground/vitest-playwright/vite.config.js
new file mode 100644
index 000000000..5c45e1d9b
--- /dev/null
+++ b/playground/vitest-playwright/vite.config.js
@@ -0,0 +1,16 @@
+import { fileURLToPath, URL } from 'node:url'
+
+import { defineConfig } from 'vite'
+import vue from '@vitejs/plugin-vue'
+
+// https://vitejs.dev/config/
+export default defineConfig({
+ plugins: [
+ vue(),
+ ],
+ resolve: {
+ alias: {
+ '@': fileURLToPath(new URL('./src', import.meta.url))
+ }
+ }
+})
diff --git a/playground/vitest-playwright/vitest.config.js b/playground/vitest-playwright/vitest.config.js
new file mode 100644
index 000000000..10067d578
--- /dev/null
+++ b/playground/vitest-playwright/vitest.config.js
@@ -0,0 +1,14 @@
+import { fileURLToPath } from 'node:url'
+import { mergeConfig, defineConfig, configDefaults } from 'vitest/config'
+import viteConfig from './vite.config'
+
+export default mergeConfig(
+ viteConfig,
+ defineConfig({
+ test: {
+ environment: 'jsdom',
+ exclude: [...configDefaults.exclude, 'e2e/*'],
+ root: fileURLToPath(new URL('./', import.meta.url))
+ }
+ })
+)
diff --git a/playground/vitest/.gitignore b/playground/vitest/.gitignore
new file mode 100644
index 000000000..8ee54e8d3
--- /dev/null
+++ b/playground/vitest/.gitignore
@@ -0,0 +1,30 @@
+# 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/
+
+# Editor directories and files
+.vscode/*
+!.vscode/extensions.json
+.idea
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?
+
+*.tsbuildinfo
diff --git a/playground/vitest/README.md b/playground/vitest/README.md
new file mode 100644
index 000000000..48871df54
--- /dev/null
+++ b/playground/vitest/README.md
@@ -0,0 +1,35 @@
+# vitest
+
+This template should help get you started developing with Vue 3 in Vite.
+
+## Recommended IDE Setup
+
+[VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur) + [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin).
+
+## Customize configuration
+
+See [Vite Configuration Reference](https://vitejs.dev/config/).
+
+## Project Setup
+
+```sh
+pnpm install
+```
+
+### Compile and Hot-Reload for Development
+
+```sh
+pnpm dev
+```
+
+### Compile and Minify for Production
+
+```sh
+pnpm build
+```
+
+### Run Unit Tests with [Vitest](https://vitest.dev/)
+
+```sh
+pnpm test:unit
+```
diff --git a/playground/vitest/index.html b/playground/vitest/index.html
new file mode 100644
index 000000000..99f583aa2
--- /dev/null
+++ b/playground/vitest/index.html
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+ Vite App
+
+
+
+
+
+
diff --git a/playground/vitest/jsconfig.json b/playground/vitest/jsconfig.json
new file mode 100644
index 000000000..5a1f2d222
--- /dev/null
+++ b/playground/vitest/jsconfig.json
@@ -0,0 +1,8 @@
+{
+ "compilerOptions": {
+ "paths": {
+ "@/*": ["./src/*"]
+ }
+ },
+ "exclude": ["node_modules", "dist"]
+}
diff --git a/playground/vitest/package.json b/playground/vitest/package.json
new file mode 100644
index 000000000..c1370e1e8
--- /dev/null
+++ b/playground/vitest/package.json
@@ -0,0 +1,22 @@
+{
+ "name": "vitest",
+ "version": "0.0.0",
+ "private": true,
+ "type": "module",
+ "scripts": {
+ "dev": "vite",
+ "build": "vite build",
+ "preview": "vite preview",
+ "test:unit": "vitest"
+ },
+ "dependencies": {
+ "vue": "^3.4.15"
+ },
+ "devDependencies": {
+ "@vitejs/plugin-vue": "^5.0.3",
+ "@vue/test-utils": "^2.4.4",
+ "jsdom": "^24.0.0",
+ "vite": "^5.0.11",
+ "vitest": "^1.2.2"
+ }
+}
diff --git a/playground/vitest/public/favicon.ico b/playground/vitest/public/favicon.ico
new file mode 100644
index 000000000..df36fcfb7
Binary files /dev/null and b/playground/vitest/public/favicon.ico differ
diff --git a/playground/vitest/src/App.vue b/playground/vitest/src/App.vue
new file mode 100644
index 000000000..b6f965e35
--- /dev/null
+++ b/playground/vitest/src/App.vue
@@ -0,0 +1,9 @@
+
+
+
+
+
+
diff --git a/playground/vitest/src/assets/logo.svg b/playground/vitest/src/assets/logo.svg
new file mode 100644
index 000000000..756566035
--- /dev/null
+++ b/playground/vitest/src/assets/logo.svg
@@ -0,0 +1 @@
+
diff --git a/playground/vitest/src/assets/main.css b/playground/vitest/src/assets/main.css
new file mode 100644
index 000000000..5aadc6ceb
--- /dev/null
+++ b/playground/vitest/src/assets/main.css
@@ -0,0 +1,6 @@
+html, body, #app {
+ width: 100%;
+ height: 100%;
+ padding: 0;
+ margin: 0;
+}
diff --git a/playground/vitest/src/components/__tests__/HelloWorld.spec.js b/playground/vitest/src/components/__tests__/HelloWorld.spec.js
new file mode 100644
index 000000000..253320200
--- /dev/null
+++ b/playground/vitest/src/components/__tests__/HelloWorld.spec.js
@@ -0,0 +1,11 @@
+import { describe, it, expect } from 'vitest'
+
+import { mount } from '@vue/test-utils'
+import HelloWorld from '../HelloWorld.vue'
+
+describe('HelloWorld', () => {
+ it('renders properly', () => {
+ const wrapper = mount(HelloWorld, { props: { msg: 'Hello Vitest' } })
+ expect(wrapper.text()).toContain('Hello Vitest')
+ })
+})
diff --git a/playground/vitest/src/main.js b/playground/vitest/src/main.js
new file mode 100644
index 000000000..0ac3a5ff0
--- /dev/null
+++ b/playground/vitest/src/main.js
@@ -0,0 +1,6 @@
+import './assets/main.css'
+
+import { createApp } from 'vue'
+import App from './App.vue'
+
+createApp(App).mount('#app')
diff --git a/playground/vitest/vite.config.js b/playground/vitest/vite.config.js
new file mode 100644
index 000000000..5c45e1d9b
--- /dev/null
+++ b/playground/vitest/vite.config.js
@@ -0,0 +1,16 @@
+import { fileURLToPath, URL } from 'node:url'
+
+import { defineConfig } from 'vite'
+import vue from '@vitejs/plugin-vue'
+
+// https://vitejs.dev/config/
+export default defineConfig({
+ plugins: [
+ vue(),
+ ],
+ resolve: {
+ alias: {
+ '@': fileURLToPath(new URL('./src', import.meta.url))
+ }
+ }
+})
diff --git a/playground/vitest/vitest.config.js b/playground/vitest/vitest.config.js
new file mode 100644
index 000000000..10067d578
--- /dev/null
+++ b/playground/vitest/vitest.config.js
@@ -0,0 +1,14 @@
+import { fileURLToPath } from 'node:url'
+import { mergeConfig, defineConfig, configDefaults } from 'vitest/config'
+import viteConfig from './vite.config'
+
+export default mergeConfig(
+ viteConfig,
+ defineConfig({
+ test: {
+ environment: 'jsdom',
+ exclude: [...configDefaults.exclude, 'e2e/*'],
+ root: fileURLToPath(new URL('./', import.meta.url))
+ }
+ })
+)
diff --git a/playground/with-tests/.gitignore b/playground/with-tests/.gitignore
new file mode 100644
index 000000000..8ee54e8d3
--- /dev/null
+++ b/playground/with-tests/.gitignore
@@ -0,0 +1,30 @@
+# 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/
+
+# Editor directories and files
+.vscode/*
+!.vscode/extensions.json
+.idea
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?
+
+*.tsbuildinfo
diff --git a/playground/with-tests/README.md b/playground/with-tests/README.md
new file mode 100644
index 000000000..3f1c26fbf
--- /dev/null
+++ b/playground/with-tests/README.md
@@ -0,0 +1,51 @@
+# with-tests
+
+This template should help get you started developing with Vue 3 in Vite.
+
+## Recommended IDE Setup
+
+[VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur) + [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin).
+
+## Customize configuration
+
+See [Vite Configuration Reference](https://vitejs.dev/config/).
+
+## Project Setup
+
+```sh
+pnpm install
+```
+
+### Compile and Hot-Reload for Development
+
+```sh
+pnpm dev
+```
+
+### Compile and Minify for Production
+
+```sh
+pnpm build
+```
+
+### Run Unit Tests with [Vitest](https://vitest.dev/)
+
+```sh
+pnpm test:unit
+```
+
+### Run End-to-End Tests with [Cypress](https://www.cypress.io/)
+
+```sh
+pnpm test:e2e:dev
+```
+
+This runs the end-to-end tests against the Vite development server.
+It is much faster than the production build.
+
+But it's still recommended to test the production build with `test:e2e` before deploying (e.g. in CI environments):
+
+```sh
+pnpm build
+pnpm test:e2e
+```
diff --git a/playground/with-tests/cypress.config.js b/playground/with-tests/cypress.config.js
new file mode 100644
index 000000000..0f66080fd
--- /dev/null
+++ b/playground/with-tests/cypress.config.js
@@ -0,0 +1,8 @@
+import { defineConfig } from 'cypress'
+
+export default defineConfig({
+ e2e: {
+ specPattern: 'cypress/e2e/**/*.{cy,spec}.{js,jsx,ts,tsx}',
+ baseUrl: 'http://localhost:4173'
+ }
+})
diff --git a/playground/with-tests/cypress/e2e/example.cy.js b/playground/with-tests/cypress/e2e/example.cy.js
new file mode 100644
index 000000000..7554c35d8
--- /dev/null
+++ b/playground/with-tests/cypress/e2e/example.cy.js
@@ -0,0 +1,8 @@
+// https://on.cypress.io/api
+
+describe('My First Test', () => {
+ it('visits the app root url', () => {
+ cy.visit('/')
+ cy.contains('h1', 'You did it!')
+ })
+})
diff --git a/playground/with-tests/cypress/e2e/jsconfig.json b/playground/with-tests/cypress/e2e/jsconfig.json
new file mode 100644
index 000000000..c790a70d6
--- /dev/null
+++ b/playground/with-tests/cypress/e2e/jsconfig.json
@@ -0,0 +1,8 @@
+{
+ "compilerOptions": {
+ "target": "es5",
+ "lib": ["es5", "dom"],
+ "types": ["cypress"]
+ },
+ "include": ["./**/*", "../support/**/*"]
+}
diff --git a/playground/with-tests/cypress/fixtures/example.json b/playground/with-tests/cypress/fixtures/example.json
new file mode 100644
index 000000000..02e425437
--- /dev/null
+++ b/playground/with-tests/cypress/fixtures/example.json
@@ -0,0 +1,5 @@
+{
+ "name": "Using fixtures to represent data",
+ "email": "hello@cypress.io",
+ "body": "Fixtures are a great way to mock data for responses to routes"
+}
diff --git a/playground/with-tests/cypress/support/commands.js b/playground/with-tests/cypress/support/commands.js
new file mode 100644
index 000000000..119ab03f7
--- /dev/null
+++ b/playground/with-tests/cypress/support/commands.js
@@ -0,0 +1,25 @@
+// ***********************************************
+// This example commands.js shows you how to
+// create various custom commands and overwrite
+// existing commands.
+//
+// For more comprehensive examples of custom
+// commands please read more here:
+// https://on.cypress.io/custom-commands
+// ***********************************************
+//
+//
+// -- This is a parent command --
+// Cypress.Commands.add('login', (email, password) => { ... })
+//
+//
+// -- This is a child command --
+// Cypress.Commands.add('drag', { prevSubject: 'element'}, (subject, options) => { ... })
+//
+//
+// -- This is a dual command --
+// Cypress.Commands.add('dismiss', { prevSubject: 'optional'}, (subject, options) => { ... })
+//
+//
+// -- This will overwrite an existing command --
+// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... })
diff --git a/playground/with-tests/cypress/support/e2e.js b/playground/with-tests/cypress/support/e2e.js
new file mode 100644
index 000000000..d68db96df
--- /dev/null
+++ b/playground/with-tests/cypress/support/e2e.js
@@ -0,0 +1,20 @@
+// ***********************************************************
+// This example support/index.js is processed and
+// loaded automatically before your test files.
+//
+// This is a great place to put global configuration and
+// behavior that modifies Cypress.
+//
+// You can change the location of this file or turn off
+// automatically serving support files with the
+// 'supportFile' configuration option.
+//
+// You can read more here:
+// https://on.cypress.io/configuration
+// ***********************************************************
+
+// Import commands.js using ES2015 syntax:
+import './commands'
+
+// Alternatively you can use CommonJS syntax:
+// require('./commands')
diff --git a/playground/with-tests/index.html b/playground/with-tests/index.html
new file mode 100644
index 000000000..99f583aa2
--- /dev/null
+++ b/playground/with-tests/index.html
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+ Vite App
+
+
+
+
+
+
diff --git a/playground/with-tests/jsconfig.json b/playground/with-tests/jsconfig.json
new file mode 100644
index 000000000..5a1f2d222
--- /dev/null
+++ b/playground/with-tests/jsconfig.json
@@ -0,0 +1,8 @@
+{
+ "compilerOptions": {
+ "paths": {
+ "@/*": ["./src/*"]
+ }
+ },
+ "exclude": ["node_modules", "dist"]
+}
diff --git a/playground/with-tests/package.json b/playground/with-tests/package.json
new file mode 100644
index 000000000..2aaac0df4
--- /dev/null
+++ b/playground/with-tests/package.json
@@ -0,0 +1,26 @@
+{
+ "name": "with-tests",
+ "version": "0.0.0",
+ "private": true,
+ "type": "module",
+ "scripts": {
+ "dev": "vite",
+ "build": "vite build",
+ "preview": "vite preview",
+ "test:unit": "vitest",
+ "test:e2e": "start-server-and-test preview http://localhost:4173 'cypress run --e2e'",
+ "test:e2e:dev": "start-server-and-test 'vite dev --port 4173' http://localhost:4173 'cypress open --e2e'"
+ },
+ "dependencies": {
+ "vue": "^3.4.15"
+ },
+ "devDependencies": {
+ "@vitejs/plugin-vue": "^5.0.3",
+ "@vue/test-utils": "^2.4.4",
+ "cypress": "^13.6.4",
+ "jsdom": "^24.0.0",
+ "start-server-and-test": "^2.0.3",
+ "vite": "^5.0.11",
+ "vitest": "^1.2.2"
+ }
+}
diff --git a/playground/with-tests/public/favicon.ico b/playground/with-tests/public/favicon.ico
new file mode 100644
index 000000000..df36fcfb7
Binary files /dev/null and b/playground/with-tests/public/favicon.ico differ
diff --git a/playground/with-tests/src/App.vue b/playground/with-tests/src/App.vue
new file mode 100644
index 000000000..b6f965e35
--- /dev/null
+++ b/playground/with-tests/src/App.vue
@@ -0,0 +1,9 @@
+
+
+
+
+
+
diff --git a/playground/with-tests/src/assets/logo.svg b/playground/with-tests/src/assets/logo.svg
new file mode 100644
index 000000000..756566035
--- /dev/null
+++ b/playground/with-tests/src/assets/logo.svg
@@ -0,0 +1 @@
+
diff --git a/playground/with-tests/src/assets/main.css b/playground/with-tests/src/assets/main.css
new file mode 100644
index 000000000..5aadc6ceb
--- /dev/null
+++ b/playground/with-tests/src/assets/main.css
@@ -0,0 +1,6 @@
+html, body, #app {
+ width: 100%;
+ height: 100%;
+ padding: 0;
+ margin: 0;
+}
diff --git a/playground/with-tests/src/components/__tests__/HelloWorld.spec.js b/playground/with-tests/src/components/__tests__/HelloWorld.spec.js
new file mode 100644
index 000000000..253320200
--- /dev/null
+++ b/playground/with-tests/src/components/__tests__/HelloWorld.spec.js
@@ -0,0 +1,11 @@
+import { describe, it, expect } from 'vitest'
+
+import { mount } from '@vue/test-utils'
+import HelloWorld from '../HelloWorld.vue'
+
+describe('HelloWorld', () => {
+ it('renders properly', () => {
+ const wrapper = mount(HelloWorld, { props: { msg: 'Hello Vitest' } })
+ expect(wrapper.text()).toContain('Hello Vitest')
+ })
+})
diff --git a/playground/with-tests/src/main.js b/playground/with-tests/src/main.js
new file mode 100644
index 000000000..0ac3a5ff0
--- /dev/null
+++ b/playground/with-tests/src/main.js
@@ -0,0 +1,6 @@
+import './assets/main.css'
+
+import { createApp } from 'vue'
+import App from './App.vue'
+
+createApp(App).mount('#app')
diff --git a/playground/with-tests/vite.config.js b/playground/with-tests/vite.config.js
new file mode 100644
index 000000000..5c45e1d9b
--- /dev/null
+++ b/playground/with-tests/vite.config.js
@@ -0,0 +1,16 @@
+import { fileURLToPath, URL } from 'node:url'
+
+import { defineConfig } from 'vite'
+import vue from '@vitejs/plugin-vue'
+
+// https://vitejs.dev/config/
+export default defineConfig({
+ plugins: [
+ vue(),
+ ],
+ resolve: {
+ alias: {
+ '@': fileURLToPath(new URL('./src', import.meta.url))
+ }
+ }
+})
diff --git a/playground/with-tests/vitest.config.js b/playground/with-tests/vitest.config.js
new file mode 100644
index 000000000..10067d578
--- /dev/null
+++ b/playground/with-tests/vitest.config.js
@@ -0,0 +1,14 @@
+import { fileURLToPath } from 'node:url'
+import { mergeConfig, defineConfig, configDefaults } from 'vitest/config'
+import viteConfig from './vite.config'
+
+export default mergeConfig(
+ viteConfig,
+ defineConfig({
+ test: {
+ environment: 'jsdom',
+ exclude: [...configDefaults.exclude, 'e2e/*'],
+ root: fileURLToPath(new URL('./', import.meta.url))
+ }
+ })
+)
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 372b7b7dd..f270c52f7 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -65,6 +65,12 @@ importers:
template/base:
dependencies:
+ axios:
+ specifier: ^1.6.7
+ version: 1.6.7(debug@4.3.4)
+ lodash:
+ specifier: ^4.17.21
+ version: 4.17.21
vue:
specifier: ^3.4.15
version: 3.4.15(typescript@5.3.3)
@@ -72,6 +78,12 @@ importers:
'@vitejs/plugin-vue':
specifier: ^5.0.3
version: 5.0.3(vite@5.0.11)(vue@3.4.15)
+ cross-env:
+ specifier: ^7.0.3
+ version: 7.0.3
+ husky:
+ specifier: ^9.0.11
+ version: 9.0.11
vite:
specifier: ^5.0.11
version: 5.0.11(@types/node@20.11.16)
@@ -1212,6 +1224,7 @@ packages:
resolution: {integrity: sha512-OrEyIfpxSsMal44JpEVx9AEcGpdBQG1ZuWISAanaQTSMeStBW+oHWwOkoqR54bw3x8heP8gBOyoJiGg+fLY8qQ==}
cpu: [arm64]
os: [linux]
+ libc: [glibc]
requiresBuild: true
dev: true
optional: true
@@ -1220,6 +1233,7 @@ packages:
resolution: {integrity: sha512-1H7wBbQuE6igQdxMSTjtFfD+DGAudcYWhp106z/9zBA8OQhsJRnemO4XGavdzHpGhRtRxbgmUGdO3YQgrWf2RA==}
cpu: [arm64]
os: [linux]
+ libc: [musl]
requiresBuild: true
dev: true
optional: true
@@ -1228,6 +1242,7 @@ packages:
resolution: {integrity: sha512-FVyFI13tXw5aE65sZdBpNjPVIi4Q5mARnL/39UIkxvSgRAIqCo5sCpCELk0JtXHGee2owZz5aNLbWNfBHzr71Q==}
cpu: [x64]
os: [linux]
+ libc: [glibc]
requiresBuild: true
dev: true
optional: true
@@ -1236,6 +1251,7 @@ packages:
resolution: {integrity: sha512-eBPYl2sLpH/o8qbSz6vPwWlDyThnQjJfcDOGFbNjmjb44XKC1F5dQfakOsADRVrXCNzM6ZsSIPDG5dc6HHLNFg==}
cpu: [x64]
os: [linux]
+ libc: [musl]
requiresBuild: true
dev: true
optional: true
@@ -1959,7 +1975,6 @@ packages:
/asynckit@0.4.0:
resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==}
- dev: true
/at-least-node@1.0.0:
resolution: {integrity: sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==}
@@ -1984,25 +1999,14 @@ packages:
engines: {node: '>=4'}
dev: true
- /axios@1.6.2(debug@4.3.4):
- resolution: {integrity: sha512-7i24Ri4pmDRfJTR7LDBhsOTtcm+9kjX5WiY1X3wIisx6G9So3pfMkEiU7emUBe46oceVImccTEM3k6C5dbVW8A==}
+ /axios@1.6.7(debug@4.3.4):
+ resolution: {integrity: sha512-/hDJGff6/c7u0hDkvkGxR/oy6CbCs8ziCsC7SqmhjfozqiJGc8Z11wrv9z9lYfY4K8l+H9TpjcMDX0xOZmx+RA==}
dependencies:
- follow-redirects: 1.15.3(debug@4.3.4)
+ follow-redirects: 1.15.5(debug@4.3.4)
form-data: 4.0.0
proxy-from-env: 1.1.0
transitivePeerDependencies:
- debug
- dev: true
-
- /axios@1.6.5:
- resolution: {integrity: sha512-Ii012v05KEVuUoFWmMW/UQv9aRIc3ZwkWDcM+h5Il8izZCtRVpDUfwpoFf7eOtajT3QiGR4yDUx7lPqHJULgbg==}
- dependencies:
- follow-redirects: 1.15.5
- form-data: 4.0.0
- proxy-from-env: 1.1.0
- transitivePeerDependencies:
- - debug
- dev: true
/b4a@1.6.4:
resolution: {integrity: sha512-fpWrvyVHEKyeEvbKZTVOeZF3VSKKWtJxFIxX/jaVPf+cLbGUSitjb49pHLqPV2BUNNZ0LcoeEGfE/YCpyDYHIw==}
@@ -2251,7 +2255,7 @@ packages:
requiresBuild: true
dependencies:
'@testim/chrome-version': 1.1.4
- axios: 1.6.5
+ axios: 1.6.7(debug@4.3.4)
compare-versions: 6.1.0
extract-zip: 2.0.1(supports-color@8.1.1)
https-proxy-agent: 5.0.1
@@ -2368,7 +2372,6 @@ packages:
engines: {node: '>= 0.8'}
dependencies:
delayed-stream: 1.0.0
- dev: true
/commander@10.0.1:
resolution: {integrity: sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==}
@@ -2449,6 +2452,14 @@ packages:
resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==}
dev: true
+ /cross-env@7.0.3:
+ resolution: {integrity: sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==}
+ engines: {node: '>=10.14', npm: '>=6', yarn: '>=1'}
+ hasBin: true
+ dependencies:
+ cross-spawn: 7.0.3
+ dev: true
+
/cross-spawn@7.0.3:
resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==}
engines: {node: '>= 8'}
@@ -2589,7 +2600,6 @@ packages:
dependencies:
ms: 2.1.2
supports-color: 8.1.1
- dev: true
/decamelize@4.0.0:
resolution: {integrity: sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==}
@@ -2679,7 +2689,6 @@ packages:
/delayed-stream@1.0.0:
resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==}
engines: {node: '>=0.4.0'}
- dev: true
/devtools-protocol@0.0.1025565:
resolution: {integrity: sha512-0s5sbGQR/EfYQhd8EpZgphpndsv+CufTlaeUyA6vYXCA0H5kMAsHCS/cHtUFWoKJCO125hpoKicQCfpxRj4oqw==}
@@ -3292,8 +3301,8 @@ packages:
hasBin: true
dev: true
- /follow-redirects@1.15.3(debug@4.3.4):
- resolution: {integrity: sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q==}
+ /follow-redirects@1.15.5(debug@4.3.4):
+ resolution: {integrity: sha512-vSFWUON1B+yAw1VN4xMfxgn5fTUiaOzAJCKBwIIgT/+7CuGy9+r+5gITvP62j3RmaD5Ph65UaERdOSRGUzZtgw==}
engines: {node: '>=4.0'}
peerDependencies:
debug: '*'
@@ -3302,17 +3311,6 @@ packages:
optional: true
dependencies:
debug: 4.3.4(supports-color@8.1.1)
- dev: true
-
- /follow-redirects@1.15.5:
- resolution: {integrity: sha512-vSFWUON1B+yAw1VN4xMfxgn5fTUiaOzAJCKBwIIgT/+7CuGy9+r+5gITvP62j3RmaD5Ph65UaERdOSRGUzZtgw==}
- engines: {node: '>=4.0'}
- peerDependencies:
- debug: '*'
- peerDependenciesMeta:
- debug:
- optional: true
- dev: true
/for-each@0.3.3:
resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==}
@@ -3340,7 +3338,6 @@ packages:
asynckit: 0.4.0
combined-stream: 1.0.8
mime-types: 2.1.35
- dev: true
/formdata-polyfill@4.0.10:
resolution: {integrity: sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==}
@@ -3584,7 +3581,6 @@ packages:
/has-flag@4.0.0:
resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==}
engines: {node: '>=8'}
- dev: true
/has-property-descriptors@1.0.1:
resolution: {integrity: sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==}
@@ -3705,6 +3701,12 @@ packages:
hasBin: true
dev: true
+ /husky@9.0.11:
+ resolution: {integrity: sha512-AB6lFlbwwyIqMdHYhwPe+kjOC3Oc5P3nThEoW/AaO2BX3vJDjWPFxYLxokUZOo6RNX20He3AaT8sESs9NJcmEw==}
+ engines: {node: '>=18'}
+ hasBin: true
+ dev: true
+
/iconv-lite@0.6.3:
resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==}
engines: {node: '>=0.10.0'}
@@ -4335,7 +4337,6 @@ packages:
/lodash@4.17.21:
resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==}
- dev: true
/log-symbols@4.1.0:
resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==}
@@ -4437,14 +4438,12 @@ packages:
/mime-db@1.52.0:
resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==}
engines: {node: '>= 0.6'}
- dev: true
/mime-types@2.1.35:
resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==}
engines: {node: '>= 0.6'}
dependencies:
mime-db: 1.52.0
- dev: true
/mimic-fn@2.1.0:
resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==}
@@ -4554,7 +4553,6 @@ packages:
/ms@2.1.2:
resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==}
- dev: true
/ms@2.1.3:
resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
@@ -5054,7 +5052,6 @@ packages:
/proxy-from-env@1.1.0:
resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==}
- dev: true
/ps-tree@1.2.0:
resolution: {integrity: sha512-0VnamPPYHl4uaU/nSFeZZpR21QAWRz+sRv4iW9+v/GS/J5U5iZB5BNN6J0RMoOvdx2gWM2+ZFMIm58q24e4UYA==}
@@ -5594,7 +5591,6 @@ packages:
engines: {node: '>=10'}
dependencies:
has-flag: 4.0.0
- dev: true
/svg-tags@1.0.0:
resolution: {integrity: sha512-ovssysQTa+luh7A5Weu3Rta6FJlFBBbInjOh722LIt6klpU2/HtdUbszju/G4devcvk8PGt7FCLv5wftu3THUA==}
@@ -6097,7 +6093,7 @@ packages:
engines: {node: '>=12.0.0'}
hasBin: true
dependencies:
- axios: 1.6.2(debug@4.3.4)
+ axios: 1.6.7(debug@4.3.4)
joi: 17.11.0
lodash: 4.17.21
minimist: 1.2.8
diff --git a/scripts/LICENSE b/scripts/LICENSE
new file mode 100644
index 000000000..7e3f1fdeb
--- /dev/null
+++ b/scripts/LICENSE
@@ -0,0 +1,33 @@
+# create-vue core license
+
+create-vue is released under the MIT license:
+
+MIT License
+
+Copyright (c) 2021-present vuejs
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
+## Licenses of bundled dependencies
+
+The published create-vue artifact additionally contains code with the following licenses:
+
+
+## Bundled dependencies
+
diff --git a/template/base/.eslintignore b/template/base/.eslintignore
new file mode 100644
index 000000000..e2e5c4276
--- /dev/null
+++ b/template/base/.eslintignore
@@ -0,0 +1,5 @@
+/node_modules/
+/src/mock/
+/src/assets/
+./package-lock.json
+useless-*.*
diff --git a/template/base/.eslintrc.cjs b/template/base/.eslintrc.cjs
new file mode 100644
index 000000000..eafb89e9d
--- /dev/null
+++ b/template/base/.eslintrc.cjs
@@ -0,0 +1,120 @@
+// @ts-check
+require('@rushstack/eslint-patch/modern-module-resolution');
+/**
+ * ESLint Configuration File
+ *
+ * Docs: https://eslint.org/docs/user-guide/configuring
+ * @type {import('eslint').Config}
+ */
+module.exports = {
+ /**
+ * Config Root
+ */
+ root: true,
+ /**
+ * Custom Rules
+ */
+ rules: {
+ 'no-console': 'off',
+ 'no-debugger': 'off',
+ },
+ /**
+ * Custom Groups
+ */
+ overrides: [
+ {
+ files: ['./*.config.js', './*rc.js', '**/scripts/**/*.js'],
+ env: {
+ node: true,
+ },
+ parserOptions: {
+ sourceType: 'module',
+ },
+ parser: '@babel/eslint-parser',
+ rules: {
+ 'no-unused-vars': 'off',
+ 'no-prototype-builtins': 'off',
+ },
+ extends: ['eslint:recommended', 'plugin:prettier/recommended'],
+ },
+ {
+ files: ['./public/*.js'],
+ env: {
+ browser: true,
+ },
+ parserOptions: {
+ sourceType: 'module',
+ requireConfigFile: false,
+ },
+ rules: {
+ 'no-unused-vars': 'off',
+ 'no-prototype-builtins': 'off',
+ },
+ extends: ['eslint:recommended', 'plugin:prettier/recommended'],
+ },
+ {
+ files: ['*.js', '*.jsx'],
+ env: {
+ es2020: true,
+ node: true,
+ browser: true,
+ },
+ parserOptions: {
+ sourceType: 'module',
+ },
+ parser: '@babel/eslint-parser',
+ rules: {
+ 'no-unused-vars': 'warn',
+ 'no-prototype-builtins': 'off',
+ },
+ extends: ['eslint:recommended', 'plugin:prettier/recommended'],
+ },
+ {
+ files: ['*.ts', '*.tsx'],
+ env: {
+ es2020: true,
+ browser: true,
+ },
+ parser: '@typescript-eslint/parser',
+ extends: [
+ 'eslint:recommended',
+ 'plugin:@typescript-eslint/eslint-recommended',
+ 'plugin:@typescript-eslint/recommended',
+ 'plugin:prettier/recommended',
+ ],
+ rules: {
+ '@typescript-eslint/no-unused-vars': 'warn',
+ '@typescript-eslint/no-non-null-assertion': 'off',
+ '@typescript-eslint/no-explicit-any': 'off',
+ 'no-prototype-builtins': 'off',
+ },
+ },
+ {
+ files: ['*.vue'],
+ env: {
+ es2020: true,
+ browser: true,
+ node: true,
+ },
+ parser: 'vue-eslint-parser',
+ parserOptions: {
+ sourceType: 'module',
+ ecmaVersion: 'latest',
+ },
+ extends: [
+ 'eslint:recommended',
+ 'plugin:prettier/recommended',
+ 'plugin:vue/vue3-essential',
+ '@vue/eslint-config-typescript',
+ '@vue/eslint-config-prettier/skip-formatting',
+ ],
+ rules: {
+ 'no-unreachable': 'warn',
+ 'no-debugger': 'warn',
+ 'no-prototype-builtins': 'off',
+ 'no-unused-vars': 'warn',
+ 'vue/multi-word-component-names': 'off',
+ },
+ },
+ ],
+};
diff --git a/template/base/.gitignore b/template/base/.gitignore
new file mode 100644
index 000000000..9dc061034
--- /dev/null
+++ b/template/base/.gitignore
@@ -0,0 +1,36 @@
+# 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/
+
+# Editor directories and files
+.vscode/*
+!.vscode/extensions.json
+.idea
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?
+
+*.tsbuildinfo
+
+./package-lock.json
+/node_modules/
+/dist/
+/.idea/
+/.husky/
diff --git a/template/base/.prettierrc.json b/template/base/.prettierrc.json
new file mode 100644
index 000000000..4fa3f78bd
--- /dev/null
+++ b/template/base/.prettierrc.json
@@ -0,0 +1,9 @@
+{
+ "$schema": "https://json.schemastore.org/prettierrc",
+ "semi": true,
+ "arrowParens": "always",
+ "singleQuote": true,
+ "endOfLine": "auto",
+ "printWidth": 120,
+ "tabWidth": 4
+}
diff --git a/template/base/.vscode/extensions.json b/template/base/.vscode/extensions.json
deleted file mode 100644
index c0a6e5a48..000000000
--- a/template/base/.vscode/extensions.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "recommendations": ["Vue.volar", "Vue.vscode-typescript-vue-plugin"]
-}
diff --git a/template/base/index.html b/template/base/index.html
index 99f583aa2..a0b0094d7 100644
--- a/template/base/index.html
+++ b/template/base/index.html
@@ -8,6 +8,7 @@
+