Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Laravel + VueJs + Webpack + Karma = world of pain

Is it possible to write unit tests for VueJs if you are using Laravel's Elixir for your webpack configuration?

VueJs 2x has a very simple example for a component test: Vue Guide Unit testing

<template>
  <span>{{ message }}</span>
</template>
<script>
  export default {
    data () {
      return {
        message: 'hello!'
      }
    },
    created () {
      this.message = 'bye!'
    }
  }
</script>

and then...

// Import Vue and the component being tested
import Vue from 'vue'
import MyComponent from 'path/to/MyComponent.vue'

describe('MyComponent', () => {
  it('has a created hook', () => {
    expect(typeof MyComponent.created).toBe('function')
  })
  it ...etc
})

and gives an example of a karma conf file here: https://github.com/vuejs-templates

But the Karma configuration file requires a webpack configuration file

webpack: webpackConfig,

The only problem is the Laravel's Elixir is creating the webpack configuration so it can't be included.

I have tried creating another webpack configuration file based on the example from https://github.com/vuejs-templates/webpack.

Something like this:

var path = require('path');
var webpack = require('webpack');

module.exports = {
    entry: './src/main.js',
    output: {
        path: path.resolve(__dirname, './dist'),
        publicPath: '/dist/',
        filename: 'build.js'
    },
    module: {
        rules: [
            {
                test: /\.vue$/,
                loader: 'vue-loader',
                options: {
                    loaders: {
                        // Since sass-loader (weirdly) has SCSS as its default parse mode, we map
                        // the "scss" and "sass" values for the lang attribute to the right configs here.
                        // other preprocessors should work out of the box, no loader config like this necessary.
                        'scss': 'vue-style-loader!css-loader!sass-loader',
                        'sass': 'vue-style-loader!css-loader!sass-loader?indentedSyntax'
                    }
                    // other vue-loader options go here
                }
            },
            {
                test: /\.js$/,
                loader: 'babel-loader',
                exclude: /node_modules/
            },
            {
                test: /\.(png|jpg|gif|svg)$/,
                loader: 'file-loader',
                options: {
                    name: '[name].[ext]?[hash]'
                }
            }
        ]
    },
    resolve: {
        alias: {
            'vue$': 'vue/dist/vue.esm.js'
        }
    },
    devServer: {
        historyApiFallback: true,
        noInfo: true
    },
    performance: {
        hints: false
    },
    devtool: '#eval-source-map'
}

and included it like...

// Karma configuration
// Generated on Wed Mar 15 2017 09:47:48 GMT-0500 (CDT)
var webpackConf = require('./karma.webpack.config.js');
delete webpackConf.entry;

module.exports = function(config) {
  config.set({

    webpack: webpackConf, // Pass your webpack.config.js file's content

    webpackMiddleware: {
      noInfo: true,
      stats: 'errors-only'
    },

But I am getting errors that seem to indicate that webpack isn't doing anything.

ERROR in ./resources/assets/js/components/test.vue
Module parse failed: /var/www/test/resources/assets/js/components/test.vue Unexpected token (1:0)
You may need an appropriate loader to handle this file type.
| <template>
|     <span >{{test}}</span>
| </template>
like image 351
Patrick_Finucane Avatar asked Nov 30 '25 16:11

Patrick_Finucane


1 Answers

Ok, I got this to work. Couple of things that might help.

I was originally running gulp, and trying to run tests in my vagrant box, to try to match the server configuration. I think that makes it much harder to find examples and answers on the internet.

Ok, so the main problem I was having is that webpack wasn't processing my components included in my test files. I copied the webpack config out of the laravel-elixir-vue-2/index.js node module directly into the Karma configuration file and it started working.

The key is that karma-webpack plugin needs both the resolve and module loader configuration settings (resolve with alias and extensions) for it to work.

Hope this helps someone.

karma.conf.js:

module.exports = function (config) {
  config.set({
    // to run in additional browsers:
    // 1. install corresponding karma launcher
    //    http://karma-runner.github.io/0.13/config/browsers.html
    // 2. add it to the `browsers` array below.
    browsers: ['Chrome'],
    frameworks: ['jasmine'],
    files: ['./index.js'],
    preprocessors: {
      './index.js': ['webpack']
    },
    webpack: {
      resolve: {
        alias: {
          vue: 'vue/dist/vue.common.js'
        },
        extensions: ['.js', '.vue']
      },
      vue: {
        buble: {
          objectAssign: 'Object.assign'
        }
      },
      module: {
        loaders: [
          {
            test: /\.vue$/,
            loader: 'vue-loader'
          },
          {
            test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
            loader: 'file-loader',
            query: {
              limit: 10000,
              name: '../img/[name].[hash:7].[ext]'
            }
          },
          {
            test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
            loader: 'url-loader',
            query: {
              limit: 10000,
              name: '../fonts/[name].[hash:7].[ext]'
            }
          }
        ]
      }
    },
    webpackMiddleware: {
      noInfo: true,
    },
    coverageReporter: {
      dir: './coverage',
      reporters: [
        { type: 'lcov', subdir: '.' },
        { type: 'text-summary' },
      ]
    },
  });
};
like image 178
Patrick_Finucane Avatar answered Dec 02 '25 06:12

Patrick_Finucane