Skip to content

Instantly share code, notes, and snippets.

@ivawzh
Last active October 25, 2016 07:47
Show Gist options
  • Save ivawzh/666079a397e12fd5ad8bf775c3e169b2 to your computer and use it in GitHub Desktop.
Save ivawzh/666079a397e12fd5ad8bf775c3e169b2 to your computer and use it in GitHub Desktop.
Babel & Jest setup 2016/10/21

Babel setup with Jest test

@ package.json

"devDependencies": {
    "babel-cli": "^6.16.0",                        // for production build
    "babel-jest": "^16.0.0",                       // for Jest test with ES6
    "babel-plugin-transform-runtime": "^6.15.0",   // for Babel Register. Because babel only handle syntax translation, but not provide                                                    // missing APIs from old javascript like `Array.includes`.
                                                   // `Promise`, `Set`, `Map`, or instance methods like `String.repeat` or
    "babel-runtime": "^6.11.6",                    // for babel-jest and maybe babel-plugin-transform-runtime
    "babel-preset-latest": "^6.16.0",              // the preset that includes 'es2015', 'es2016' and 'es2017', which includes async function, but not decorator!
    "babel-register": "^6.16.3",                   // Babel on the fly compilation in runtime(a.k.a Require Hook)
    "jest": "^16.0.2"
},
"dependencies": {},
"scripts": {
    "test": "./node_modules/.bin/jest",
    "test-watch": "npm test -- --watch --onlyChanged",
    "test-coverage": "npm test -- --coverage",
    "build": "NODE_ENV=production ./node_modules/.bin/babel src -d dist --ignore */__tests__/*"      // build distribution-ready es5 code. Code will be at /dist/ folder.
},
"jest": {
    "automock": true,
    "rootDir": "",
    "unmockedModulePathPatterns": [
      "<rootDir>/node_modules/lodash/"
    ],
    "testPathDirs": [
      "<rootDir>/src/"                              // set what path to look for tests. Do not set this to root, otherwise it will look through `.node-modules`
    ],
    "testEnvironment": "node",                      // indicate this is backend node js project. no browser considerations, won't load `JsDOM`. 
    "testRegex": ".*/__tests__/.*\\.spec\\.js$",
    "modulePathIgnorePatterns": [
      "examples/.*",
      "dist/.*"
    ],
    "scriptPreprocessor": "<rootDir>/node_modules/babel-jest",
    "collectCoverageFrom": [
      "!**/bin/**",
      "!dist/**",
      "!**/cli/**",
      "!**/vendor/**",
      "!**/__mocks__/**",
      "!**/__tests__/**"
    ],
    "coverageReporters": [
      "json"
    ],
    "testPathIgnorePatterns": [
      "/node_modules/",
      "/dist/"
    ],
    "verbose": true                                 // shows test descriptions
  }
@ .babaelrc

{
    "presets": ["latest"],                          // to use preset `babel-preset-latest`
    "plugins": ["transform-runtime"]                // to use `babel-plugin-transform-runtime` to support `babel-register` require hook
}
@ babel-runtime.js

var fs = require('fs')
var babelrc = fs.readFileSync('./.babelrc')

try {
  config = JSON.parse(babelrc)
} catch (err) {
  console.error('==>     ERROR: Error parsing your .babelrc.')
  console.error(err)
}

// runtime compile from ES6+ to ES5

require('babel-register')
@ /bin/go.js

#!/usr/bin/env node

require('../babel-runtime.js')

// now, the following required files will support ES6+

require('../something-written-with-es6').default() // works

// however, inside `go.js` itself, you have to use your environment node version. i.e. no ES6 in this file.

const { a, b } = { a: 1, b: 2 } // Syntax error, cannot support ES6 in this file.  

Babel Cli vs Babel Core vs Babel register

Babel Cli is used via cli comand to transiple ES5. Babel Core is Node API, which can be used inside the NodeJs code to trigger transpilation. Babel register is for require hook (transiple in runtime on the fly).

Babel Polyfill vs Babel runtime

Why do you need them? Because default Babel only handle syntaxic transpilation but not giving magical ES6 functions like generator function, Promise, Array.include, etc.

Babel Polyfill is for require hook (like babel register, require('babel-register') and require('babel-polyfill')). Babel-runtime is for Babel-cli, that goes with .babelrc "plugins": ["transform-runtime"].

@ivawzh
Copy link
Author

ivawzh commented Oct 22, 2016

If you see very slow tests:

  1. make sure Jest test is not searching for the whole project that includes node-modules
  2. make sure NPM version is not 2.x.x. Update it to at least 3.0+, by:
sudo npm uninstall npm -g
npm install npm@latest -g
rm -rf node_modules
npm install
npm dedupe

@ivawzh
Copy link
Author

ivawzh commented Oct 25, 2016

There is a bug on Jest 16.0.2. It cannot load Firebase with Jest config "testEnvironment": "node",. Removing it will fix the problem for now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment