Skip to content

Commit fff7ba9

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 89cd5f3 commit fff7ba9

5 files changed

+323
-23
lines changed

README.md

+132-4
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
Jest Vue transformer with source map support
44

5+
> **NOTE:** This is documentation for `[email protected]`. [View the [email protected] documentation](https://github.com/vuejs/vue-jest/tree/e694fc7ce11ae1ac1c778ed7c4402515c5f0d5aa)
6+
57
## Usage
68

79
```bash
@@ -57,28 +59,154 @@ vue-jest compiles the script and template of SFCs into a JavaScript file that Je
5759
- **typescript** (`lang="ts"`, `lang="typescript"`)
5860
- **coffeescript** (`lang="coffee"`, `lang="coffeescript"`)
5961

60-
To define a tsconfig file that vue-jest will use when transpiling typescript, you can specify it in the jest globals
62+
### Global Jest options
63+
64+
You can change the behavior of `vue-jest` by using `jest.globals`.
65+
66+
> *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
67+
68+
#### babelConfig
69+
70+
Provide `babelConfig` in one of the following formats:
71+
72+
- `<Boolean>`
73+
- `<Object>`
74+
- `<String>`
75+
76+
##### Boolean
77+
78+
- `true` - Enable Babel processing. `vue-jest` will try to find Babel configuration using [find-babel-config](https://www.npmjs.com/package/find-babel-config).
79+
80+
> This is the default behavior if [babelConfig](#babelconfig) is not defined.
81+
82+
- `false` - Skip Babel processing entirely:
83+
84+
```json
85+
{
86+
"jest": {
87+
"globals": {
88+
"vue-jest": {
89+
"babelConfig": false
90+
}
91+
}
92+
}
93+
}
94+
```
95+
96+
##### Object
97+
98+
Provide inline [Babel options](https://babeljs.io/docs/en/options):
6199

62100
```json
63101
{
64102
"jest": {
65103
"globals": {
66104
"vue-jest": {
67-
"tsConfigFile": "tsconfig.jest.json"
105+
"babelConfig": {
106+
"presets": [
107+
[
108+
"env",
109+
{
110+
"useBuiltIns": "entry",
111+
"shippedProposals": true
112+
}
113+
]
114+
],
115+
"plugins": [
116+
"syntax-dynamic-import"
117+
],
118+
"env": {
119+
"test": {
120+
"plugins": [
121+
"dynamic-import-node"
122+
]
123+
}
124+
}
125+
}
68126
}
69127
}
70128
}
71129
}
72130
```
73131

74-
To define a babelrc file that vue-jest will use when transpiling javascript, you can specify it in the jest globals
132+
##### String
133+
134+
If a string is provided, it will be an assumed path to a babel configuration file (e.g. `.babelrc`, `.babelrc.js`).
135+
- Config file should export a Babel configuration object.
136+
- 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.
137+
138+
```json
139+
{
140+
"jest": {
141+
"globals": {
142+
"vue-jest": {
143+
"babelConfig": "path/to/.babelrc.js"
144+
}
145+
}
146+
}
147+
}
148+
```
149+
150+
To use the [Config Function API](https://babeljs.io/docs/en/config-files#config-function-api), use inline options instead. i.e.:
151+
152+
```json
153+
{
154+
"jest": {
155+
"globals": {
156+
"vue-jest": {
157+
"babelConfig": {
158+
"configFile": "path/to/babel.config.js"
159+
}
160+
}
161+
}
162+
}
163+
}
164+
```
165+
166+
#### tsConfig
167+
168+
Provide `tsConfig` in one of the following formats:
169+
170+
- `<Boolean>`
171+
- `<Object>`
172+
- `<String>`
173+
174+
##### Boolean
175+
176+
- `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).
177+
178+
> This is the default behavior if [tsConfig](#tsConfig) is not defined.
179+
180+
- `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).
181+
182+
##### Object
183+
184+
Provide inline [TypeScript compiler options](https://www.typescriptlang.org/docs/handbook/compiler-options.html):
185+
186+
```json
187+
{
188+
"jest": {
189+
"globals": {
190+
"vue-jest": {
191+
"tsConfig": {
192+
"importHelpers": true
193+
}
194+
}
195+
}
196+
}
197+
}
198+
```
199+
200+
##### String
201+
202+
If a string is provided, it will be an assumed path to a TypeScript configuration file:
75203

76204
```json
77205
{
78206
"jest": {
79207
"globals": {
80208
"vue-jest": {
81-
"babelRcFile": "jest.babelrc"
209+
"tsConfig": "path/to/tsconfig.json"
82210
}
83211
}
84212
}

lib/load-babel-config.js

+36-9
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

+33-7
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

+58-1
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)