Skip to content

Commit

Permalink
fix: support import cjs from mjs (#9850)
Browse files Browse the repository at this point in the history
  • Loading branch information
SimenB committed Apr 20, 2020
1 parent 5179604 commit 47e956f
Show file tree
Hide file tree
Showing 6 changed files with 41 additions and 31 deletions.
4 changes: 3 additions & 1 deletion CHANGELOG.md
Expand Up @@ -6,6 +6,8 @@

### Fixes

- `[jest-runtime]` Support importing CJS from ESM using `import` statements ([#9850](https://github.com/facebook/jest/pull/9850))

### Chore & Maintenance

### Performance
Expand All @@ -19,8 +21,8 @@
### Fixes

- `[expect]` Restore support for passing functions to `toHaveLength` matcher ([#9796](https://github.com/facebook/jest/pull/9796))
- `[jest-circus]` Throw on nested test definitions ([#9828](https://github.com/facebook/jest/pull/9828))
- `[jest-changed-files]` `--only-changed` should include staged files ([#9799](https://github.com/facebook/jest/pull/9799))
- `[jest-circus]` Throw on nested test definitions ([#9828](https://github.com/facebook/jest/pull/9828))
- `[jest-each]` `each` will throw an error when called with too many arguments ([#9818](https://github.com/facebook/jest/pull/9818))
- `[jest-runner]` Don't print warning to stdout when using `--json` ([#9843](https://github.com/facebook/jest/pull/9843))

Expand Down
2 changes: 1 addition & 1 deletion e2e/__tests__/__snapshots__/nativeEsm.test.ts.snap
Expand Up @@ -2,7 +2,7 @@

exports[`on node >=12.16.0 runs test with native ESM 1`] = `
Test Suites: 1 passed, 1 total
Tests: 8 passed, 8 total
Tests: 9 passed, 9 total
Snapshots: 0 total
Time: <<REPLACED>>
Ran all test suites.
Expand Down
5 changes: 5 additions & 0 deletions e2e/native-esm/__tests__/native-esm.test.js
Expand Up @@ -10,6 +10,7 @@ import {createRequire} from 'module';
import {dirname, resolve} from 'path';
import {fileURLToPath} from 'url';
import staticImportedStateful from '../stateful.mjs';
import staticImportedStatefulFromCjs from '../fromCjs.mjs';
import {double} from '../index';

test('should have correct import.meta', () => {
Expand Down Expand Up @@ -78,6 +79,10 @@ test('import from mjs and import(mjs) should share caches', async () => {
expect(staticImportedStateful()).toBe(6);
});

test('import cjs via import statement', () => {
expect(staticImportedStatefulFromCjs(4)).toBe(2);
});

test('handle unlinked dynamic imports', async () => {
const {double: deepDouble} = await import('../dynamicImport');

Expand Down
8 changes: 8 additions & 0 deletions e2e/native-esm/fromCjs.mjs
@@ -0,0 +1,8 @@
/**
* 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.
*/

export {default} from './commonjs.cjs';
4 changes: 2 additions & 2 deletions packages/jest-resolve/src/shouldLoadAsEsm.ts
Expand Up @@ -7,11 +7,11 @@

import {dirname, extname} from 'path';
// @ts-ignore: experimental, not added to the types
import {SourceTextModule} from 'vm';
import {SyntheticModule} from 'vm';
import type {Config} from '@jest/types';
import readPkgUp = require('read-pkg-up');

const runtimeSupportsVmModules = typeof SourceTextModule === 'function';
const runtimeSupportsVmModules = typeof SyntheticModule === 'function';

const cachedFileLookups = new Map<string, boolean>();
const cachedDirLookups = new Map<string, boolean>();
Expand Down
49 changes: 22 additions & 27 deletions packages/jest-runtime/src/index.ts
Expand Up @@ -112,7 +112,7 @@ const EVAL_RESULT_VARIABLE = 'Object.<anonymous>';

type RunScriptEvalResult = {[EVAL_RESULT_VARIABLE]: ModuleWrapper};

const runtimeSupportsVmModules = typeof SourceTextModule === 'function';
const runtimeSupportsVmModules = typeof SyntheticModule === 'function';

/* eslint-disable-next-line no-redeclare */
class Runtime {
Expand Down Expand Up @@ -351,39 +351,15 @@ class Runtime {
const module = new SourceTextModule(transformedFile.code, {
context,
identifier: modulePath,
importModuleDynamically: (
specifier: string,
referencingModule: VMModule,
) => {
const resolved = this._resolveModule(
referencingModule.identifier,
specifier,
);
if (
this._resolver.isCoreModule(resolved) ||
this.unstable_shouldLoadAsEsm(resolved)
) {
return this.loadEsmModule(resolved);
}

return this.loadCjsAsEsm(
referencingModule.identifier,
resolved,
context,
);
},
importModuleDynamically: this.linkModules.bind(this),
initializeImportMeta(meta: ImportMeta) {
meta.url = pathToFileURL(modulePath).href;
},
});

this._esmoduleRegistry.set(cacheKey, module);

await module.link((specifier: string, referencingModule: VMModule) =>
this.loadEsmModule(
this._resolveModule(referencingModule.identifier, specifier),
),
);
await module.link(this.linkModules.bind(this));

await module.evaluate();
}
Expand All @@ -395,6 +371,25 @@ class Runtime {
return module;
}

private async linkModules(specifier: string, referencingModule: VMModule) {
const resolved = this._resolveModule(
referencingModule.identifier,
specifier,
);
if (
this._resolver.isCoreModule(resolved) ||
this.unstable_shouldLoadAsEsm(resolved)
) {
return this.loadEsmModule(resolved);
}

return this.loadCjsAsEsm(
referencingModule.identifier,
resolved,
referencingModule.context,
);
}

async unstable_importModule(
from: Config.Path,
moduleName?: string,
Expand Down

0 comments on commit 47e956f

Please sign in to comment.