Handling Webpack

The build system uses Webpack to create your website/app. Don’t worry if you aren’t acquainted with Webpack. Out of the box, you won’t need to configure it because it already has everything set up.

Usage with quasar.conf.js

For cases where you need to tweak the default Webpack config you can do so by editing /quasar.conf.js and configuring build > extendWebpack (cfg) method or build > chainWebpack (chain).

Example of adding ESLint loader to Webpack (assuming you’ve installed it):

// quasar.conf.js
build: {
  extendWebpack (cfg, { isServer, isClient }) {
    cfg.module.rules.push({
      enforce: 'pre',
      test: /\.(js|vue)$/,
      loader: 'eslint-loader',
      exclude: /(node_modules|quasar)/,
      options: {
        formatter: require('eslint').CLIEngine.getFormatter('stylish')
      }
    })
  }
}

Notice that you don’t need to return anything. The parameter of extendWebpack(cfg) is the Webpack configuration Object generated by Quasar for you. You can add/remove/replace anything from it, assuming you really know what you are doing.

Equivalent quasar.conf for chainWebpack():

// quasar.conf.js
build: {
  chainWebpack (chain, { isServer, isClient }) {
    chain.module.rule('eslint')
      .test(/\.(js|vue)$/)
      .enforce('pre')
      .exclude(/[\\/]node_modules[\\/]/)
      .use('eslint-loader')
        .loader('eslint-loader')
  }
}

TIP

The method chainWebpack() supplies a webpack-chain Object. You might want to check its documentation page.

WARNING

chainWebpack() gets executed beforeextendWebpack().

The two examples above are equivalent. Do NOT use both methods to tamper for the same thing!

Inspecting Webpack Config

Quasar CLI offers a useful command for this:

$ quasar inspect -h

  Description
    Inspect Quasar generated Webpack config

  Usage
    $ quasar inspect
    $ quasar inspect -c build
    $ quasar inspect -m electron -p 'module.rules'

  Options
    --cmd, -c        Quasar command [dev|build] (default: dev)
    --mode, -m       App mode [spa|ssr|pwa|cordova|electron] (default: spa)
    --depth, -d      Number of levels deep (default: 5)
    --path, -p       Path of config in dot notation
                        Examples:
                          -p module.rules
                          -p plugins
    --help, -h       Displays this message

Webpack Aliases

Quasar comes with a bunch of useful Webpack aliases preconfigured. You can use them anywhere in your project and webpack will resolve the correct path.

AliasResolves to
src/src
app/
components/src/components
layouts/src/layouts
pages/src/pages
assets/src/assets
boot/src/boot

Also if you configure to build with the Vue compiler version (quasar.conf > build > vueCompiler: true), vue$ resolves to vue/dist/vue.esm.js.

Adding Webpack aliases

To add your own alias you can extend the webpack config and merge it with the existing alias. Use the path.resolve helper to resolve the path to your intended alias.

// quasar.conf.js
const path = require('path')

module.exports = function (ctx) {
  return {
    build: {
      extendWebpack (cfg, { isServer, isClient }) {
        cfg.resolve.alias = {
          ...cfg.resolve.alias, // This adds the existing alias

          // Add your own alias like this
          myalias: path.resolve(__dirname, './src/somefolder'),
        }
      }
    }
  }
}

Equivalent with chainWebpack():

// quasar.conf.js
const path = require('path')

module.exports = function (ctx) {
  return {
    build: {
      chainWebpack (chain, { isServer, isClient }) {
        chain.resolve.alias
          .set('myalias', path.resolve(__dirname, './src/somefolder'))
      }
    }
  }
}

Webpack loaders

The build system uses Webpack, so it relies on using webpack loaders to handle different types of files (js, css, styl, scss, json, and so on). By default, the most used loaders are provided by default.

Installing loaders

Let’s take an example. You want to be able to import .json files. Out of the box, Quasar supplies json support so you don’t actually need to follow these steps, but for the sake of demonstrating how to add a loader, we’ll pretend Quasar doesn’t offer it.

So, you need a loader for it. You search Google to see what webpack loader you need. In this case, it’s “json-loader”. We first install it:

$ yarn add --dev json-loader

After installing your new loader, we want to tell Webpack to use it. So we edit /quasar.conf.js and change build.extendWebpack() to add entries to module/rules for this new loader:

// quasar.conf
build: {
  extendWebpack (cfg) {
    cfg.module.rules.push({
      test: /\.json$/,
      loader: 'json-loader'
    })
  }
}

Equivalent with chainWebpack():

// quasar.conf
build: {
  chainWebpack (chain) {
    chain.module.rule('json')
      .test(/\.json$/)
      .use('json-loader')
        .loader('json-loader')
  }
}

And you’re done.

SASS/SCSS

So you want to be able to write SASS/SCSS CSS code. You need a loader for it. We first install it. Note that for this particular case you also need to install node-sass because sass-loader depends on it as a peer dependency.

$ yarn add --dev sass-loader node-sass

And you’re done. For SCSS/SASS it’s all it takes. You don’t need to further configure /quasar.conf.js.

Once installed, you can use this pre-processor inside your *.vue components using the lang attribute on <style> tags:

<style lang="scss">
/* We can write SASS now! */
</style>

A note on SASS syntax:

  • lang=“scss” corresponds to the CSS-superset syntax (with curly braces and semicolons).
  • lang=“sass” corresponds to the indentation-based syntax.

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 /.postcssrc.js where you can tweak it if you need to.

Pug

First, you need to install some dependencies:

$ yarn add --dev pug pug-plain-loader

Then you need to extend the webpack configuration through quasar.conf.js:

// quasar.conf.js
build: {
  extendWebpack (cfg) {
    cfg.module.rules.push({
      test: /\.pug$/,
      loader: 'pug-plain-loader'
    })
  }
}

Equivalent with chainWebpack():

// quasar.conf.js
build: {
  chainWebpack (chain) {
    chain.module.rule('pug')
      .test(/\.pug$/)
      .use('pug-plain-loader')
        .loader('pug-plain-loader')
  }
}

Coffeescript

If you are using Coffeescript then you need to EITHER disable ESLint OR tell ESLint which Vue components are using Coffeescript.

Note that vue-loader uses lang="coffee" to identify components which are using Coffeescript, but lang="coffee" is not recognizable for ESLint. Fortunately, ESLint (following traditional HTML) uses type="xxx" to identify the type of scripts. As long as a <script> tag has any type other than javascript, ESLint would mark the script as non-javascript, and skips linting it. Coffeescript’s convention is to use type="text/coffeescript" to identify itself. Therefore, in your Vue components which are using Coffeescript, using both lang and type to avoid ESLint warnings:

<template>
  ...
</template>
<script lang="coffee" type="text/coffeescript">
  ...
</script>