Javascript tools painful party (karma vs babel vs webpack) or how to start to migrate coffee to es6 and not give up.

Intro

We have a frontend project which has a legacy CoffeeScript and already integrated webpack (1.x version). This is 2k17 and we decided to integrate babel and es6 to our codebase, but do not rewrite whole application completely from scratch (because our code is still maintainable and well written).

We follow the idea to integrate babel with a small short plan:

  1. Integrate babel to webpack.
  2. Transfer one simple code file and spec from coffee to es6.
  3. Take a mojito.
yarn add babel-loader babel-core babel-preset-es2015
...
module: {
loaders: [
{test: /\.cjsx$/, loaders: ["coffee", "cjsx"]},
{test: /\.coffee$/, loader: "coffee"},
{
test: /\.js$/, loader: "babel-loader",
include: [ path.join(__dirname, 'src') ],
query: { presets: ['es2016'] }
}
]
}
...
export const THUMBNAIL_VIEW = 'THUMBNAIL_VIEW'
export const TABLE_VIEW = 'TABLE_VIEW'
export const SET_VIEW_MODE = 'SET_VIEW_MODE'
export function setViewMode(viewMode) {
return { type: SET_VIEW_MODE, viewMode }
}

Karma.

Everything compiles and works great you prepared to open a pull request on Github. Just need one trivial procedure before I will go home, just one simple detail which I do not cover yet… tests… hm… ok, “I think I will write some boilerplate lines to our karma config it should be simple then took some candy from baby”.

karma.set({
frameworks: [ 'jasmine' ],
files: [
'spec/test.webpack.js'
],
captureConsole: true,
preprocessors: {
'spec/test.webpack.js': ['webpack', 'sourcemap']
},
webpack: require('./webpack.karma.config.js'),
});
spec/test.webpack.js
...
var req = require.context('.', true,/(\.cjsx|\.coffee)$/);
req.keys().forEach(req);
...

Just simple googling showed us that it has only one solution how to integrate babel to your karma: babel-preprocessor.

After reading documentation the decision was just to try babel-preprocessor and webpack preprocessor together and it did not work for me.

...
module: {
loaders: [
{test: /\.cjsx$/, loaders: ["coffee", "cjsx"]},
{test: /\.coffee$/, loader: "coffee"},
{
test: /\.js$/, loader: "babel-loader",
include: [
path.join(__dirname, 'src'),
path.join(__dirname, 'spec')
],
query: { presets: ['es2016'] }
}
]
}
...
yarn test
...
SyntaxError: Use of reserved word ‘export’
...
or
...
SyntaxError: Use of reserved word ‘import’
...

The Internet should help me!

I found millions of issues everywhere like “Do not use include”, “It is internal karma problem” and answers were completely different.

I experimented, change something, run, the same error, change, run, the same error. Sounds very common, isn’t it?

Logically, I realized the problems is probably in transpilation and this process seeded in webpack that gave us thought that is the problem of babel. After research on the internet, I did not find proper answer but I decided to downgrade es2016 preset to es2015(Just randomly, because there are no so much examples with es2016)

query: { presets: [‘es2015’] }

Tips which can save your time on 13.1.2017 with karma, babel and webpack.

  1. Bring babel-loader into webpack and use webpack preprocessor, instead of bringing 2 preprocessors (babel and webpack) to Karma.
  2. Use presets: [‘es2015’] instead of es2016 it did not work for me out of the box and I do not wanna go internal to find details why.
  3. Use include directive in babel loader to avoid loading all js and load only what you need:
include: [path.join(__dirname, ‘src’), path.join(__dirname, ‘spec')]
var req = require.context('.', true,/(\.cjsx|\.coffee|\_spec.js)$/);
req.keys().forEach(req);
...

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Wowa Barsukov

Wowa Barsukov

Impactful Entrepreneur. Music producer and podcaster. TypeScript and React expert.