+
+ {{ exclamationMarks }}
+
+
+
+
+
diff --git a/e2e/2.x/basic/components/ModuleRequiringEsModuleInterop.js b/e2e/2.x/basic/components/ModuleRequiringEsModuleInterop.js
new file mode 100644
index 00000000..fed7caa7
--- /dev/null
+++ b/e2e/2.x/basic/components/ModuleRequiringEsModuleInterop.js
@@ -0,0 +1 @@
+module.exports = () => false
diff --git a/e2e/2.x/basic/test.js b/e2e/2.x/basic/test.js
index 7ec85043..a340be9c 100644
--- a/e2e/2.x/basic/test.js
+++ b/e2e/2.x/basic/test.js
@@ -21,6 +21,8 @@ import Jsx from './components/Jsx.vue'
import Constructor from './components/Constructor.vue'
import { compileStyle } from '@vue/component-compiler-utils'
import ScriptSetup from './components/ScriptSetup'
+import ExtendedTsConfig from './components/ExtendedTsConfig.vue'
+
jest.mock('@vue/component-compiler-utils', () => ({
...jest.requireActual('@vue/component-compiler-utils'),
compileStyle: jest.fn(() => ({ errors: [], code: '' }))
@@ -163,6 +165,11 @@ test('processes SFC with
diff --git a/e2e/3.x/basic/components/ModuleRequiringEsModuleInterop.js b/e2e/3.x/basic/components/ModuleRequiringEsModuleInterop.js
new file mode 100644
index 00000000..fed7caa7
--- /dev/null
+++ b/e2e/3.x/basic/components/ModuleRequiringEsModuleInterop.js
@@ -0,0 +1 @@
+module.exports = () => false
diff --git a/e2e/3.x/basic/test.js b/e2e/3.x/basic/test.js
index 553ec119..3a5dddaa 100644
--- a/e2e/3.x/basic/test.js
+++ b/e2e/3.x/basic/test.js
@@ -23,6 +23,7 @@ import ScriptSetup from './components/ScriptSetup.vue'
import ScriptSetupSugarRef from './components/ScriptSetupSugarRef.vue'
import FunctionalRenderFn from './components/FunctionalRenderFn.vue'
import CompilerDirective from './components/CompilerDirective.vue'
+import ExtendedTsConfig from './components/ExtendedTsConfig.vue'
// TODO: JSX for Vue 3? TSX?
import Jsx from './components/Jsx.vue'
@@ -207,3 +208,9 @@ test('ensure compilerOptions is passed down', () => {
const elm = document.querySelector('h1')
expect(elm.hasAttribute('data-test')).toBe(false)
})
+
+test('handles extended tsconfig.json files', () => {
+ mount(ExtendedTsConfig)
+ const elm = document.querySelector('div')
+ expect(elm).toBeDefined()
+})
diff --git a/e2e/3.x/basic/tsconfig.base.json b/e2e/3.x/basic/tsconfig.base.json
new file mode 100644
index 00000000..0b98e194
--- /dev/null
+++ b/e2e/3.x/basic/tsconfig.base.json
@@ -0,0 +1,21 @@
+{
+ "compilerOptions": {
+ "target": "es5",
+ "lib": ["dom", "es6"],
+ "module": "es2015",
+ "moduleResolution": "node",
+ "types": ["vue-typescript-import-dts", "node"],
+ "isolatedModules": false,
+ "experimentalDecorators": true,
+ "noImplicitAny": true,
+ "noImplicitThis": true,
+ "strictNullChecks": true,
+ "removeComments": true,
+ "emitDecoratorMetadata": true,
+ "suppressImplicitAnyIndexErrors": true,
+ "allowSyntheticDefaultImports": true,
+ "sourceMap": true,
+ "esModuleInterop": true,
+ "allowJs": true
+ }
+}
diff --git a/e2e/3.x/basic/tsconfig.json b/e2e/3.x/basic/tsconfig.json
index 8073706e..ffcbb947 100644
--- a/e2e/3.x/basic/tsconfig.json
+++ b/e2e/3.x/basic/tsconfig.json
@@ -1,20 +1,3 @@
{
- "compilerOptions": {
- "target": "es5",
- "lib": ["dom", "es6"],
- "module": "es2015",
- "moduleResolution": "node",
- "types": ["vue-typescript-import-dts", "node"],
- "isolatedModules": false,
- "experimentalDecorators": true,
- "noImplicitAny": true,
- "noImplicitThis": true,
- "strictNullChecks": true,
- "removeComments": true,
- "emitDecoratorMetadata": true,
- "suppressImplicitAnyIndexErrors": true,
- "allowSyntheticDefaultImports": true,
- "sourceMap": true,
- "allowJs": true
- }
+ "extends": "./tsconfig.base.json"
}
diff --git a/packages/vue2-jest/lib/ensure-require.js b/packages/vue2-jest/lib/ensure-require.js
index 17f40920..dd945ee2 100644
--- a/packages/vue2-jest/lib/ensure-require.js
+++ b/packages/vue2-jest/lib/ensure-require.js
@@ -1,4 +1,4 @@
-const throwError = require('./utils').throwError
+const throwError = require('./throw-error')
module.exports = function(name, deps) {
let i, len
diff --git a/packages/vue2-jest/lib/throw-error.js b/packages/vue2-jest/lib/throw-error.js
new file mode 100644
index 00000000..5d1272e3
--- /dev/null
+++ b/packages/vue2-jest/lib/throw-error.js
@@ -0,0 +1,3 @@
+module.exports = function throwError(msg) {
+ throw new Error('\n[vue-jest] Error: ' + msg + '\n')
+}
diff --git a/packages/vue2-jest/lib/utils.js b/packages/vue2-jest/lib/utils.js
index 25b8a5fa..f68d79ec 100644
--- a/packages/vue2-jest/lib/utils.js
+++ b/packages/vue2-jest/lib/utils.js
@@ -1,6 +1,8 @@
+const ensureRequire = require('./ensure-require')
+const throwError = require('./throw-error')
const constants = require('./constants')
const loadPartialConfig = require('@babel/core').loadPartialConfig
-const { loadSync: loadTsConfigSync } = require('tsconfig')
+const { resolveSync: resolveTsConfigSync } = require('tsconfig')
const chalk = require('chalk')
const path = require('path')
const fs = require('fs')
@@ -68,23 +70,55 @@ const getBabelOptions = function loadBabelOptions(filename, options = {}) {
return loadPartialConfig(opts).options
}
+const tsConfigCache = new Map()
+
/**
* Load TypeScript config from tsconfig.json.
* @param {string | undefined} path tsconfig.json file path (default: root)
* @returns {import('typescript').TranspileOptions | null} TypeScript compilerOptions or null
*/
const getTypeScriptConfig = function getTypeScriptConfig(path) {
- const tsconfig = loadTsConfigSync(process.cwd(), path || '')
- if (!tsconfig.path) {
+ if (tsConfigCache.has(path)) {
+ return tsConfigCache.get(path)
+ }
+
+ ensureRequire('typescript', ['typescript'])
+ const typescript = require('typescript')
+
+ const tsconfigPath = resolveTsConfigSync(process.cwd(), path || '')
+ if (!tsconfigPath) {
warn(`Not found tsconfig.json.`)
return null
}
- const compilerOptions =
- (tsconfig.config && tsconfig.config.compilerOptions) || {}
- return {
- compilerOptions: { ...compilerOptions, module: 'commonjs' }
+ const parsedConfig = typescript.getParsedCommandLineOfConfigFile(
+ tsconfigPath,
+ {},
+ {
+ ...typescript.sys,
+ onUnRecoverableConfigFileDiagnostic: e => {
+ const errorMessage = typescript.formatDiagnostic(e, {
+ getCurrentDirectory: () => process.cwd(),
+ getNewLine: () => `\n`,
+ getCanonicalFileName: file => file.replace(/\\/g, '/')
+ })
+ warn(errorMessage)
+ }
+ }
+ )
+
+ const compilerOptions = parsedConfig ? parsedConfig.options : {}
+
+ const transpileConfig = {
+ compilerOptions: {
+ ...compilerOptions,
+ module: typescript.ModuleKind.CommonJS
+ }
}
+
+ tsConfigCache.set(path, transpileConfig)
+
+ return transpileConfig
}
function isValidTransformer(transformer) {
@@ -131,10 +165,6 @@ const getCustomTransformer = function getCustomTransformer(
: transformer
}
-const throwError = function error(msg) {
- throw new Error('\n[vue-jest] Error: ' + msg + '\n')
-}
-
const stripInlineSourceMap = function(str) {
return str.slice(0, str.indexOf('//# sourceMappingURL'))
}
diff --git a/packages/vue3-jest/lib/ensure-require.js b/packages/vue3-jest/lib/ensure-require.js
index 17f40920..dd945ee2 100644
--- a/packages/vue3-jest/lib/ensure-require.js
+++ b/packages/vue3-jest/lib/ensure-require.js
@@ -1,4 +1,4 @@
-const throwError = require('./utils').throwError
+const throwError = require('./throw-error')
module.exports = function(name, deps) {
let i, len
diff --git a/packages/vue3-jest/lib/throw-error.js b/packages/vue3-jest/lib/throw-error.js
new file mode 100644
index 00000000..5d1272e3
--- /dev/null
+++ b/packages/vue3-jest/lib/throw-error.js
@@ -0,0 +1,3 @@
+module.exports = function throwError(msg) {
+ throw new Error('\n[vue-jest] Error: ' + msg + '\n')
+}
diff --git a/packages/vue3-jest/lib/utils.js b/packages/vue3-jest/lib/utils.js
index cbd7fd7a..5b1e70ee 100644
--- a/packages/vue3-jest/lib/utils.js
+++ b/packages/vue3-jest/lib/utils.js
@@ -1,6 +1,8 @@
+const ensureRequire = require('./ensure-require')
+const throwError = require('./throw-error')
const constants = require('./constants')
const loadPartialConfig = require('@babel/core').loadPartialConfig
-const { loadSync: loadTsConfigSync } = require('tsconfig')
+const { resolveSync: resolveTsConfigSync } = require('tsconfig')
const chalk = require('chalk')
const path = require('path')
const fs = require('fs')
@@ -68,24 +70,57 @@ const getBabelOptions = function loadBabelOptions(filename, options = {}) {
return loadPartialConfig(opts).options
}
+const tsConfigCache = new Map()
+
/**
* Load TypeScript config from tsconfig.json.
* @param {string | undefined} path tsconfig.json file path (default: root)
* @returns {import('typescript').TranspileOptions | null} TypeScript compilerOptions or null
*/
const getTypeScriptConfig = function getTypeScriptConfig(path) {
- const tsconfig = loadTsConfigSync(process.cwd(), path || '')
- if (!tsconfig.path) {
+ if (tsConfigCache.has(path)) {
+ return tsConfigCache.get(path)
+ }
+
+ ensureRequire('typescript', ['typescript'])
+ const typescript = require('typescript')
+
+ const tsconfigPath = resolveTsConfigSync(process.cwd(), path || '')
+ if (!tsconfigPath) {
warn(`Not found tsconfig.json.`)
return null
}
- const compilerOptions =
- (tsconfig.config && tsconfig.config.compilerOptions) || {}
- // Force es5 to prevent const vue_1 = require('vue') from conflicting
- return {
- compilerOptions: { ...compilerOptions, target: 'es5', module: 'commonjs' }
+ const parsedConfig = typescript.getParsedCommandLineOfConfigFile(
+ tsconfigPath,
+ {},
+ {
+ ...typescript.sys,
+ onUnRecoverableConfigFileDiagnostic: e => {
+ const errorMessage = typescript.formatDiagnostic(e, {
+ getCurrentDirectory: () => process.cwd(),
+ getNewLine: () => `\n`,
+ getCanonicalFileName: file => file.replace(/\\/g, '/')
+ })
+ warn(errorMessage)
+ }
+ }
+ )
+
+ const compilerOptions = parsedConfig ? parsedConfig.options : {}
+
+ const transpileConfig = {
+ compilerOptions: {
+ ...compilerOptions,
+ // Force es5 to prevent const vue_1 = require('vue') from conflicting
+ target: typescript.ScriptTarget.ES5,
+ module: typescript.ModuleKind.CommonJS
+ }
}
+
+ tsConfigCache.set(path, transpileConfig)
+
+ return transpileConfig
}
function isValidTransformer(transformer) {
@@ -133,10 +168,6 @@ const getCustomTransformer = function getCustomTransformer(
: transformer
}
-const throwError = function error(msg) {
- throw new Error('\n[vue-jest] Error: ' + msg + '\n')
-}
-
const stripInlineSourceMap = function(str) {
return str.slice(0, str.indexOf('//# sourceMappingURL'))
}