Skip to content

Commit d3fc458

Browse files
authored
feat: more flexible transformer mechanism (#19)
BREAKING CHANGE: migrate your preTransform and postTransform callbacks
1 parent 391a116 commit d3fc458

File tree

5 files changed

+25
-44
lines changed

5 files changed

+25
-44
lines changed

__fixtures__/simple-project/.esbuild-jestrc.js

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
/** @type {import('esbuild-jest-cli').ESBuildJestConfig} */
12
module.exports = {
23
"esbuild": {
34
"sourcemap": true,
@@ -8,12 +9,17 @@ module.exports = {
89
},
910
"external": ["chalk", "dtrace-provider", "@linked-dependencies/external"],
1011
},
11-
"preTransform": (path, contents) => {
12-
if (path.includes('lodash/noop')) {
13-
return 'console.log("You called noop!");\n' + contents;
14-
}
12+
"useTransformer": ({ build, transformer }) => {
13+
build.onLoad({ filter: /lodash\/noop/ }, async (args) => {
14+
const fs = await import('fs');
15+
const raw = await fs.promises.readFile(args.path, 'utf8');
16+
const { code: transformed } = transformer.transformSource(args.path, raw, {});
1517

16-
return contents;
18+
return {
19+
contents: 'console.log("You called noop!");\n' + transformed,
20+
loader: 'js',
21+
};
22+
});
1723
},
1824
"package": {
1925
"name": "custom-name",

index.d.mts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import type {BuildOptions} from 'esbuild';
1+
import type { PluginBuild, BuildOptions } from 'esbuild';
2+
import type { ScriptTransformer } from '@jest/transform';
23

34
export type ESBuildJestConfig = {
45
esbuild: Omit<
@@ -12,7 +13,7 @@ export type ESBuildJestConfig = {
1213
| 'entryPoints'
1314
>;
1415
package: Record<string, unknown> | ((base: Record<string, unknown>) => Record<string, unknown>);
15-
preTransform: (filePath: string, fileContent: string) => string;
16+
useTransformer: (context: { build: PluginBuild; transformer: ScriptTransformer; }) => void | Promise<void>;
1617
postTransform: (filePath: string, fileContent: string) => string;
1718
};
1819

index.mjs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ const __IS_EXTERNAL__ = optimizeTracing((id, external) => {
1717
optimizedLogger.trace(`mark as ${external ? 'external' : 'internal'}: ${id}`);
1818
});
1919

20+
/** @param {import('esbuild-jest-cli').ESBuildJestConfig} esbuildJestConfig */
2021
export async function build(esbuildJestConfig = {}) {
2122
const rootDir = process.cwd();
2223

@@ -101,8 +102,7 @@ export async function build(esbuildJestConfig = {}) {
101102
projectConfig,
102103
tests: tests.map(t => t.path),
103104
package: wrapPackageMiddleware(esbuildJestConfig.package),
104-
preTransform: esbuildJestConfig.preTransform,
105-
postTransform: esbuildJestConfig.postTransform,
105+
useTransformer: esbuildJestConfig.useTransformer,
106106
}),
107107
...(esbuildBaseConfig.plugins || []),
108108
],

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
},
4848
"devDependencies": {
4949
"@jest/types": "^29.6.3",
50+
"@jest/transform": "^29.6.3",
5051
"esbuild": "^0.19.8"
5152
}
5253
}

plugin.mjs

Lines changed: 8 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
1-
import { readFile, writeFile } from 'node:fs/promises';
2-
import { sep, join, relative, resolve } from 'node:path';
1+
import { writeFile } from 'node:fs/promises';
2+
import { sep, join, resolve } from 'node:path';
33
import importFrom from 'import-from';
4-
import { logger, optimizedLogger, optimizeTracing } from "./utils/logger.mjs";
4+
import { logger, optimizeTracing } from "./utils/logger.mjs";
55
import { convertPathToImport } from "./utils/resolve-module.mjs";
66
import { isBuiltinReporter } from "./utils/is-builtin-reporter.mjs";
77
import { mapSourceToOutputFiles } from "./utils/map-inputs-outputs.mjs";
88
import { moveJsFile } from "./utils/move-js-file.mjs";
99
import { pruneDirectory } from "./utils/prune-directory.mjs";
1010
import { JEST_DEPENDENCIES } from "./utils/jest-dependencies.mjs";
1111

12-
const passThrough = (filePath, fileContents) => fileContents;
12+
const noop = () => {};
1313

1414
const __CONTENT = optimizeTracing((log, content, message) => log.trace(
1515
typeof content === 'object'
@@ -18,16 +18,6 @@ const __CONTENT = optimizeTracing((log, content, message) => log.trace(
1818
message
1919
));
2020

21-
const __DIFF = optimizeTracing((log, before, after, message) => {
22-
if (before !== after) {
23-
__CONTENT(log, after, message);
24-
}
25-
});
26-
27-
const __READ = (log, content) => __CONTENT(log, content, 'read file');
28-
const __PREPROCESS = (log, before, after) => __DIFF(log, before, after, 'pre-process file');
29-
const __TRANSFORM = (log, content) => __CONTENT(log, content, 'transform file');
30-
const __POSTPROCESS = (log, before, after) => __DIFF(log, before, after, 'post-process file');
3121
const __FILE_MAPPING_CREATING = (log, input) => __CONTENT(log, input, 'creating file mapping');
3222
const __FILE_MAPPING_CREATED = (log, input) => __CONTENT(log, input, 'created file mapping');
3323
const __JEST_CONFIG = (log, config) => __CONTENT(log, config, 'create jest config');
@@ -38,8 +28,7 @@ export default ({
3828
globalConfig,
3929
projectConfig,
4030
tests,
41-
preTransform = passThrough,
42-
postTransform = passThrough,
31+
useTransformer = noop,
4332
}) => {
4433
return {
4534
name: 'jest',
@@ -51,25 +40,9 @@ export default ({
5140
const { createScriptTransformer } = importFrom(rootDir, '@jest/transform');
5241
const transformer = await createScriptTransformer(projectConfig);
5342

54-
build.onLoad({ filter: /.*/ }, async (args) => {
55-
const log = optimizedLogger.child({ tid: ['jest-transform', args.path] });
56-
57-
return log.trace.complete(relative(rootDir, args.path), async () => {
58-
const fileContent = await readFile(args.path, 'utf8');
59-
__READ(log, fileContent);
60-
61-
const preprocessed = preTransform(args.path, fileContent);
62-
__PREPROCESS(log, fileContent, preprocessed);
63-
64-
const { code: transformed } = transformer.transformSource(args.path, preprocessed, {});
65-
__TRANSFORM(log, transformed);
66-
67-
const contents = postTransform(args.path, transformed);
68-
__POSTPROCESS(log, transformed, contents);
69-
70-
const loader = args.path.endsWith('.json') ? 'json' : 'js';
71-
return { contents, loader };
72-
});
43+
await useTransformer({
44+
build,
45+
transformer,
7346
});
7447

7548
build.onEnd(async (result) => {

0 commit comments

Comments
 (0)