Build Vue 3 Subfolder
March 9, 2025 Β· AI Conversations
### Steps:
1. **Set the `base` option in `vite.config.js`:**
Modify your `vite.config.js` to specify the subfolder where your Vue app will be served.
import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
export default defineConfig({
plugins: [vue()],
base: '/your-subfolder/', // Change to your actual subfolder name
});
– If your app is hosted at `https://example.com/myapp/`, set `base: '/myapp/'`.
2. **Update Vue Router (if applicable):**
If you're using **Vue Router**, update your router file to use **`history.createWebHistory(base)`**:
import { createRouter, createWebHistory } from 'vue-router';
import Home from '@/views/Home.vue';
const router = createRouter({
history: createWebHistory('/your-subfolder/'), // Ensure it matches the Vite base
routes: [
{ path: '/', component: Home },
],
});
export default router;
3. **Build the project:**
yarn build # or npm run build
4. **Deploy to the subfolder:**
– Upload the `dist` folder contents to `/your-subfolder/` on your server.
5. **Check the server config:**
If using **Apache**, update `.htaccess` in `/your-subfolder/`:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /your-subfolder/
RewriteRule ^index.html$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /your-subfolder/index.html [L]
</IfModule>
If using **Nginx**, add:
location /your-subfolder/ {
try_files $uri /index.html;
}
Now your Vue 3 app should work correctly inside the `/your-subfolder/`. π
<script>
</script>
update above to run in subfolder set baseurl
For example, if your app is hosted at `https://example.com/myapp/`, update the file as follows:
### Updated `index.html`:
<!DOCTYPE html>
<html lang="">
<head>
<meta charset="UTF-8">
<link rel="icon" href="/myapp/favicon.ico"> <!-- Update the subfolder path -->
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Quicksand:wght@300..700&display=swap" rel="stylesheet">
<title>Vite App</title>
<script type="module" crossorigin src="/myapp/assets/index-BjA2gWtO.js"></script>
<link rel="stylesheet" crossorigin href="/myapp/assets/index-mx26lbES.css">
</head>
<body>
<div id="app"></div>
</body>
</html>
### Also, update `vite.config.js`:
import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
export default defineConfig({
plugins: [vue()],
base: '/myapp/', // Ensure this matches the subfolder
});
### Build & Deploy:
1. Run:
yarn build # or npm run build
2. Upload the generated `dist` folder to `https://example.com/myapp/`.
Now, your Vue 3 app should work correctly inside the `/myapp/` subfolder! π
### **Solution: Update `vite.config.js`**
Modify `vite.config.js` to check the environment:
import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
export default defineConfig(({ mode }) => ({
plugins: [vue()],
base: mode === 'development' ? '/' : '/myapp/', // Use '/' locally and '/myapp/' in production
}));
### **How It Works:**
– **During local development (`yarn dev` or `npm run dev`)**, it runs at `/` (root).
– **During build (`yarn build` or `npm run build`)**, it uses `/myapp/` as the base path.
### **No Need to Modify `index.html`**
Vite will automatically set correct paths when building.
### **Now, Follow These Steps:**
1. **Run locally** (`localhost:5173` works as usual):
yarn dev # or npm run dev
2. **Build for production (subfolder mode):**
yarn build # or npm run build
3. **Deploy the `dist` folder to `/myapp/`** on your server.
Now, your app will work at `/` locally and `/myapp/` in production **without breaking local development!** π
import { fileURLToPath, URL } from 'node:url'
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import vueJsx from '@vitejs/plugin-vue-jsx'
import vueDevTools from 'vite-plugin-vue-devtools'
// https://vite.dev/config/
export default defineConfig({
plugins: [
vue(),
vueJsx(),
vueDevTools(),
],
resolve: {
alias: {
'@': fileURLToPath(new URL('./src', import.meta.url))
},
},
})
import { fileURLToPath, URL } from 'node:url';
import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
import vueJsx from '@vitejs/plugin-vue-jsx';
import vueDevTools from 'vite-plugin-vue-devtools';
// https://vite.dev/config/
export default defineConfig(({ mode }) => ({
plugins: [
vue(),
vueJsx(),
vueDevTools(),
],
resolve: {
alias: {
'@': fileURLToPath(new URL('./src', import.meta.url)),
},
},
base: mode === 'development' ? '/' : '/myapp/', // Root for dev, subfolder for production
}));
### **How This Works:**
– When running `yarn dev` or `npm run dev`, the app runs at `/`.
– When running `yarn build` or `npm run build`, the app builds with `/myapp/` as the base.
– No need to modify `index.html` manually.
This ensures smooth development locally and proper deployment in a subfolder! π
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import vueJsx from '@vitejs/plugin-vue-jsx'
import vueDevTools from 'vite-plugin-vue-devtools'
// https://vite.dev/config/
export default defineConfig({
plugins: [
vue(),
vueJsx(),
vueDevTools(),
],
resolve: {
alias: {
'@': fileURLToPath(new URL('./src', import.meta.url))
},
},
server: {
host: 'localhost',
port: 5173,
strictPort: true,
origin: 'http://localhost:5173',
watch: {
ignored: ['**/node_modules/**', '**/vendor/**'],
usePolling: true,
},
},
})
import { fileURLToPath, URL } from 'node:url';
import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
import vueJsx from '@vitejs/plugin-vue-jsx';
import vueDevTools from 'vite-plugin-vue-devtools';
// https://vite.dev/config/
export default defineConfig(({ mode }) => ({
plugins: [
vue(),
vueJsx(),
vueDevTools(),
],
resolve: {
alias: {
'@': fileURLToPath(new URL('./src', import.meta.url)),
},
},
server: {
host: 'localhost',
port: 5173,
strictPort: true,
origin: 'http://localhost:5173',
watch: {
ignored: ['**/node_modules/**', '**/vendor/**'],
usePolling: true,
},
},
base: mode === 'development' ? '/' : '/myapp/', // Root for dev, subfolder for production
}));
### **How This Works:**
β
Runs at `/` in local development (`yarn dev` / `npm run dev`).
β
Builds for `/myapp/` in production (`yarn build` / `npm run build`).
β
No need to modify `index.html` manually.
β
Keeps your existing server settings intact.
This ensures a **smooth local development experience** and a **correct deployment path in production**! π
$ run-p type-check "build-only {@}" —
$ vue-tsc –build
$ vite build
vitest.config.ts:6:3 – error TS2345: Argument of type 'UserConfigFnObject' is not assignable to parameter of type 'never'.
6 viteConfig,
~~~~~~~~~~
vite v6.2.1 building for production…
transforming (141) node_modules/vuetify/lib/composables/index.mjs
Found 1 error.
error Command failed with exit code 2.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
ERROR: "type-check" exited with 2.
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
### **Possible Fixes:**
#### **1. Ensure `defineConfig` is used properly in `vite.config.ts`**
If you're using TypeScript, update your `vite.config.ts` to explicitly define the return type:
import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
import vueJsx from '@vitejs/plugin-vue-jsx';
import vueDevTools from 'vite-plugin-vue-devtools';
export default defineConfig(({ mode }): import('vite').UserConfig => ({
plugins: [
vue(),
vueJsx(),
vueDevTools(),
],
resolve: {
alias: {
'@': new URL('./src', import.meta.url).pathname,
},
},
server: {
host: 'localhost',
port: 5173,
strictPort: true,
origin: 'http://localhost:5173',
watch: {
ignored: ['**/node_modules/**', '**/vendor/**'],
usePolling: true,
},
},
base: mode === 'development' ? '/' : '/myapp/', // Root for dev, subfolder for production
}));
#### **2. Check for Conflicting Vite Versions**
Run:
yarn list vite
Ensure you are using a **stable version** of Vite (e.g., `6.2.1` might have a regression, consider `6.1.x` or `5.x.x`).
#### **3. Upgrade TypeScript and Vitest**
Your error is related to TypeScript type checking. Ensure TypeScript and Vitest are up to date:
yarn upgrade typescript vitest --latest
#### **4. Try a Clean Install**
If the issue persists, clear dependencies and reinstall:
rm -rf node_modules yarn.lock
yarn install
yarn build
#### **5. Check `vitest.config.ts` for Errors**
If your `vitest.config.ts` has an invalid `viteConfig` reference, ensure it's properly structured:
import { defineConfig } from 'vitest/config';
import viteConfig from './vite.config';
export default defineConfig({
...viteConfig,
test: {
globals: true,
environment: 'jsdom',
},
});
—
### **Summary**
β
Fix `vite.config.ts` typing issues.
β
Ensure correct `vite` version.
β
Upgrade TypeScript & Vitest.
β
Clear dependencies and reinstall.
β
Verify `vitest.config.ts`.
Try these steps and let me know if the error persists! π
6 viteConfig,
~~~~~~~~~~
vite v6.2.1 building for production…
transforming (181) node_modules/vuetify/lib/components/VBottomSheet/VBottomSheet.mjs
Found 1 error.
error Command failed with exit code 2.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
ERROR: "type-check" exited with 2.
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
—
### **1οΈβ£ Fix the Typing Issue in `vite.config.ts`**
Modify your **`vite.config.ts`** to ensure TypeScript correctly infers the type:
import { fileURLToPath, URL } from 'node:url';
import { defineConfig, type UserConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
import vueJsx from '@vitejs/plugin-vue-jsx';
import vueDevTools from 'vite-plugin-vue-devtools';
export default defineConfig(({ mode }): UserConfig => ({
plugins: [
vue(),
vueJsx(),
vueDevTools(),
],
resolve: {
alias: {
'@': fileURLToPath(new URL('./src', import.meta.url)),
},
},
server: {
host: 'localhost',
port: 5173,
strictPort: true,
origin: 'http://localhost:5173',
watch: {
ignored: ['**/node_modules/**', '**/vendor/**'],
usePolling: true,
},
},
base: mode === 'development' ? '/' : '/myapp/', // Root for dev, subfolder for production
}));
β
**Why?**
– Explicitly sets `UserConfig` as the return type to prevent type mismatches.
—
### **2οΈβ£ Fix `vitest.config.ts`**
Modify **`vitest.config.ts`** to **properly import `viteConfig`**:
import { defineConfig } from 'vitest/config';
import viteConfig from './vite.config';
// Ensure viteConfig is typed correctly before spreading it
export default defineConfig({
...viteConfig as any, // Temporary workaround if needed
test: {
globals: true,
environment: 'jsdom',
},
});
β
**Why?**
– Ensures TypeScript doesnβt fail due to inferred types.
– The `as any` workaround is temporary; try without it first.
—
### **3οΈβ£ Check Dependencies**
Run:
yarn list vite vitest typescript
Ensure you're using:
– `vite` **latest stable** (`6.2.1` might have a regression).
– `vitest` **>=0.34.0**.
– `typescript` **>=5.3.0**.
If outdated, upgrade:
yarn upgrade vite vitest typescript --latest
—
### **4οΈβ£ Clean Install & Rebuild**
If the error persists, try:
rm -rf node_modules yarn.lock
yarn install
yarn build
—
### **π Summary**
β
**Fix type issues** in `vite.config.ts` (use `UserConfig`).
β
**Fix `vitest.config.ts`** by ensuring `viteConfig` is typed.
β
**Upgrade dependencies** (`vite`, `vitest`, `typescript`).
β
**Clean install** (`rm -rf node_modules yarn.lock && yarn install`).
Try these steps and let me know if you still face issues! π