https://github.com/60frames/jestpack
Jest Webpack Integration
https://github.com/60frames/jestpack
Last synced: 9 months ago
JSON representation
Jest Webpack Integration
- Host: GitHub
- URL: https://github.com/60frames/jestpack
- Owner: 60frames
- License: mit
- Created: 2015-09-05T22:22:32.000Z (over 10 years ago)
- Default Branch: master
- Last Pushed: 2016-03-31T21:37:06.000Z (almost 10 years ago)
- Last Synced: 2025-04-21T18:52:35.474Z (9 months ago)
- Language: JavaScript
- Homepage:
- Size: 61.5 KB
- Stars: 66
- Watchers: 6
- Forks: 3
- Open Issues: 7
-
Metadata Files:
- Readme: README.md
- License: LICENSE.md
Awesome Lists containing this project
README
# Jestpack [](https://travis-ci.org/60frames/jestpack) [](https://badge.fury.io/js/jestpack)
Unfortunately [Jest doesn't play nicely with Webpack](http://stackoverflow.com/questions/31547587/testing-webpack-built-react-components-with-jest), especially when using some of Webpack's more useful features such as [loaders](http://webpack.github.io/docs/loaders.html) or [code splitting](http://webpack.github.io/docs/code-splitting.html).
Jestpack attempts to solve this problem by ~~extending~~ replacing Jest's default module loader to support Webpack's internal module system.
## Installation
`npm install jestpack --save-dev`
> NOTE: Jestpack >=0.2.0 depends on Node >=5.x.x.
> NOTE: Jestpack declares both `jest-cli` and `webpack` as peer dependencies meaning you must declare them both as either `devDependencies` or `dependencies` in your projects `package.json`.
> NOTE: Jestpack doesn't currently support Jest 0.8.x https://github.com/60frames/jestpack/issues/12
## Setup
Jestpack works by supplying pre-built test files to Jest so the first thing you'll want to do is tell Jest where it can expect to find your soon-to-be-bundled test files:
```js
// package.json
{
...
"jest": {
"testPathDirs": ["/__bundled_tests__"]
}
}
```
Then you'll need to get Jest to use the Jestpack module loader:
```js
// package.json
{
...
"jest": {
...
"moduleLoader": "/node_modules/jestpack/ModuleLoader",
}
}
```
Now you're ready to setup your Webpack config by first specifiying the output directory:
```js
// webpack.config.js
module.exports = {
output: {
path: '__bundled_tests__',
filename: '[name].js'
}
}
```
And then getting Webpack to build each test as a separate entry point:
```js
// webpack.config.js
module.exports = {
...
entry: {
'src/__tests__/test1': './src/__tests__/test1',
'src/__tests__/test2': './src/__tests__/test2',
'src/__tests__/test3': './src/__tests__/test3'
// etc.
}
}
```
> NOTE: Using a separate entry point per test suite allows Jest to run your tests in parallel processes!
> NOTE: The /example demonstrates how the entry points could be dynamically generated.
If you intend to define manual `__mocks__` then you need to run your modules through the manual mock loader:
```js
// webpack.config.js
module.exports = {
...
preLoaders: [
{
test: /\.js$/,
loader: 'jestpack/ManualMockLoader'
}
]
}
```
Finally, you need to apply the Jestpack plugin which transforms Jest's CommonJs API calls into something Webpack can understand, i.e. `jest.dontMock('../foo')` becomes `jest.dontMock(1)`:
```js
// webpack.config.js
var JestpackPlugin = require('jestpack/Plugin');
module.exports = {
...
plugins: [
new JestpackPlugin()
]
}
```
And save the `stats.json` in the root of your `config.testPathDirs` directory. So in this case `__bundled_tests__/stats.json`:
```js
// webpack.config.js
var StatsWebpackPlugin = require('stats-webpack-plugin');
module.exports = {
...
plugins: [
...
new StatsWebpackPlugin('stats.json')
]
}
```
Tests can then be run by building your tests and running Jest:
`webpack && jest`
> NOTE: A complete working configuration can be found in the /example directory.
### Optimization
Depending on the number of modules in your dependency graph you may experience *incredibly* slow builds when building a separate entry point per test suite. This can be greatly optimized using Webpack's [`CommonsChunkPlugin`](http://webpack.github.io/docs/list-of-plugins.html#commonschunkplugin):
```js
// webpack.config.js
var webpack = require('webpack');
modle.exports = {
...
plugins: [
...
// This is telling Webpack to extract all dependencies that are used by 2 or more modules into '__bundled_tests__/common.js'
new webpack.optimize.CommonsChunkPlugin({
filename: 'common.js',
minChunks: 2
})
]
}
```
Which can then be included via Jest's [`config.setupEnvScriptFile`](https://facebook.github.io/jest/docs/api.html#config-setupenvscriptfile-string):
```js
// package.json
{
...
"jest": {
...
"setupEnvScriptFile": "/__bundled_tests__/common.js"
}
}
```
In addition, if you actually need to do some environment setup you can get the common chunk to execute an entry point like this:
```js
// webpack.config.js
module.exports = {
...
entry: {
...
setup: './setup.js'
},
...
plugins: [
...
// When the common.js chunk is included it will execute the 'setup' entry point.
new webpack.optimize.CommonsChunkPlugin({
name: 'setup',
filename: 'common.js',
minChunks: 2
})
]
}
```
If you need to do some setup after Jasmine has loaded, e.g. define some global matchers, then you can use Jest's [`config.setupTestFrameworkScriptFile`](https://facebook.github.io/jest/docs/api.html#config-setuptestframeworkscriptfile-string) instead:
```js
// package.json
{
...
"jest": {
...
"setupTestFrameworkScriptFile": "/__bundled_tests__/common.js"
}
}
```
### Tips
If you're using the [babel-loader](https://github.com/babel/babel-loader) it's best not to include the runtime. If for some reason you need to then make sure it's in Jest's [`config.unmockedModulePathPatterns`](https://facebook.github.io/jest/docs/api.html#config-unmockedmodulepathpatterns-array-string):
```js
// package.json
{
...
"jest": {
...
"unmockedModulePathPatterns": [
...
"/node_modules/babel-runtime"
]
}
}
```
If you're using [code splitting](http://webpack.github.io/docs/code-splitting.html) then you're better off disabling it for tests with Webpack's [`LimitChunkCountPlugin`](https://github.com/webpack/docs/wiki/list-of-plugins#limitchunkcountplugin):
```js
// webpack.config.js
var webpack = require('webpack');
module.exports = {
...
plugins: [
...
new webpack.optimize.LimitChunkCountPlugin({
maxChunks: 1
})
]
}
```
If you're using [css modules](https://github.com/webpack/css-loader#css-modules) you'll need to add the loader to Jest's [`config.unmockedModulePathPatterns`](https://facebook.github.io/jest/docs/api.html#config-unmockedmodulepathpatterns-array-string):
```js
// package.json
{
...
"jest": {
...
"unmockedModulePathPatterns": [
...
"/node_modules/css-loader"
]
}
}
```
## Current Limitations
- Code coverage isn't supported.