The build system uses Vite to create the UI of your website/app (/src
folder). Don’t worry if you aren’t acquainted with Vite. Out of the box, you won’t need to configure it because it already has everything set up.
Updating Vite config
You may have noticed that the vite.config.js
/ vite.config.ts
file does not exist in your Quasar CLI with Vite project. This is because Quasar CLI generates the Vite configuration for you so that you don’t have to worry about it.
In case you need to tweak it, you can do so through quasar.config file > build > extendViteConf like so:
// use mergeConfig helper to avoid overwriting the default config
const { mergeConfig } = require('vite')
// ...
build: {
extendViteConf (viteConf, { isServer, isClient }) {
// example: change the chunk size warning limit
viteConf.build = mergeConfig(viteConf.build, {
chunkSizeWarningLimit: 750
})
// equivalent of following vite.config.js/vite.config.ts:
// export default defineConfig({
// build: {
// chunkSizeWarningLimit: 750
// }
// })
}
}
Notice that you don’t need to return anything. The parameter of extendViteConf(viteConf) is the Vite configuration Object generated by Quasar for you. You can add/remove/replace almost anything in it, assuming you really know what you are doing. Do not tamper with the input and output files though or any other option that is already configured by quasar.config file > build
.
If you want to add some Vite plugins, see the Adding Vite plugins section below.
Inspecting Vite Config
Quasar CLI offers a useful command for this:
$ quasar inspect -h
Description
Inspect Quasar generated Vite config
Usage
$ quasar inspect
$ quasar inspect -c build
$ quasar inspect -m electron -p 'build.outDir'
Options
--cmd, -c Quasar command [dev|build] (default: dev)
--mode, -m App mode [spa|ssr|pwa|bex|cordova|capacitor|electron] (default: spa)
--depth, -d Number of levels deep (default: 2)
--path, -p Path of config in dot notation
Examples:
-p module.rules
-p plugins
--thread, -t Display only one specific app mode config thread
--help, -h Displays this message
Adding Vite plugins @quasar/app-vite 1.8+
Make sure to yarn/npm install the vite plugin package that you want to use, then edit the /quasar.config
file:
build: {
vitePlugins: [
// both are perfectly equivalent:
[ '<plugin-name>', { /* plugin options */ } ],
[ '<plugin-name>', { /* plugin options */ }, { server: true, client: true } ]
]
}
You can disable a plugin on the client-side or the server-side, which is especially useful when developing a SSR app:
build: {
vitePlugins: [
// disable on the server-side:
[ '<plugin-name>', { /* plugin options */ }, { server: false } ],
// disable on the client-side:
[ '<plugin-name>', { /* plugin options */ }, { client: false } ]
]
}
There are multiple syntaxes supported:
vitePlugins: [
[ '<plugin1-name>', { /* plugin1 options */ }, { server: true, client: true } ],
[ '<plugin2-name>', { /* plugin2 options */ }, { server: true, client: true } ],
// ...
]
// or:
vitePlugins: [
[ require('<plugin1-name>'), { /* plugin1 options */ }, { server: true, client: true } ],
[ require('<plugin2-name>'), { /* plugin2 options */ }, { server: true, client: true } ],
// ...
]
// finally, you can specify using the form below,
// but this one has a drawback in that Quasar CLI cannot pick up
// when you change the options param so you'll have to manually
// restart the dev server
vitePlugins: [
require('<plugin1-name>')({ /* plugin1 options */ }),
require('<plugin2-name>')({ /* plugin2 options */ })
// ...
]
TIP
You might actually bump into Vite plugins that need to be used as require('<package-name>').default
instead of require('<package-name>')
. So:
vitePlugins: [
[ require('<plugin1-name>').default, { /* plugin1 options */ } ],
// ...
]
And, should you want, you can also add Vite plugins through extendViteConf()
in the /quasar.config
file. This is especially useful for (but not limited to) SSR mode where you’d want a Vite plugin to be applied only on the server-side or the client-side:
build: {
extendViteConf (viteConf, { isClient, isServer }) {
viteConf.plugins.push(
require('<plugin1-name>')({ /* plugin1 options */ }),
require('<plugin2-name>')({ /* plugin2 options */ })
// ...
)
}
}
Moreover, don’t forget that your /quasar.config
file exports a function that receives ctx
as parameter. You can use it throughout the whole config file to apply settings only to certain Quasar modes or only to dev or prod:
module.exports = function (ctx) {
return {
build: {
extendViteConf (viteConf, { isClient, isServer }) {
if (ctx.mode.pwa) {
viteConf.plugins.push(/* ... */)
}
if (ctx.dev) {
viteConf.plugins.push(/* ... */)
}
}
}
}
}
Example: rollup-plugin-copy
It is likely that you will need to copy static or external files to your Quasar project during the build to production process, rollup-plugin-copy allows you to copy files and folders when building your app.
// ...
build: {
// ...
vitePlugins: [
[
'rollup-plugin-copy', {
targets: [
{ // Syntax code, check doc in https://www.npmjs.com/package/rollup-plugin-copy
src: '[ORIGIN_PATH]',
dest: '[DEST_PATH]'
},
{ // Copying firebase-messaging-sw.js to SPA/PWA/SSR dest build folder
src: 'config/firebase/firebase-messaging-sw.js',
dest: 'dest/spa' // example when building SPA
}
]
}
]
// other vite/rollup plugins
]
}
// ...
Vite Vue Plugin options
If you need to tweak the Vite Vue Plugin(@vitejs/plugin-vue
) options, you can do so through quasar.config file > build > viteVuePluginOptions
like so:
build: {
viteVuePluginOptions: {
script: {
// example: enable experimental props destructuring
propsDestructure: true
},
template: {
compilerOptions: {
// example: enable custom/web element tag detection
isCustomElement: (tag) => tag.startsWith('my-')
}
}
}
}
Folder aliases
Quasar comes with a bunch of useful folder aliases pre-configured. You can use them anywhere in your project and Vite will resolve the correct path.
Alias | Resolves to |
---|---|
src | /src |
app | / |
components | /src/components |
layouts | /src/layouts |
pages | /src/pages |
assets | /src/assets |
boot | /src/boot |
stores | /src/stores (Pinia stores) |
Adding folder aliases
We will use utils
as an example, which may be used as import { formatTime } from 'utils/time'
. There are two ways to add a folder alias:
- Through
/quasar.config file > build > alias
property. This is the simplest way to add a folder alias. Use Node’spath.join
helper to get the absolute path to your alias. Example:
const path = require('node:path')
module.exports = function (ctx) {
return {
build: {
alias: {
utils: path.join(__dirname, './src/utils')
}
}
}
}
- By extending the Vite config directly. Do not assign to
viteConf.resolve.alias
directly to preserve the built-in aliases, useObject.assign
instead. Use Node’spath.join
helper to resolve the path to your intended alias.
const path = require('node:path')
module.exports = function (ctx) {
return {
build: {
extendViteConf (viteConf, { isServer, isClient }) {
Object.assign(viteConf.resolve.alias, {
utils: path.join(__dirname, './src/utils')
})
}
}
}
}
Using with TypeScript
If you are using TypeScript, you also have to add the aliases you defined in quasar.config file
to your tsconfig.json
file. To preserve the built-in aliases, you have to re-define them in your tsconfig.json
file. Example:
{
"extends": "@quasar/app-vite/tsconfig-preset",
"compilerOptions": {
"baseUrl": ".",
"paths": {
"src/*": ["src/*"],
"app/*": ["*"],
"components/*": ["src/components/*"],
"layouts/*": ["src/layouts/*"],
"pages/*": ["src/pages/*"],
"assets/*": ["src/assets/*"],
"boot/*": ["src/boot/*"],
"stores/*": ["src/stores/*"],
"utils/*": ["src/utils/*"]
}
}
}
If you want to use tsconfig.json
as the source of truth and let Vite pick them up from there automatically, you can use vite-tsconfig-paths
plugin. This way, you will not have to update both quasar.config file
and tsconfig.json
whenever adding an alias, avoiding potential mistakes. Install it following the instructions in the link and then add it to your quasar.config file
:
module.exports = function (ctx) {
return {
build: {
// no longer needed to define aliases here
// alias: {},
vitePlugins: [
['vite-tsconfig-paths', {
// projects: ['./tsconfig.json', '../../tsconfig.json'] // if you have multiple tsconfig files (e.g. in a monorepo)
}]
]
}
}
}
PostCSS
Styles in *.vue
files (and all other style files) are piped through PostCSS by default, so you don’t need to use a specific loader for it.
By default, PostCSS is configured to use Autoprefixer. Take a look at /postcss.config.cjs
where you can tweak it if you need to.