wallabyjs / public

Repository for Wallaby.js questions and issues
http://wallabyjs.com
758 stars 45 forks source link

CoffeeScript 2 support #1417

Closed foxbunny closed 6 years ago

foxbunny commented 6 years ago

Issue description or question

Is CoffeeScript 2 supported? Either way how would I go about getting it to work with Wallaby and Jest?

With the configuration presented below, I get:

.\src\func.test.js:2
import {
^^^^^^
SyntaxError: Unexpected token import

The test file contains the now-supported import statement at the top:

import { 
  x, 
  y, 
  z.
} from './foo'

Wallaby.js configuration file

module.exports = (wallaby) => ({
  files: [
    'package.json',
    'src/**/*.*',
    '!src/**/*.test.coffee',
  ],
  tests: [
    'src/**/*.test.coffee',
  ],
  env: {
    type: 'node',
  },
  testFramework: 'jest',
  debug: true,
});

Additional, Jest config:

{
    "verbose": true,
    "testMatch": [
      "**/*.test.coffee"
    ],
    "moduleFileExtensions": [
      "coffee.md",
      "coffee",
      "litcoffee",
      "js"
    ],
    "transform": {
      "\\.coffee$": "<rootDir>/infra/coffee-processor.js",
      "\\.litcoffee$": "<rootDir>/infra/coffee-processor.js",
      "\\.coffee\\.md$": "<rootDir>/infra/coffee-processor.js"
    },
    "mapCoverage": true
  }

Processor looks like this:

const CoffeeScript = require('coffeescript')
const helpers = require('coffeescript/lib/coffeescript/helpers')

exports.process = (src, path) => {
  return CoffeeScript.compile(src, { 
    bare: true, 
    inlineMap: true, 
    filename: path,
    literate: helpers.isLiterate(path),
    transpile: {
      presets: ['env'],
    },
  })
}

Code editor or IDE name and version

Atom v1.22.1 x64

OS name and version

Windows 10 64-bit

ArtemGovorov commented 6 years ago

It should be supported.

By default Wallaby CoffeeScript compiler doesn't pass the transpile option, so CoffeeScript compiler emits ES6 module imports/exports as is (that are not supported by node, hence the error).

You may either configure babel preprocessor on top of the CoffeeScript compiler, or pass the transpile option to the Wallaby CoffeeScript compiler:

module.exports = (wallaby) => ({
  files: [
    'package.json',
    'src/**/*.*',
    '!src/**/*.test.coffee',
  ],
  tests: [
    'src/**/*.test.coffee',
  ],
+ compilers: {
+   '**/*.coffee': wallaby.compilers.coffeeScript({
+     transpile: {
+       presets: ['env'],
+     }
+   })
+ },
  env: {
    type: 'node',
  },
  testFramework: 'jest',
  debug: true,
});
foxbunny commented 6 years ago

Adding the compiler option worked, thanks! Now I have module resolution issue:

Error: Cannot find module './func' from 'func.test.js'
  at Object.<anonymous> src/func.test.coffee:1:0x

I have func.test.coffee sitting in the same directory as func.coffee.md. In Jest config, I have:

    "moduleFileExtensions": [
      "coffee.md",
      "coffee",
      "litcoffee",
      "js"
    ],

Any idea how I can fix this?

ArtemGovorov commented 6 years ago

Yep, by default Wallaby CoffeeScript compiler changes compiled file extension to .js, and it is ok for cases like foo.coffee, that becomes foo.js. But foo.coffee.md becomes foo.coffee.js and because coffee.js is not in the moduleFileExtensions, foo is not found.

The easiest way to make it work is to pass the noFileRename option to Wallaby CoffeeScript compiler. Note that I have also extended the compiler pattern (**/*.?(lit)coffee?(.md)) to include .litcoffee and coffee.md.

module.exports = (wallaby) => ({
  files: [
    'package.json',
    'src/**/*.*',
    '!src/**/*.test.coffee',
  ],
  tests: [
    'src/**/*.test.coffee',
  ],
+ compilers: {
+   '**/*.?(lit)coffee?(.md)': wallaby.compilers.coffeeScript({
+     transpile: {
+       presets: ['env'],
+     },
+     noFileRename: true
+   })
+ },
  env: {
    type: 'node',
  },
  testFramework: 'jest',
  debug: true,
});
foxbunny commented 6 years ago

I've added the noFileRename flag to the compiler options, but that caused the compiler to complain about var not being a keyword. I assume it tried to compile the file twice?

.\src\contexts.test.coffee:3:1: error: reserved word 'var'
var _contexts = ($_$w(3, 0), require('./contexts'));
^^^

I added this to the wallaby configuration, and that seems to work:

  setup: w => {
    const jestCfg = require('./package.json').jest
    jestCfg.moduleFileExtensions.push('coffee.js')
    w.testFramework.configure(jestCfg)
  },

I suppose switching to .litcoffee extension would probably work even better.

ArtemGovorov commented 6 years ago

Glad to hear you've found the working solution. Switching to .litcoffee extension is the best option.

but that caused the compiler to complain about var not being a keyword. I assume it tried to compile the file twice?

Yes, it is second Jest compilation of top of Wallaby one. This should work:

  setup: w => {
    const jestCfg = require('./package.json').jest
    delete jestCfg.transform; // <--
    w.testFramework.configure(jestCfg)
  },
foxbunny commented 6 years ago

Good to know. Do you plan on setting up a cookbook for edge cases like this one?

ArtemGovorov commented 6 years ago

We are handling the case automatically for TypeScript, should probably do the same for CoffeeScript. It's just you're the first one to hit it, very few of our users are using CoffeeScript these days.