Development Tools

Testing your application is part of the web development. Nuxt.js helps you to make it as easy as possible.

End-to-End Testing

AVA is a powerful JavaScript testing framework, mixed with jsdom, we can use them to do end-to-end testing easily.

First, we need to add AVA and jsdom as development dependencies:

npm install --save-dev ava jsdom

Then add a test script to our package.json and configure AVA to compile files that we import into our tests.

"scripts": {
  "test": "ava",
},
"ava": {
  "require": [
    "babel-register"
  ]
},
"babel": {
  "presets": [
    "es2015"
  ]
}

We are going to write our tests in the test folder:

mkdir test

Let's say we have a page in pages/index.vue:

<template>
  <h1 class="red">Hello {{ name }}!</h1>
</template>

<script>
export default {
  data () {
    return { name: 'world' }
  }
}
</script>

<style>
.red {
  color: red;
}
</style>

When we launch our app with npm run dev and open http://localhost:3000, we can see our red Hello world! title.

We add our test file test/index.test.js:

import test from 'ava'
import { Nuxt, Builder } from 'nuxt'
import { resolve } from 'path'

// We keep a reference to Nuxt so we can close
// the server at the end of the test
let nuxt = null

// Init Nuxt.js and start listening on localhost:4000
test.before('Init Nuxt.js', async t => {
  const rootDir = resolve(__dirname, '..')
  let config = {}
  try { config = require(resolve(rootDir, 'nuxt.config.js')) } catch (e) {}
  config.rootDir = rootDir // project folder
  config.dev = false // production build
  nuxt = new Nuxt(config)
  await new Builder(nuxt).build()
  nuxt.listen(4000, 'localhost')
})

// Example of testing only generated html
test('Route / exits and render HTML', async t => {
  let context = {}
  const { html } = await nuxt.renderRoute('/', context)
  t.true(html.includes('<h1 class="red">Hello world!</h1>'))
})

// Example of testing via DOM checking
test('Route / exits and render HTML with CSS applied', async t => {
  const window = await nuxt.renderAndGetWindow('http://localhost:4000/')
  const element = window.document.querySelector('.red')
  t.not(element, null)
  t.is(element.textContent, 'Hello world!')
  t.is(element.className, 'red')
  t.is(window.getComputedStyle(element).color, 'red')
})

// Close the Nuxt server
test.after('Closing server', t => {
  nuxt.close()
})

We can now launch our tests:

npm test

jsdom has some limitations because it does not use a browser. However, it will cover most of our tests. If you want to use a browser to test your application, you might want to check out Nightwatch.js.

ESLint and Prettier

ESLint is a great tool to keep your code clean.

Prettier is a very popular code formatter.

You can add ESLint with Prettier pretty easily with Nuxt.js, first, you need to add the npm dependencies:

npm install --save-dev babel-eslint eslint eslint-config-prettier eslint-loader eslint-plugin-vue eslint-plugin-prettier prettier

Then, you can configure ESLint via a .eslintrc.js file in your root project directory:

module.exports = {
  root: true,
  env: {
    browser: true,
    node: true
  },
  parserOptions: {
    parser: 'babel-eslint'
  },
  extends: [
    "eslint:recommended",
    // https://github.com/vuejs/eslint-plugin-vue#priority-a-essential-error-prevention
    // consider switching to `plugin:vue/strongly-recommended` or `plugin:vue/recommended` for stricter rules.
    "plugin:vue/recommended",
    "plugin:prettier/recommended"
  ],
  // required to lint *.vue files
  plugins: [
    'vue'
  ],
  // add your custom rules here
  rules: {
    "semi": [2, "never"],
    "no-console": "off",
    "vue/max-attributes-per-line": "off",
    "prettier/prettier": ["error", { "semi": false }]
  }
}

Then, you can add a lint and lintfix scripts in your package.json:

"scripts": {
  "lint": "eslint --ext .js,.vue --ignore-path .gitignore .",
  "lintfix": "eslint --fix --ext .js,.vue --ignore-path .gitignore ."
}

You can now launch lint to just check for errors:

npm run lint

or lintfix to also fix those which are doable

npm run lintfix

ESLint will lint every of your JavaScript and Vue files while ignoring your ignored files defined in your .gitignore.

It is also recommended to enable ESLint at hot reloading mode via webpack. This way ESLint will run on save during npm run dev. Just add the following to your nuxt.config.js:

...
  /*
   ** Build configuration
  */
  build: {
   /*
    ** You can extend webpack config here
   */
   extend(config, ctx) {
      // Run ESLint on save
      if (ctx.isDev && ctx.isClient) {
        config.module.rules.push({
          enforce: "pre",
          test: /\.(js|vue)$/,
          loader: "eslint-loader",
          exclude: /(node_modules)/
        })
      }
    }
  }

One best practice is to add also "precommit": "npm run lint" in your package.json to lint your code automatically before commiting your code.

Caught a mistake or want to contribute to the documentation? Edit this page on GitHub!