From 89d2eb41c7c3c76d1bf7b2e336d9f2b0f3fc1a44 Mon Sep 17 00:00:00 2001 From: Daniel Herman Date: Tue, 24 Apr 2018 14:37:22 -0400 Subject: [PATCH 1/3] feat: allow specifying the tsconfig file as a jest global --- README.md | 12 ++++++++++++ lib/compilers/typescript-compiler.js | 4 ++-- lib/load-typescript-config.js | 17 ++++++++++++----- lib/process.js | 6 +++--- test/load-typescript-config.spec.js | 28 ++++++++++++++++++++++++---- 5 files changed, 53 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 9a77916c..1158336e 100644 --- a/README.md +++ b/README.md @@ -57,6 +57,18 @@ vue-jest compiles the script and template of SFCs into a JavaScript file that Je - **typescript** (`lang="ts"`, `lang="typescript"`) - **coffeescript** (`lang="coffee"`, `lang="coffeescript"`) +To define a tsconfig file that vue-jest will use when transpiling typescript, you can specify it in the jest globals + +```json +{ + "jest": { + "vue-jest": { + "tsConfigFile": "tsconfig.jest.json" + } + } +} +``` + ### Supported template languages - **pug** (`lang="pug"`) diff --git a/lib/compilers/typescript-compiler.js b/lib/compilers/typescript-compiler.js index 1b5f3256..d903c616 100644 --- a/lib/compilers/typescript-compiler.js +++ b/lib/compilers/typescript-compiler.js @@ -3,10 +3,10 @@ const compileBabel = require('./babel-compiler') const loadBabelConfig = require('../load-babel-config.js') const { loadTypescriptConfig } = require('../load-typescript-config') -module.exports = function compileTypescript (scriptContent) { +module.exports = function compileTypescript (scriptContent, vueJestConfig) { ensureRequire('typescript', ['typescript']) const typescript = require('typescript') - const tsConfig = loadTypescriptConfig() + const tsConfig = loadTypescriptConfig(vueJestConfig) const res = typescript.transpileModule(scriptContent, tsConfig) const inputSourceMap = (res.sourceMapText !== undefined) diff --git a/lib/load-typescript-config.js b/lib/load-typescript-config.js index 8d72a477..aee1b970 100644 --- a/lib/load-typescript-config.js +++ b/lib/load-typescript-config.js @@ -26,18 +26,25 @@ const defaultTypescriptConfig = { } } -module.exports.loadTypescriptConfig = function loadTypescriptConfig () { +module.exports.loadTypescriptConfig = function loadTypescriptConfig (vueJestConfig) { const cachedConfig = cache.get('typescript-config') if (cachedConfig) { return cachedConfig } else { - const { path, config } = tsconfig.loadSync(process.cwd()) + let typescriptConfig - if (!path) { - logger.info('no tsconfig.json found, defaulting to default typescript options') + if (vueJestConfig.tsConfigFile) { + typescriptConfig = tsconfig.readFileSync(vueJestConfig.tsConfigFile) + } else { + const { path, config } = tsconfig.loadSync(process.cwd()) + + if (!path) { + logger.info('no tsconfig.json found, defaulting to default typescript options') + } + + typescriptConfig = path ? config : defaultTypescriptConfig } - const typescriptConfig = path ? config : defaultTypescriptConfig cache.set('typescript-config', typescriptConfig) return typescriptConfig } diff --git a/lib/process.js b/lib/process.js index e288838e..8692e5d6 100644 --- a/lib/process.js +++ b/lib/process.js @@ -14,13 +14,13 @@ const join = path.join const logger = require('./logger') const splitRE = /\r?\n/g -function processScript (scriptPart) { +function processScript (scriptPart, vueJestConfig) { if (!scriptPart) { return { code: '' } } if (/^typescript|tsx?$/.test(scriptPart.lang)) { - return compileTypescript(scriptPart.content) + return compileTypescript(scriptPart.content, vueJestConfig) } if (scriptPart.lang === 'coffee' || scriptPart.lang === 'coffeescript') { @@ -51,7 +51,7 @@ module.exports = function (src, filePath, jestConfig) { parts.script.content = fs.readFileSync(join(filePath, '..', parts.script.src), 'utf8') } - const result = processScript(parts.script) + const result = processScript(parts.script, vueJestConfig) const script = result.code const inputMap = result.sourceMap diff --git a/test/load-typescript-config.spec.js b/test/load-typescript-config.spec.js index b41ef330..0a1b05c9 100644 --- a/test/load-typescript-config.spec.js +++ b/test/load-typescript-config.spec.js @@ -4,7 +4,9 @@ import { createReadStream, createWriteStream, readFileSync, - renameSync + writeFileSync, + renameSync, + unlinkSync } from 'fs' import clearModule from 'clear-module' import cache from '../lib/cache' @@ -20,7 +22,7 @@ describe('load-typescript-config.js', () => { const tempPath = resolve(__dirname, '../.renamed') renameSync(tsconfigPath, tempPath) - const tsConfig = loadTypescriptConfig() + const tsConfig = loadTypescriptConfig({}) try { expect(tsConfig).toEqual(defaultConfig) @@ -34,16 +36,34 @@ describe('load-typescript-config.js', () => { expect(tsconfigCachedConfig).toEqual(defaultConfig) }) + it('returns the tsconfig specified in jest globals', () => { + const jestGlobalTsConfigPath = resolve(__dirname, '../tsconfig.jest.json') + + writeFileSync(jestGlobalTsConfigPath, JSON.stringify({ + allowJs: false + })) + + const jestGlobalTsConfig = JSON.parse(readFileSync(jestGlobalTsConfigPath, { encoding: 'utf8' })) + + const tsconfig = loadTypescriptConfig({ + tsConfigFile: jestGlobalTsConfigPath + }) + + expect(tsconfig).toEqual(jestGlobalTsConfig) + + unlinkSync(jestGlobalTsConfigPath) + }) + it('reads default tsconfig if there is tsconfig.json', () => { const tsconfigPath = resolve(__dirname, '../tsconfig.json') const tsconfigCopiedPath = resolve(__dirname, '../.tsconfig.json_cp') createReadStream(tsconfigPath).pipe(createWriteStream(tsconfigCopiedPath)) const tsconfigOriginal = JSON.parse(readFileSync(tsconfigPath, { encoding: 'utf8' })) - const tsconfig = loadTypescriptConfig() + const tsconfig = loadTypescriptConfig({}) expect(tsconfig).toEqual(tsconfigOriginal) const tempPath = resolve(__dirname, '../.renamed') renameSync(tsconfigCopiedPath, tempPath) - const tsconfigCached = loadTypescriptConfig() + const tsconfigCached = loadTypescriptConfig({}) try { expect(tsconfig).not.toBe(tsconfigCached) expect(tsconfig).toEqual(tsconfigCached) From 596e035086a6035274b386b76b18c95abed222b3 Mon Sep 17 00:00:00 2001 From: Daniel Herman Date: Tue, 24 Apr 2018 15:11:50 -0400 Subject: [PATCH 2/3] chore: remove unused arguments from the coffee compiler --- lib/compilers/coffee-compiler.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/compilers/coffee-compiler.js b/lib/compilers/coffee-compiler.js index 99c113fd..e58bfd86 100644 --- a/lib/compilers/coffee-compiler.js +++ b/lib/compilers/coffee-compiler.js @@ -2,7 +2,7 @@ var ensureRequire = require('../ensure-require.js') const throwError = require('../throw-error') const loadBabelConfig = require('../load-babel-config.js') -module.exports = function (raw, cb, compiler) { +module.exports = function (raw) { ensureRequire('coffee', ['coffeescript']) var coffee = require('coffeescript') var compiled From f0d66a8d3f32d3117938a01f68e869bebb0e1a99 Mon Sep 17 00:00:00 2001 From: Daniel Herman Date: Tue, 24 Apr 2018 15:02:48 -0400 Subject: [PATCH 3/3] feat: allow specifying the babelrc file as a jest global Closes #66 --- README.md | 12 ++++++++++++ lib/compilers/babel-compiler.js | 4 ++-- lib/compilers/coffee-compiler.js | 4 ++-- lib/compilers/typescript-compiler.js | 4 ++-- lib/load-babel-config.js | 27 +++++++++++++++++++-------- lib/process.js | 4 ++-- test/load-babel-config.spec.js | 21 ++++++++++++++++++--- 7 files changed, 57 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index 1158336e..6360ca51 100644 --- a/README.md +++ b/README.md @@ -69,6 +69,18 @@ To define a tsconfig file that vue-jest will use when transpiling typescript, yo } ``` +To define a babelrc file that vue-jest will use when transpiling javascript, you can specify it in the jest globals + +```json +{ + "jest": { + "vue-jest": { + "babelRcFile": "jest.babelrc" + } + } +} +``` + ### Supported template languages - **pug** (`lang="pug"`) diff --git a/lib/compilers/babel-compiler.js b/lib/compilers/babel-compiler.js index 571f4db5..a8a6d1d3 100644 --- a/lib/compilers/babel-compiler.js +++ b/lib/compilers/babel-compiler.js @@ -1,8 +1,8 @@ const babel = require('babel-core') const loadBabelConfig = require('../load-babel-config.js') -module.exports = function compileBabel (scriptContent, inputSourceMap, inlineConfig) { - const babelConfig = inlineConfig || loadBabelConfig() +module.exports = function compileBabel (scriptContent, inputSourceMap, inlineConfig, vueJestConfig) { + const babelConfig = inlineConfig || loadBabelConfig(vueJestConfig) if (!babelConfig) { return { diff --git a/lib/compilers/coffee-compiler.js b/lib/compilers/coffee-compiler.js index e58bfd86..cb5ae54f 100644 --- a/lib/compilers/coffee-compiler.js +++ b/lib/compilers/coffee-compiler.js @@ -2,7 +2,7 @@ var ensureRequire = require('../ensure-require.js') const throwError = require('../throw-error') const loadBabelConfig = require('../load-babel-config.js') -module.exports = function (raw) { +module.exports = function (raw, vueJestConfig) { ensureRequire('coffee', ['coffeescript']) var coffee = require('coffeescript') var compiled @@ -10,7 +10,7 @@ module.exports = function (raw) { compiled = coffee.compile(raw, { bare: true, sourceMap: true, - transpile: loadBabelConfig() + transpile: loadBabelConfig(vueJestConfig) }) } catch (err) { throwError(err) diff --git a/lib/compilers/typescript-compiler.js b/lib/compilers/typescript-compiler.js index d903c616..a1c344cd 100644 --- a/lib/compilers/typescript-compiler.js +++ b/lib/compilers/typescript-compiler.js @@ -16,7 +16,7 @@ module.exports = function compileTypescript (scriptContent, vueJestConfig) { // handle ES modules in TS source code in case user uses non commonjs module // output and there is no .babelrc. let inlineBabelConfig - if (tsConfig.compilerOptions.module !== 'commonjs' && !loadBabelConfig()) { + if (tsConfig.compilerOptions.module !== 'commonjs' && !loadBabelConfig(vueJestConfig)) { inlineBabelConfig = { plugins: [ require('babel-plugin-transform-es2015-modules-commonjs') @@ -24,5 +24,5 @@ module.exports = function compileTypescript (scriptContent, vueJestConfig) { } } - return compileBabel(res.outputText, inputSourceMap, inlineBabelConfig) + return compileBabel(res.outputText, inputSourceMap, inlineBabelConfig, vueJestConfig) } diff --git a/lib/load-babel-config.js b/lib/load-babel-config.js index c45379c8..d2985d65 100644 --- a/lib/load-babel-config.js +++ b/lib/load-babel-config.js @@ -1,21 +1,32 @@ const findBabelConfig = require('find-babel-config') const logger = require('./logger') const cache = require('./cache') +const { readFileSync } = require('fs') -module.exports = function getBabelConfig () { +module.exports = function getBabelConfig (vueJestConfig) { const cachedConfig = cache.get('babel-config') if (cachedConfig) { return cachedConfig } else if (cachedConfig === false) { return } else { - const { file, config } = findBabelConfig.sync(process.cwd(), 0) - if (!file) { - logger.info('no .babelrc found, skipping babel compilation') - cache.set('babel-config', false) - return + let babelConfig + + if (vueJestConfig.babelRcFile) { + babelConfig = JSON.parse(readFileSync(vueJestConfig.babelRcFile)) + } else { + const { file, config } = findBabelConfig.sync(process.cwd(), 0) + + if (!file) { + logger.info('no .babelrc found, skipping babel compilation') + cache.set('babel-config', false) + return + } + + babelConfig = config } - cache.set('babel-config', config) - return config + + cache.set('babel-config', babelConfig) + return babelConfig } } diff --git a/lib/process.js b/lib/process.js index 8692e5d6..0d2dac02 100644 --- a/lib/process.js +++ b/lib/process.js @@ -24,10 +24,10 @@ function processScript (scriptPart, vueJestConfig) { } if (scriptPart.lang === 'coffee' || scriptPart.lang === 'coffeescript') { - return compileCoffeeScript(scriptPart.content) + return compileCoffeeScript(scriptPart.content, vueJestConfig) } - return compileBabel(scriptPart.content) + return compileBabel(scriptPart.content, undefined, undefined, vueJestConfig) } function changePartsIfFunctional (parts) { diff --git a/test/load-babel-config.spec.js b/test/load-babel-config.spec.js index f84e80d1..3086f3bc 100644 --- a/test/load-babel-config.spec.js +++ b/test/load-babel-config.spec.js @@ -4,7 +4,9 @@ import { createReadStream, createWriteStream, readFileSync, - renameSync + renameSync, + writeFileSync, + unlinkSync } from 'fs' import clearModule from 'clear-module' import cache from '../lib/cache' @@ -19,7 +21,7 @@ describe('load-babel-config.js', () => { const babelRcPath = resolve(__dirname, '../.babelrc') const tempPath = resolve(__dirname, '../.renamed') renameSync(babelRcPath, tempPath) - const babelConfig = loadBabelConfig() + const babelConfig = loadBabelConfig({}) try { expect(babelConfig).toBe(undefined) } catch (err) { @@ -31,12 +33,25 @@ describe('load-babel-config.js', () => { expect(babelConfigCached).toBe(undefined) }) + it('reads babelrc from jest globals if exists', () => { + const jestGlobalBabelPath = resolve(__dirname, '../jest.babelrc') + writeFileSync(jestGlobalBabelPath, JSON.stringify({ + plugins: ['foo'] + })) + const jestGlobalBabelConfig = JSON.parse(readFileSync(jestGlobalBabelPath, { encoding: 'utf8' })) + const babelConfig = loadBabelConfig({ + babelRcFile: 'jest.babelrc' + }) + expect(babelConfig).toEqual(jestGlobalBabelConfig) + unlinkSync(jestGlobalBabelPath) + }) + it('reads default babel if there is .babelrc', () => { const babelRcPath = resolve(__dirname, '../.babelrc') const babelRcCopiedPath = resolve(__dirname, '../.babelrc_cp') createReadStream(babelRcPath).pipe(createWriteStream(babelRcCopiedPath)) const babelRcOriginal = JSON.parse(readFileSync(babelRcPath, { encoding: 'utf8' })) - const babelConfig = loadBabelConfig() + const babelConfig = loadBabelConfig({}) expect(babelConfig).toEqual(babelRcOriginal) const tempPath = resolve(__dirname, '../.renamed') renameSync(babelRcCopiedPath, tempPath)