cli: simplify Jest ESM support
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
This commit is contained in:
@@ -19,6 +19,11 @@ const { default: JestRuntime } = require('jest-runtime');
|
||||
const scriptTransformCache = new Map();
|
||||
|
||||
module.exports = class CachingJestRuntime extends JestRuntime {
|
||||
constructor(config, ...restAgs) {
|
||||
super(config, ...restAgs);
|
||||
this.allowLoadAsEsm = config.extensionsToTreatAsEsm.includes('.mts');
|
||||
}
|
||||
|
||||
// This may or may not be a good idea. Theoretically I don't know why this would impact
|
||||
// test correctness and flakiness, but it seems like it may introduce flakiness and strange failures.
|
||||
// It does seem to speed up test execution by a fair amount though.
|
||||
@@ -34,19 +39,10 @@ module.exports = class CachingJestRuntime extends JestRuntime {
|
||||
return script;
|
||||
}
|
||||
|
||||
// Notes(Rugvip): As far as I can tell this is the best we can currently do
|
||||
// for runtime ESM support in Jest. What the below logic effectively does is
|
||||
// to only allow packages to be loaded as ESM if all imports of that package
|
||||
// are done in an ESM compatible way, as in either from ESM code or with a
|
||||
// dynamic import.
|
||||
cjsModules = new Set();
|
||||
_resolveCjsModule(...args) {
|
||||
const path = super._resolveCjsModule(...args);
|
||||
this.cjsModules.add(path);
|
||||
return path;
|
||||
}
|
||||
// Unfortunately we need to use this unstable API to make sure that .js files
|
||||
// are only loaded as modules where ESM is supported, i.e. Node.js packages.
|
||||
unstable_shouldLoadAsEsm(path, ...restArgs) {
|
||||
if (this.cjsModules.has(path)) {
|
||||
if (!this.allowLoadAsEsm) {
|
||||
return false;
|
||||
}
|
||||
return super.unstable_shouldLoadAsEsm(path, ...restArgs);
|
||||
|
||||
@@ -18,13 +18,18 @@ const { createTransformer: createSwcTransformer } = require('@swc/jest');
|
||||
const ESM_REGEX = /\b(?:import|export)\b/;
|
||||
|
||||
function createTransformer(config) {
|
||||
const useModules = Boolean(config?.module);
|
||||
const swcTransformer = createSwcTransformer({
|
||||
inputSourceMap: false,
|
||||
...config,
|
||||
});
|
||||
const process = (source, filePath, jestOptions) => {
|
||||
if (filePath.endsWith('.js') && (useModules || !ESM_REGEX.test(source))) {
|
||||
// Skip transformation of .js files without ESM syntax, we never transform from CJS to ESM
|
||||
if (filePath.endsWith('.js') && !ESM_REGEX.test(source)) {
|
||||
return { code: source };
|
||||
}
|
||||
|
||||
// Skip transformation of .mjs files, they should only be used if ESM support is available
|
||||
if (filePath.endsWith('.mjs')) {
|
||||
return { code: source };
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user