diff --git a/src/index.ts b/src/index.ts index e2bca0f..051dc0c 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,11 +1,9 @@ -import { extname } from 'path' - import { Config } from '@jest/types' import { TransformOptions as JestTransformOptions, Transformer } from '@jest/transform' -import { Format, Loader, TransformOptions, transformSync } from 'esbuild' +import { transformSync } from 'esbuild' import { Options } from './options' -import { getExt, loaders } from './utils' +import { getEsbuildConfig } from './utils' const createTransformer = (options?: Options) => ({ process(content: string, @@ -14,16 +12,6 @@ const createTransformer = (options?: Options) => ({ opts?: JestTransformOptions ) { const sources = { code: content } - const ext = getExt(filename), extName = extname(filename).slice(1) - - const enableSourcemaps = options?.sourcemap || false - const loader = (options?.loaders && options?.loaders[ext] - ? options.loaders[ext] - : loaders.includes(extName) ? extName: 'text' - ) as Loader - const sourcemaps: Partial = enableSourcemaps - ? { sourcemap: true, sourcesContent: false, sourcefile: filename } - : {} /// this logic or code from /// https://github.com/threepointone/esjest-transform/blob/main/src/index.js @@ -40,17 +28,11 @@ const createTransformer = (options?: Options) => ({ sources.code = source } - const result = transformSync(sources.code, { - loader, - format: options?.format as Format || 'cjs', - target: options?.target || 'es2018', - ...(options?.jsxFactory ? { jsxFactory: options.jsxFactory }: {}), - ...(options?.jsxFragment ? { jsxFragment: options.jsxFragment }: {}), - ...sourcemaps - }) + const esbuildConfig = getEsbuildConfig(options, filename) + const result = transformSync(sources.code, esbuildConfig) let { map, code } = result; - if (enableSourcemaps) { + if (esbuildConfig.sourcemap) { map = { ...JSON.parse(result.map), sourcesContent: null, diff --git a/src/utils.ts b/src/utils.ts index 849e686..0d61dd9 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -1,14 +1,28 @@ import path from 'path' +import { Format, Loader, TransformOptions } from 'esbuild' -export const loaders = ["js", "jsx", "ts", "tsx", "json"] +const loaders = ['js', 'jsx', 'ts', 'tsx', 'json'] -export const getExt = (str: string) => { - const basename = path.basename(str); - const firstDot = basename.indexOf('.'); - const lastDot = basename.lastIndexOf('.'); - const extname = path.extname(basename).replace(/(\.[a-z0-9]+).*/i, '$1'); +export const getEsbuildConfig = (options, filename) => { + const ext = path.extname(filename), + extName = path.extname(filename).slice(1) + const loader = (options?.loaders && options?.loaders[ext] + ? options.loaders[ext] + : loaders.includes(extName) + ? extName + : 'text') as Loader - if (firstDot === lastDot) return extname + const enableSourcemaps = options?.sourcemap || false + const sourcemaps: Partial = enableSourcemaps + ? { sourcemap: true, sourcesContent: false, sourcefile: filename } + : {} - return basename.slice(firstDot, lastDot) + extname -} \ No newline at end of file + return { + loader, + format: (options?.format as Format) || 'cjs', + target: options?.target || 'es2018', + ...(options?.jsxFactory ? { jsxFactory: options.jsxFactory } : {}), + ...(options?.jsxFragment ? { jsxFragment: options.jsxFragment } : {}), + ...sourcemaps, + } +} diff --git a/tests/utils.spec.ts b/tests/utils.spec.ts new file mode 100644 index 0000000..c8a26d1 --- /dev/null +++ b/tests/utils.spec.ts @@ -0,0 +1,44 @@ +import { getEsbuildConfig } from '../src/utils'; + +describe('getEsbuildConfig', () => { + test('with sourcemaps returns correct config', () => { + const config = getEsbuildConfig({ sourcemap: true }, 'filename.js') + + expect(config).toEqual({ + format: 'cjs', + loader: 'js', + target: 'es2018', + sourcefile: 'filename.js', + sourcemap: true, + sourcesContent: false, + }) + }) + + describe('with loaders', () => { + test('.js loader returns correct config', () => { + const config = getEsbuildConfig( + { loaders: { '.js': 'jsx' } }, + 'filename.js' + ) + + expect(config).toEqual({ + format: 'cjs', + loader: 'jsx', + target: 'es2018', + }); + }); + + test('.js loader returns correct config with compound extension', () => { + const config = getEsbuildConfig( + { loaders: { '.js': 'jsx' } }, + 'filename.test.js' + ) + + expect(config).toEqual({ + format: 'cjs', + loader: 'jsx', + target: 'es2018', + }); + }); + }) +}) \ No newline at end of file