Skip to content

Commit

Permalink
feat: metafile support, jestConfig transformation
Browse files Browse the repository at this point in the history
BREAKING CHANGE: new bundles are using @swc/jest
  • Loading branch information
noomorph committed Jan 13, 2025
1 parent 749926f commit 2c297a9
Show file tree
Hide file tree
Showing 7 changed files with 85 additions and 57 deletions.
24 changes: 15 additions & 9 deletions __fixtures__/simple-project/.esbuild-jestrc.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
/** @type {import('esbuild-jest-cli').ESBuildJestConfig} */
module.exports = {
"esbuild": {
"sourcemap": true,
"platform": "node",
"outdir": "../simple-project-bundled",
"external": ["chalk", "dtrace-provider", "@linked-dependencies/external"],
esbuild: {
sourcemap: true,
platform: "node",
metafile: true,
outdir: "../simple-project-bundled",
external: ["chalk", "dtrace-provider", "@linked-dependencies/external"],
},
"useTransformer": ({ build, transformer }) => {
useTransformer: ({ build, transformer }) => {
build.onLoad({ filter: /lodash\/noop/ }, async (args) => {
const fs = await import('fs');
const raw = await fs.promises.readFile(args.path, 'utf8');
Expand All @@ -18,9 +19,14 @@ module.exports = {
};
});
},
"package": {
"name": "custom-name",
"dependencies": {
jestConfig: {
transform: {
'someCuriousPattern': '@swc/jest',
},
},
package: {
name: "custom-name",
dependencies: {
"@linked-dependencies/external": "../linked-dependencies/external",
}
}
Expand Down
1 change: 1 addition & 0 deletions __fixtures__/simple-project/jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ module.exports = {
],
testMatch: [
'<rootDir>/src/**/*.test.js',
'<rootDir>/src/**/*.test.cjs',
],
testEnvironment: 'jest-environment-emit/node',
};
3 changes: 2 additions & 1 deletion index.d.mts
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
import type { PluginBuild, BuildOptions } from 'esbuild';
import type { Config as JestConfig } from '@jest/types';
import type { ScriptTransformer } from '@jest/transform';

export type ESBuildJestConfig = {
esbuild: Omit<
BuildOptions,
| 'bundle'
| 'splitting'
| 'metafile'
| 'outbase'
| 'banner'
| 'format'
| 'entryPoints'
>;
jestConfig: JestConfig.InitialOptions | ((base: JestConfig.InitialOptions) => JestConfig.InitialOptions);
package: Record<string, unknown> | ((base: Record<string, unknown>) => Record<string, unknown>);
useTransformer: (context: { build: PluginBuild; transformer: ScriptTransformer; }) => void | Promise<void>;
postTransform: (filePath: string, fileContent: string) => string;
Expand Down
6 changes: 4 additions & 2 deletions index.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,9 @@ export async function build(esbuildJestConfig = {}) {
globalConfig,
projectConfig,
tests: tests.map(t => t.path),
package: wrapPackageMiddleware(esbuildJestConfig.package),
jestConfig: wrapPatcherMiddleware(esbuildJestConfig.jestConfig),
package: wrapPatcherMiddleware(esbuildJestConfig.package),
writeMetafile: esbuildBaseConfig.metafile,
useTransformer: esbuildJestConfig.useTransformer,
}),
...(esbuildBaseConfig.plugins || []),
Expand All @@ -108,7 +110,7 @@ export async function build(esbuildJestConfig = {}) {
return buildResult;
}

function wrapPackageMiddleware(config) {
function wrapPatcherMiddleware(config) {
return typeof config === 'function' ? config : createPackageMerger(config)
}

Expand Down
98 changes: 54 additions & 44 deletions plugin.mjs
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import { writeFile } from 'node:fs/promises';
import { sep, join, relative, resolve } from 'node:path';
import {writeFile} from 'node:fs/promises';
import {join, resolve, sep} from 'node:path';
import importFrom from 'import-from';
import { logger, optimizeTracing } from "./utils/logger.mjs";
import { convertPathToImport } from "./utils/resolve-module.mjs";
import { isBuiltinReporter } from "./utils/is-builtin-reporter.mjs";
import { mapSourceToOutputFiles } from "./utils/map-inputs-outputs.mjs";
import { moveJsFile } from "./utils/move-js-file.mjs";
import { pruneDirectory } from "./utils/prune-directory.mjs";
import { JEST_DEPENDENCIES } from "./utils/jest-dependencies.mjs";
import {logger, optimizeTracing} from "./utils/logger.mjs";
import {convertPathToImport} from "./utils/resolve-module.mjs";
import {isBuiltinReporter} from "./utils/is-builtin-reporter.mjs";
import {mapSourceToOutputFiles, relativizeEntries} from "./utils/map-inputs-outputs.mjs";
import {moveJsFile} from "./utils/move-js-file.mjs";
import {pruneDirectory} from "./utils/prune-directory.mjs";
import {JEST_DEPENDENCIES} from "./utils/jest-dependencies.mjs";

const noop = () => {};

Expand All @@ -24,11 +24,13 @@ const __JEST_CONFIG = (log, config) => __CONTENT(log, config, 'create jest confi
const __PACKAGE_JSON = (log, packageJson) => __CONTENT(log, packageJson, 'create package.json');

export default ({
jestConfig: jestConfigMiddleware,
package: packageMiddleware,
globalConfig,
projectConfig,
tests,
useTransformer = noop,
writeMetafile = false,
}) => {
return {
name: 'jest',
Expand All @@ -55,7 +57,46 @@ export default ({

__FILE_MAPPING_CREATING(logger, mappingInput);
const mapping = mapSourceToOutputFiles(mappingInput);
await moveExternalEntryPointsBackToRoot(mapping);
await pruneDirectory(join(outdir, 'node_modules'));
__FILE_MAPPING_CREATED(logger, mapping);
const flattenedConfig = jestConfigMiddleware({
maxWorkers: globalConfig.maxWorkers,
testTimeout: globalConfig.testTimeout,
reporters: globalConfig.reporters.map(mapReporter),

...projectConfig,
cacheDirectory: undefined,
cwd: undefined,
coverageDirectory: mapFile(projectConfig.coverageDirectory),
globalSetup: mapFile(projectConfig.globalSetup),
globalTeardown: mapFile(projectConfig.globalTeardown),
id: undefined,
moduleNameMapper: undefined,
rootDir: undefined,
roots: undefined,
runner: undefined,
setupFiles: projectConfig.setupFiles.map(mapFile),
setupFilesAfterEnv: projectConfig.setupFilesAfterEnv.map(mapFile),
testEnvironment: mapFile(projectConfig.testEnvironment),
testMatch: tests.map(mapFile),
testRunner: mapTestRunner(mapFile(projectConfig.testRunner)),
transform: {
'^(?!node_modules/).+\\.js$': '@swc/jest',
'^.+\\.jsx$': '@swc/jest',
'^.+\\.tsx?$': '@swc/jest',
},
transformIgnorePatterns: [],
});
__JEST_CONFIG(logger, flattenedConfig);
await writeFile(join(outdir, 'jest.config.json'), JSON.stringify(flattenedConfig, null, 2));

if (writeMetafile) {
await writeFile(join(outdir, 'metafile.json'), JSON.stringify({
...result.metafile,
mapping: relativizeEntries([rootDir, outdir], mapping),
}, null, 2) + '\n');
}

/**
* @param {string} file
Expand Down Expand Up @@ -125,37 +166,6 @@ export default ({
const segments = modulePath.split(sep);
return segments.map(x => x === 'node_modules' && replacements++ === 0 ? 'bundled_modules' : x).join(sep);
}

await moveExternalEntryPointsBackToRoot();
await pruneDirectory(join(outdir, 'node_modules'));

const flattenedConfig = {
maxWorkers: globalConfig.maxWorkers,
testTimeout: globalConfig.testTimeout,
reporters: globalConfig.reporters.map(mapReporter),

...projectConfig,
cacheDirectory: undefined,
cwd: undefined,
coverageDirectory: mapFile(projectConfig.coverageDirectory),
globalSetup: mapFile(projectConfig.globalSetup),
globalTeardown: mapFile(projectConfig.globalTeardown),
id: undefined,
moduleNameMapper: undefined,
rootDir: undefined,
roots: undefined,
runner: undefined,
setupFiles: projectConfig.setupFiles.map(mapFile),
setupFilesAfterEnv: projectConfig.setupFilesAfterEnv.map(mapFile),
testEnvironment: mapFile(projectConfig.testEnvironment),
testMatch: tests.map(mapFile),
testRunner: mapTestRunner(mapFile(projectConfig.testRunner)),
transform: undefined,
transformIgnorePatterns: undefined,
};

__JEST_CONFIG(logger, flattenedConfig);
await writeFile(join(outdir, 'jest.config.json'), JSON.stringify(flattenedConfig, null, 2));
});

build.onEnd(async (result) => {
Expand All @@ -175,12 +185,12 @@ export default ({
version: '0.0.0',
private: true,
scripts: {
test: "NODE_OPTIONS='-r @babel/register' jest"
test: "NODE_OPTIONS='-r @swc-node/register' jest"
},
dependencies: {
"@babel/core": "^7.24.6",
"@babel/plugin-transform-modules-commonjs": "^7.24.6",
"@babel/register": "^7.24.6",
"@swc/core": "^1.10.1",
"@swc/jest": "^0.2.37",
"@swc-node/register": "^1.10.9",

...externalDependencies,
},
Expand Down
10 changes: 9 additions & 1 deletion utils/map-inputs-outputs.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,20 @@ export function mapSourceToOutputFiles({ rootDir, outdir, sourceFiles, outputFil
return result;
}

export function relativizeEntries(rootDirs, mapping) {
return Object.fromEntries(
Object.entries(mapping).map(([source, output]) => [
path.relative(rootDirs[0], source),
path.relative(rootDirs[1], output),
]),
);
}

function adaptTwoDots(filePath) {
const segments = filePath.split(path.sep);
return segments.map(convertTwoDots).join(path.sep);
}

function convertTwoDots(segment) {
return segment === '_.._' ? '..' : segment;

}

0 comments on commit 2c297a9

Please sign in to comment.