/edit: I stripped the config completely to a minimum demonstrating the problem. I also uploaded a working project to GitHub that you can checkout, so you can see for yourself.
Problematic use case on GitHub: webpack-angular15-es6-karma (download 7z archive)
npm install
npm run build
npm run test
I know there are a couple of related questions, but the world is moving so fast and there are so many factors / dependencies that I'm not able to crack this problem with the current proposed solutions.
I have a webpack config that takes care of all my source code and it works great.
For testing, I reuse that config to take care of a single central entry script that loads both the sources and the test files. I could not find another way to import modules from my source code into my test code for testing.
Karma builds fine reusing my webpack config, but the browser reports an error as soon as it is opened.
The source code uses ES6 imports and webpack require statements.
package.json:
npm run build >>> webpack --config webpack.config.js --display-error-details --colors --progress
npm run test >>> karma start --single-run --no-auto-watch karma.config.js
{
"name": "ProblemDemo",
"scripts": {
"build": "rimraf dist && webpack --config webpack.config.js --display-error-details --colors --progress",
"test": "karma start --single-run --no-auto-watch karma.config.js"
},
"dependencies": {
"angular": "^1.5.7",
"angular-filter": "^0.5.8"
},
"devDependencies": {
"webpack": "1.13.1",
"html-loader": "0.4.3",
"babel-loader": "5.3.2",
"html-webpack-plugin": "1.6.1",
"rimraf": "^2.5.3",
"run-sequence": "1.1.2",
"jasmine-core": "^2.4.1",
"karma": "^0.13.19",
"karma-chrome-launcher": "^0.2.2",
"karma-coverage": "^0.5.3",
"karma-jasmine": "^0.3.6",
"karma-webpack": "^1.7.0",
"loader-utils": "^0.2.12"
}
}
karma.config.js:
module.exports = function (config) {
config.set({
browsers: ['Chrome'],
coverageReporter: {
reporters: [
{ type: 'html', subdir: 'html' },
{ type: 'lcovonly', subdir: '.' }
]
},
files: ['./tests.webpack.js'],
frameworks: ['jasmine'],
preprocessors: { './tests.webpack.js': ['webpack'] },
reporters: ['progress', 'coverage'],
webpack: configureWebpack()
});
function configureWebpack(webpackConfigFunction) {
var webpackConfig = require('./webpack.config');
webpackConfig.entry = undefined; // karma will pass the proper argument for entry
return webpackConfig;
}
};
As you can see I'm not using karma-babel plugins: I'm not sure why I would need those, seeing I already have a working build for code with import / require statements.
test_entry.js:
var testsContext = require.context('./test', true, /\.js$/);
testsContext.keys().forEach(testsContext);
var srcContext = require.context('./app', true, /\.js$/);
srcContext.keys().forEach(srcContext);
The webpack build succeeds without a hitch (and emits test_entry.js chunk of expected file size), but then Karma opens Chrome and as soon as the page is loaded I'm greeted with the following error:
Chrome 51.0.2704 (Windows 7 0.0.0) ERROR
Uncaught SyntaxError: Unexpected token import
at the_path/test_entry.js:41
test_entry.js doesn't have 41 lines and doesn't contain import statements and anyway they should have been taken care of. What's going wrong?
In case you want to know the webpack config as well:
// webpack.config.js, works perfectly for normal builds but not with Karma
var path = require('path');
var webpack = require('webpack');
var HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
debug: true,
entry: {
app: ['./app/index.js'],
vendor: ['./app/vendor.js']
},
output: {
path: path.join(__dirname, 'dist'),
filename: 'js/[name].js'
},
plugins: [
new HtmlWebpackPlugin({
template: './app/index.html',
inject: 'body',
minify: false
}),
new webpack.optimize.CommonsChunkPlugin('vendor', 'js/vendor.js'),
new webpack.SourceMapDevToolPlugin({
filename: '[file].map',
exclude: /vendor/
})
],
resolve: {
extensions: ['', '.js'],
alias: {
app: path.join(__dirname, 'app')
}
},
module: {
loaders: [
{
test: /\.js$/,
loader: 'babel-loader',
include: path.join(__dirname, 'app'),
exclude: path.join(__dirname, 'node_modules')
},
{
test: /\.html$/,
loader: 'html-loader'
}
]
},
resolveLoader: {
root: path.join(__dirname, 'node_modules')
},
};
In case you want to see my test, required by test_entry.js, which I can't get to run:
import jasmine from 'jasmine-core';
import readableNumberFilter from './file_path/readableNumber.filter';
// for some reason needed, or else unexpected token errors during build:
var describe = jasmine.describe;
var it = jasmine.it;
var expect = jasmine.expect;
describe('readableNumber Filter', function () {
describe('readableNumber Filter formatting', () => {
it('it should support optional arguments', function () {
expect(readableNumberFilter("50.3")).toEqual("50,30");
});
});
});
edit 20-7-2016
The problem persists with updated babel-loader dependencies as well (including setting es2015 presets option). "babel-core": "^6.11.4", "babel-loader": "^6.2.4", "babel-preset-es2015": "^6.9.0",