Skip to content

Commit

Permalink
chore: make requiring from outside the Jest VM easier w/ a Babel plug…
Browse files Browse the repository at this point in the history
…in (#10824)
  • Loading branch information
jeysal committed Nov 14, 2020
1 parent dbb1290 commit e66a0e8
Show file tree
Hide file tree
Showing 6 changed files with 61 additions and 6 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -20,6 +20,7 @@

- `[*]` [**BREAKING**] Only support Node LTS releases and Node 15 ([#10685](https://github.com/facebook/jest/pull/10685))
- `[*]` [**BREAKING**] Add `exports` field to all `package.json`s ([#9921](https://github.com/facebook/jest/pull/9921))
- `[*]` Make it easier for Jest's packages to use the VM escape hatch ([#10824](https://github.com/facebook/jest/pull/10824))
- `[jest-config]` [**BREAKING**] Remove `enabledTestsMap` config, use `filter` instead ([#10787](https://github.com/facebook/jest/pull/10787))
- `[jest-resolve]` [**BREAKING**] Migrate to ESM ([#10688](https://github.com/facebook/jest/pull/10688))

Expand Down
1 change: 1 addition & 0 deletions babel.config.js
Expand Up @@ -56,6 +56,7 @@ module.exports = {
['@babel/plugin-transform-modules-commonjs', {allowTopLevelThis: true}],
'@babel/plugin-transform-strict-mode',
'@babel/plugin-proposal-class-properties',
require.resolve('./scripts/babel-plugin-jest-require-outside-vm'),
],
presets: [
[
Expand Down
Expand Up @@ -44,7 +44,7 @@ describe('Runtime require.resolve', () => {
);
});

describe('with the OUTSIDE_JEST_VM_RESOLVE_OPTION', () => {
describe('with the jest-resolve-outside-vm-option', () => {
it('forwards to the real Node require in an internal context', async () => {
const runtime = await createRuntime(__filename);
const module = runtime.requireInternalModule(
Expand Down
Expand Up @@ -8,7 +8,7 @@
'use strict';

const resolved = require.resolve('./create_require_module', {
[Symbol.for('OUTSIDE_JEST_VM_RESOLVE_OPTION')]: true,
[Symbol.for('jest-resolve-outside-vm-option')]: true,
});
if (typeof resolved !== 'string') {
throw new Error('require.resolve not spec-compliant: must return a string');
Expand Down
8 changes: 4 additions & 4 deletions packages/jest-runtime/src/index.ts
Expand Up @@ -92,11 +92,11 @@ const defaultTransformOptions: InternalModuleOptions = {
type InitialModule = Omit<Module, 'require' | 'parent' | 'paths'>;
type ModuleRegistry = Map<string, InitialModule | Module>;

const OUTSIDE_JEST_VM_RESOLVE_OPTION = Symbol.for(
'OUTSIDE_JEST_VM_RESOLVE_OPTION',
const JEST_RESOLVE_OUTSIDE_VM_OPTION = Symbol.for(
'jest-resolve-outside-vm-option',
);
type ResolveOptions = Parameters<typeof require.resolve>[1] & {
[OUTSIDE_JEST_VM_RESOLVE_OPTION]?: true;
[JEST_RESOLVE_OUTSIDE_VM_OPTION]?: true;
};

type StringMap = Map<string, string>;
Expand Down Expand Up @@ -1402,7 +1402,7 @@ export default class Runtime {
resolveOptions,
);
if (
resolveOptions?.[OUTSIDE_JEST_VM_RESOLVE_OPTION] &&
resolveOptions?.[JEST_RESOLVE_OUTSIDE_VM_OPTION] &&
options?.isInternalModule
) {
return createOutsideJestVmPath(resolved);
Expand Down
53 changes: 53 additions & 0 deletions scripts/babel-plugin-jest-require-outside-vm.js
@@ -0,0 +1,53 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

'use strict';

const assert = require('assert');

/*
Replace
requireOutside('package')
with
require(require.resolve('package', {
[Symbol.for('jest-resolve-outside-vm-option')]: true,
}));
*/

const REQUIRE_OUTSIDE_FUNCTION_NAME = 'requireOutside';

module.exports = ({template, types: t}) => {
const replacement = template(`
require(require.resolve(IMPORT_PATH, {
[(global['jest-symbol-do-not-touch'] || global.Symbol).for('jest-resolve-outside-vm-option')]: true,
}));
`);
return {
name: 'jest-require-outside-vm',
visitor: {
CallExpression(path) {
const {callee, arguments: args} = path.node;
if (
t.isIdentifier(callee) &&
callee.name === REQUIRE_OUTSIDE_FUNCTION_NAME &&
!path.scope.hasBinding(REQUIRE_OUTSIDE_FUNCTION_NAME)
) {
assert.strictEqual(
args.length,
1,
'requireOutside must be called with exactly one argument',
);
const importPath = args[0];
path.replaceWith(replacement({IMPORT_PATH: importPath}));
}
},
},
};
};

0 comments on commit e66a0e8

Please sign in to comment.