Skip to content

Commit a8714cf

Browse files
author
Justin Helmer
committed
feat: support for babelConfig and tsConfig
- babelConfig/tsConfig can take a boolean (config file lookup), object (inline config options), or string (path to config file) - deprecated babelRcFile and tsConfigFile options - Matches ts-jest API for babelConfig/tsConfig, with the exception that the default behavior for babelConfig is switched (enabled) - Not a breaking change
1 parent b40094f commit a8714cf

5 files changed

+321
-23
lines changed

README.md

Lines changed: 130 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -57,28 +57,154 @@ vue-jest compiles the script and template of SFCs into a JavaScript file that Je
5757
- **typescript** (`lang="ts"`, `lang="typescript"`)
5858
- **coffeescript** (`lang="coffee"`, `lang="coffeescript"`)
5959

60-
To define a tsconfig file that vue-jest will use when transpiling typescript, you can specify it in the jest globals
60+
### Global Jest options
61+
62+
You can change the behavior of `vue-jest` by using `jest.globals`.
63+
64+
> *Tip:* Need programmatic configuration? Use the [--config](https://jestjs.io/docs/en/cli.html#config-path) option in Jest CLI, and export a `.js` file
65+
66+
#### babelConfig
67+
68+
Provide `babelConfig` in one of the following formats:
69+
70+
- `<Boolean>`
71+
- `<Object>`
72+
- `<String>`
73+
74+
##### Boolean
75+
76+
- `true` - Enable Babel processing. `vue-jest` will try to find Babel configuration using [find-babel-config](https://www.npmjs.com/package/find-babel-config).
77+
78+
> This is the default behavior if [babelConfig](#babelconfig) is not defined.
79+
80+
- `false` - Skip Babel processing entirely:
81+
82+
```json
83+
{
84+
"jest": {
85+
"globals": {
86+
"vue-jest": {
87+
"babelConfig": false
88+
}
89+
}
90+
}
91+
}
92+
```
93+
94+
##### Object
95+
96+
Provide inline [Babel options](https://babeljs.io/docs/en/options):
97+
98+
```json
99+
{
100+
"jest": {
101+
"globals": {
102+
"vue-jest": {
103+
"babelConfig": {
104+
"presets": [
105+
[
106+
"env",
107+
{
108+
"useBuiltIns": "entry",
109+
"shippedProposals": true
110+
}
111+
]
112+
],
113+
"plugins": [
114+
"syntax-dynamic-import"
115+
],
116+
"env": {
117+
"test": {
118+
"plugins": [
119+
"dynamic-import-node"
120+
]
121+
}
122+
}
123+
}
124+
}
125+
}
126+
}
127+
}
128+
```
129+
130+
##### String
131+
132+
If a string is provided, it will be an assumed path to a babel configuration file (e.g. `.babelrc`, `.babelrc.js`).
133+
- Config file should export a Babel configuration object.
134+
- Should *not* point to a [project-wide configuration file (babel.config.js)](https://babeljs.io/docs/en/config-files#project-wide-configuration), which exports a function.
61135

62136
```json
63137
{
64138
"jest": {
65139
"globals": {
66140
"vue-jest": {
67-
"tsConfigFile": "tsconfig.jest.json"
141+
"babelConfig": "path/to/.babelrc.js"
68142
}
69143
}
70144
}
71145
}
72146
```
73147

74-
To define a babelrc file that vue-jest will use when transpiling javascript, you can specify it in the jest globals
148+
To use the [Config Function API](https://babeljs.io/docs/en/config-files#config-function-api), use inline options instead. i.e.:
149+
150+
```json
151+
{
152+
"jest": {
153+
"globals": {
154+
"vue-jest": {
155+
"babelConfig": {
156+
"configFile": "path/to/babel.config.js"
157+
}
158+
}
159+
}
160+
}
161+
}
162+
```
163+
164+
#### tsConfig
165+
166+
Provide `tsConfig` in one of the following formats:
167+
168+
- `<Boolean>`
169+
- `<Object>`
170+
- `<String>`
171+
172+
##### Boolean
173+
174+
- `true` - Process TypeScript files using custom configuration. `vue-jest` will try to find TypeScript configuration using [tsconfig.loadSync](https://www.npmjs.com/package/tsconfig#api).
175+
176+
> This is the default behavior if [tsConfig](#tsConfig) is not defined.
177+
178+
- `false` - Process TypeScript files using the [default configuration provided by vue-jest](https://github.com/vuejs/vue-jest/blob/master/lib/load-typescript-config.js#L5-L27).
179+
180+
##### Object
181+
182+
Provide inline [TypeScript compiler options](https://www.typescriptlang.org/docs/handbook/compiler-options.html):
183+
184+
```json
185+
{
186+
"jest": {
187+
"globals": {
188+
"vue-jest": {
189+
"tsConfig": {
190+
"importHelpers": true
191+
}
192+
}
193+
}
194+
}
195+
}
196+
```
197+
198+
##### String
199+
200+
If a string is provided, it will be an assumed path to a TypeScript configuration file:
75201

76202
```json
77203
{
78204
"jest": {
79205
"globals": {
80206
"vue-jest": {
81-
"babelRcFile": "jest.babelrc"
207+
"tsConfig": "path/to/tsconfig.json"
82208
}
83209
}
84210
}

lib/load-babel-config.js

Lines changed: 36 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,22 @@
11
const findBabelConfig = require('find-babel-config')
22
const logger = require('./logger')
33
const cache = require('./cache')
4+
const deprecate = require('./deprecate')
45
const path = require('path')
56
const { readFileSync, existsSync } = require('fs')
67

78
module.exports = function getBabelConfig (vueJestConfig, filePath) {
9+
const find = () => {
10+
const { file, config } = findBabelConfig.sync(filePath || process.cwd())
11+
12+
if (!file) {
13+
logger.info('no .babelrc found, skipping babel compilation')
14+
cache.set('babel-config', false)
15+
return
16+
}
17+
18+
return config
19+
}
820
const cachedConfig = cache.get('babel-config')
921
if (cachedConfig) {
1022
return cachedConfig
@@ -14,22 +26,37 @@ module.exports = function getBabelConfig (vueJestConfig, filePath) {
1426
let babelConfig
1527

1628
if (vueJestConfig.babelRcFile) {
29+
deprecate.replace('babelRcFile', 'babelConfig')
1730
babelConfig = JSON.parse(readFileSync(vueJestConfig.babelRcFile))
1831
} else if (existsSync('babel.config.js')) {
1932
babelConfig = require(path.resolve('babel.config.js'))
20-
} else {
21-
const { file, config } = findBabelConfig.sync(filePath || process.cwd())
22-
23-
if (!file) {
24-
logger.info('no .babelrc found, skipping babel compilation')
25-
cache.set('babel-config', false)
26-
return
33+
} else if (vueJestConfig.hasOwnProperty('babelConfig')) {
34+
switch (typeof vueJestConfig.babelConfig) {
35+
case 'string':
36+
// a path to a config file is being passed in; load it
37+
babelConfig = require(vueJestConfig.babelConfig)
38+
break
39+
case 'boolean':
40+
// if babelConfig is true, search for it. If false, will end up
41+
// returning undefined which results in no babel processing
42+
if (vueJestConfig.babelConfig === true) {
43+
babelConfig = find()
44+
}
45+
break
46+
case 'object':
47+
default:
48+
// support for inline babel options
49+
babelConfig = vueJestConfig.babelConfig
50+
break
2751
}
52+
} else {
53+
babelConfig = find()
54+
}
2855

29-
babelConfig = config
56+
if (babelConfig) {
57+
cache.set('babel-config', babelConfig)
3058
}
3159

32-
cache.set('babel-config', babelConfig)
3360
return babelConfig
3461
}
3562
}

lib/load-typescript-config.js

Lines changed: 33 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
const tsconfig = require('tsconfig')
22
const cache = require('./cache')
3+
const deprecate = require('./deprecate')
34
const logger = require('./logger')
45

56
const defaultTypescriptConfig = {
@@ -27,22 +28,47 @@ const defaultTypescriptConfig = {
2728
}
2829

2930
module.exports.loadTypescriptConfig = function loadTypescriptConfig (vueJestConfig) {
31+
const find = () => {
32+
const { path, config } = tsconfig.loadSync(process.cwd())
33+
34+
if (!path) {
35+
logger.info('no tsconfig.json found, defaulting to default typescript options')
36+
}
37+
38+
return path ? config : defaultTypescriptConfig
39+
}
3040
const cachedConfig = cache.get('typescript-config')
3141
if (cachedConfig) {
3242
return cachedConfig
3343
} else {
3444
let typescriptConfig
3545

3646
if (vueJestConfig.tsConfigFile) {
47+
deprecate.replace('tsConfigFile', 'tsConfig')
3748
typescriptConfig = tsconfig.readFileSync(vueJestConfig.tsConfigFile)
38-
} else {
39-
const { path, config } = tsconfig.loadSync(process.cwd())
40-
41-
if (!path) {
42-
logger.info('no tsconfig.json found, defaulting to default typescript options')
49+
} else if (vueJestConfig.hasOwnProperty('tsConfig')) {
50+
switch (typeof vueJestConfig.tsConfig) {
51+
case 'string':
52+
// a path to a config file is being passed in; load it
53+
typescriptConfig = require(vueJestConfig.tsConfig)
54+
break
55+
case 'boolean':
56+
// if tsConfig is true, search for it
57+
if (vueJestConfig.tsConfig === true) {
58+
typescriptConfig = find()
59+
} else {
60+
// use default typescript options
61+
typescriptConfig = defaultTypescriptConfig
62+
}
63+
break
64+
case 'object':
65+
default:
66+
// support for inline typescript options
67+
typescriptConfig = vueJestConfig.tsConfig
68+
break
4369
}
44-
45-
typescriptConfig = path ? config : defaultTypescriptConfig
70+
} else {
71+
typescriptConfig = find()
4672
}
4773

4874
cache.set('typescript-config', typescriptConfig)

test/load-babel-config.spec.js

Lines changed: 58 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import findBabelConfig from 'find-babel-config'
12
import loadBabelConfig from '../lib/load-babel-config'
23
import { resolve } from 'path'
34
import {
@@ -10,6 +11,7 @@ import {
1011
} from 'fs'
1112
import clearModule from 'clear-module'
1213
import cache from '../lib/cache'
14+
import deprecate from '../lib/deprecate'
1315

1416
describe('load-babel-config.js', () => {
1517
beforeEach(() => {
@@ -38,7 +40,10 @@ describe('load-babel-config.js', () => {
3840
expect(babelConfigCached).toBe(undefined)
3941
})
4042

41-
it('reads babelrc from jest globals if exists', () => {
43+
it('[DEPRECATED] reads babelrc from jest globals if exists', () => {
44+
const replace = deprecate.replace
45+
deprecate.replace = jest.fn()
46+
4247
const jestGlobalBabelPath = resolve(__dirname, '../jest.babelrc')
4348
writeFileSync(jestGlobalBabelPath, JSON.stringify({
4449
plugins: ['foo']
@@ -48,7 +53,9 @@ describe('load-babel-config.js', () => {
4853
babelRcFile: 'jest.babelrc'
4954
})
5055
expect(babelConfig).toEqual(jestGlobalBabelConfig)
56+
expect(deprecate.replace).toHaveBeenCalledWith('babelRcFile', 'babelConfig')
5157
unlinkSync(jestGlobalBabelPath)
58+
deprecate.replace = replace
5259
})
5360

5461
it('reads default babel if there is .babelrc', () => {
@@ -103,4 +110,54 @@ describe('load-babel-config.js', () => {
103110
expect(babelConfig).toEqual(config)
104111
unlinkSync(babelConfigPath)
105112
})
113+
114+
describe('babelConfig option', () => {
115+
it('supports a path to a babel configuration file', () => {
116+
const babelConfigPath = resolve(__dirname, '../some-babel-config.js')
117+
const config = {
118+
plugins: ['foo']
119+
}
120+
writeFileSync(babelConfigPath, `module.exports = ${JSON.stringify(config)}`)
121+
const babelConfig = loadBabelConfig({
122+
babelConfig: babelConfigPath
123+
})
124+
expect(babelConfig).toEqual(config)
125+
})
126+
127+
it('supports a boolean indicating whether or not to search for babel config', () => {
128+
const config = {
129+
plugins: ['foo']
130+
}
131+
findBabelConfig.sync = jest.fn(() => ({ file: true, config }))
132+
const noBabelConfig = loadBabelConfig({
133+
babelConfig: false
134+
})
135+
expect(findBabelConfig.sync).not.toHaveBeenCalled()
136+
expect(noBabelConfig).toBeUndefined()
137+
138+
const babelConfig = loadBabelConfig({
139+
babelConfig: true
140+
})
141+
expect(findBabelConfig.sync).toHaveBeenCalled()
142+
expect(babelConfig).toEqual(config)
143+
findBabelConfig.sync.mockRestore()
144+
})
145+
146+
it('supports an inline babel configuration object', () => {
147+
const config = {
148+
plugins: ['foo']
149+
}
150+
const babelConfig = loadBabelConfig({
151+
babelConfig: config
152+
})
153+
expect(babelConfig).toEqual(config)
154+
})
155+
156+
it('defaults to searching for babel config if option is not provided', () => {
157+
findBabelConfig.sync = jest.fn(() => ({}))
158+
loadBabelConfig({})
159+
expect(findBabelConfig.sync).toHaveBeenCalled()
160+
findBabelConfig.sync.mockRestore()
161+
})
162+
})
106163
})

0 commit comments

Comments
 (0)