Skip to content
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

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 11 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# esbuild-jest

### A Jest transformer using esbuild

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

prettier 🤦

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)
Expand All @@ -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?$": [
Copy link
Author

Choose a reason for hiding this comment

The 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

105 changes: 60 additions & 45 deletions src/index.ts
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;
};
}
Copy link
Author

Choose a reason for hiding this comment

The 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,
Copy link
Author

Choose a reason for hiding this comment

The 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;
12 changes: 0 additions & 12 deletions src/options.ts

This file was deleted.