-
Notifications
You must be signed in to change notification settings - Fork 51
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: support esbuild options #29
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,7 @@ | ||
# esbuild-jest | ||
|
||
### A Jest transformer using esbuild | ||
|
||
With this transformer you can use and transform (ts, js, tsx and jsx) files | ||
|
||
[![npm](https://img.shields.io/npm/v/esbuild-jest.svg)](https://www.npmjs.com/package/esbuild-jest) | ||
|
@@ -25,34 +26,31 @@ esbuild-jest transformer should be used in your Jest config file like this: | |
``` | ||
|
||
#### Setting up Jest config file with transformOptions | ||
|
||
```typescript | ||
export interface Options { | ||
jsxFactory?: string | ||
jsxFragment?: string | ||
sourcemap?: boolean | 'inline' | 'external' | ||
import type { Loader, TransformOptions } from "esbuild"; | ||
|
||
export interface Options extends TransformOptions { | ||
loaders?: { | ||
[ext: string]: Loader | ||
}, | ||
target?: string | ||
format?: string | ||
[ext: string]: Loader; | ||
}; | ||
} | ||
``` | ||
|
||
```js | ||
{ | ||
"transform": { | ||
"^.+\\.tsx?$": [ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. prettier 🤦 |
||
"esbuild-jest", | ||
{ | ||
"^.+\\.tsx?$": [ | ||
"esbuild-jest", | ||
{ | ||
sourcemap: true, | ||
loaders: { | ||
'.spec.ts': 'tsx' | ||
} | ||
} | ||
} | ||
] | ||
} | ||
} | ||
``` | ||
|
||
> Note: if you are using tsconfig.json and jsconfig.json with "paths", Please look `alias-hq` and there documentation https://github.com/davestewart/alias-hq/blob/master/docs/integrations.md | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,77 +1,92 @@ | ||
import { extname } from 'path' | ||
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 { Config } from "@jest/types"; | ||
import { | ||
TransformOptions as JestTransformOptions, | ||
Transformer, | ||
} from "@jest/transform"; | ||
import { Loader, TransformOptions, transformSync } from "esbuild"; | ||
|
||
import { Options } from './options' | ||
import { getExt, loaders } from './utils' | ||
export interface Options extends TransformOptions { | ||
loaders?: { | ||
[ext: string]: Loader; | ||
}; | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. actual change! ^^ |
||
|
||
import { getExt, loaders } from "./utils"; | ||
|
||
const createTransformer = (options?: Options) => ({ | ||
process(content: string, | ||
filename: string, | ||
config: Config.ProjectConfig, | ||
process( | ||
content: string, | ||
filename: string, | ||
config: Config.ProjectConfig, | ||
opts?: JestTransformOptions | ||
) { | ||
const sources = { code: content } | ||
const ext = getExt(filename), extName = extname(filename).slice(1) | ||
const { loaders: userLoaders = {}, ...esbuildOptions } = options || {}; | ||
const { sourcemap, jsxFactory, jsxFragment } = esbuildOptions; | ||
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<TransformOptions> = enableSourcemaps | ||
? { sourcemap: true, sourcesContent: false, sourcefile: filename } | ||
: {} | ||
const enableSourcemaps = sourcemap || false; | ||
const loader = (userLoaders[ext] | ||
? userLoaders[ext] | ||
: loaders.includes(extName) | ||
? extName | ||
: "text") as Loader; | ||
const sourcemaps: Partial<TransformOptions> = enableSourcemaps | ||
? { sourcemap: true, sourcesContent: false, sourcefile: filename } | ||
: {}; | ||
|
||
/// this logic or code from | ||
/// this logic or code from | ||
/// https://github.com/threepointone/esjest-transform/blob/main/src/index.js | ||
/// this will support the jest.mock | ||
/// https://github.com/aelbore/esbuild-jest/issues/12 | ||
/// TODO: transform the jest.mock to a function using babel traverse/parse then hoist it | ||
if (sources.code.indexOf("ock(") >= 0 || opts?.instrument) { | ||
const source = require('./transformer').babelTransform({ | ||
const source = require("./transformer").babelTransform({ | ||
sourceText: content, | ||
sourcePath: filename, | ||
config, | ||
options: opts | ||
}) | ||
sources.code = source | ||
options: opts, | ||
}); | ||
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 | ||
}) | ||
|
||
...esbuildOptions, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👀 👀 👀 this is the "big" change. i'm really sorry about the big diff. |
||
format: esbuildOptions.format || "cjs", | ||
target: esbuildOptions.target || "es2018", | ||
...(jsxFactory ? { jsxFactory } : {}), | ||
...(jsxFragment ? { jsxFragment } : {}), | ||
...sourcemaps, | ||
}); | ||
|
||
let { map, code } = result; | ||
if (enableSourcemaps) { | ||
map = { | ||
...JSON.parse(result.map), | ||
sourcesContent: null, | ||
} | ||
}; | ||
|
||
// Append the inline sourcemap manually to ensure the "sourcesContent" | ||
// is null. Otherwise, breakpoints won't pause within the actual source. | ||
code = code + '\n//# sourceMappingURL=data:application/json;base64,' + Buffer.from(JSON.stringify(map)).toString('base64') | ||
code = | ||
code + | ||
"\n//# sourceMappingURL=data:application/json;base64," + | ||
Buffer.from(JSON.stringify(map)).toString("base64"); | ||
} else { | ||
map = null | ||
map = null; | ||
} | ||
|
||
return { code, map } | ||
} | ||
}) | ||
|
||
const transformer: Pick<Transformer, 'canInstrument' | 'createTransformer'> = { | ||
canInstrument: true, | ||
createTransformer | ||
} | ||
return { code, map }; | ||
}, | ||
}); | ||
|
||
export * from './options' | ||
const transformer: Pick<Transformer, "canInstrument" | "createTransformer"> = { | ||
canInstrument: true, | ||
createTransformer, | ||
}; | ||
|
||
export default transformer | ||
export default transformer; |
This file was deleted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
prettier 🤦