Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Preserve import order for ESM #15031

Open
wants to merge 17 commits into
base: main
Choose a base branch
from
Open
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -32,6 +32,7 @@
- `[jest-snapshot]` [**BREAKING**] Add support for [Error causes](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error/cause) in snapshots ([#13965](https://github.com/facebook/jest/pull/13965))
- `[jest-snapshot]` Support Prettier 3 ([#14566](https://github.com/facebook/jest/pull/14566))
- `[pretty-format]` [**BREAKING**] Do not render empty string children (`''`) in React plugin ([#14470](https://github.com/facebook/jest/pull/14470))
- `[jest-runtime] provide an option to preserve the load order across CJS and ESM modules. Useful when load order is important (e.g., implicit dependencies or global declarations) ([#15031](https://github.com/jestjs/jest/pull/15031))

### Fixes

Expand Down
25 changes: 25 additions & 0 deletions docs/Configuration.md
Expand Up @@ -1094,6 +1094,31 @@ Default: `1000`

Print a warning indicating that there are probable open handles if Jest does not exit cleanly this number of milliseconds after it completes. Use `0` to disable the warning.

### `preserveLoadOrder` \[boolean]

Default: `false`

When running ESM tests, ensures that ESM and CJS modules load in the exact order that node would load them in. This only matters if you have implicit load order dependencies between ESM and CJS modules.

Consider the following:

```js
// __tests__/testfile.js
import '../file1.mjs';
import '../file3.mjs';

// file1.mjs
globalThis.Registrar = {};

// file3.mjs
import './file2.cjs';

// file2.cjs
globalThis.Registrar.whatever = true;
```

In node, this code will work - but in jest (without `preserveLoadOrder: true`) it will crash, because jest uses virtual modules - which can fully link before they run the code - as such, file2.cjs can run before file1.mjs

### `preset` \[string]

Default: `undefined`
Expand Down
2 changes: 2 additions & 0 deletions e2e/__tests__/__snapshots__/showConfig.test.ts.snap
Expand Up @@ -55,6 +55,7 @@ exports[`--showConfig outputs config info and exits 1`] = `
"moduleNameMapper": [],
"modulePathIgnorePatterns": [],
"openHandlesTimeout": 1000,
"preserveLoadOrder": false,
"prettierPath": "prettier",
"resetMocks": false,
"resetModules": false,
Expand Down Expand Up @@ -135,6 +136,7 @@ exports[`--showConfig outputs config info and exits 1`] = `
"onlyFailures": false,
"openHandlesTimeout": 1000,
"passWithNoTests": false,
"preserveLoadOrder": false,
"projects": [],
"rootDir": "<<REPLACED_ROOT_DIR>>",
"runInBand": false,
Expand Down
22 changes: 22 additions & 0 deletions e2e/__tests__/preserveLoadOrder.test.ts
@@ -0,0 +1,22 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

import runJest from '../runJest';

test("errors when you don't provide the option", () => {
const result = runJest('esm-load-order/default', [], {
nodeOptions: '--experimental-vm-modules',
});
expect(result.exitCode).toBe(1);
});

test('works when you do provide the option', () => {
const result = runJest('esm-load-order/preserve-load-order', [], {
nodeOptions: '--experimental-vm-modules',
});
expect(result.exitCode).toBe(0);

Check failure on line 21 in e2e/__tests__/preserveLoadOrder.test.ts

View workflow job for this annotation

GitHub Actions / Node LTS on Ubuntu with coverage (2/4)

works when you do provide the option

expect(received).toBe(expected) // Object.is equality Expected: 0 Received: 1 at Object.toBe (e2e/__tests__/preserveLoadOrder.test.ts:21:27)

Check failure on line 21 in e2e/__tests__/preserveLoadOrder.test.ts

View workflow job for this annotation

GitHub Actions / Node LTS on Ubuntu with coverage (2/4)

works when you do provide the option

expect(received).toBe(expected) // Object.is equality Expected: 0 Received: 1 at Object.toBe (e2e/__tests__/preserveLoadOrder.test.ts:21:27)

Check failure on line 21 in e2e/__tests__/preserveLoadOrder.test.ts

View workflow job for this annotation

GitHub Actions / Node LTS on Ubuntu with coverage (2/4)

works when you do provide the option

expect(received).toBe(expected) // Object.is equality Expected: 0 Received: 1 at Object.toBe (e2e/__tests__/preserveLoadOrder.test.ts:21:27)

Check failure on line 21 in e2e/__tests__/preserveLoadOrder.test.ts

View workflow job for this annotation

GitHub Actions / Ubuntu with shard 2/4 / Node v16.x

works when you do provide the option

expect(received).toBe(expected) // Object.is equality Expected: 0 Received: 1 at Object.toBe (e2e/__tests__/preserveLoadOrder.test.ts:21:27)

Check failure on line 21 in e2e/__tests__/preserveLoadOrder.test.ts

View workflow job for this annotation

GitHub Actions / Ubuntu with shard 2/4 / Node v16.x

works when you do provide the option

expect(received).toBe(expected) // Object.is equality Expected: 0 Received: 1 at Object.toBe (e2e/__tests__/preserveLoadOrder.test.ts:21:27)

Check failure on line 21 in e2e/__tests__/preserveLoadOrder.test.ts

View workflow job for this annotation

GitHub Actions / Ubuntu with shard 2/4 / Node v16.x

works when you do provide the option

expect(received).toBe(expected) // Object.is equality Expected: 0 Received: 1 at Object.toBe (e2e/__tests__/preserveLoadOrder.test.ts:21:27)

Check failure on line 21 in e2e/__tests__/preserveLoadOrder.test.ts

View workflow job for this annotation

GitHub Actions / Ubuntu with shard 2/4 / Node LTS using jest-jasmine2

works when you do provide the option

expect(received).toBe(expected) // Object.is equality Expected: 0 Received: 1 at Object.toBe (e2e/__tests__/preserveLoadOrder.test.ts:21:27)

Check failure on line 21 in e2e/__tests__/preserveLoadOrder.test.ts

View workflow job for this annotation

GitHub Actions / Ubuntu with shard 2/4 / Node LTS using jest-jasmine2

works when you do provide the option

expect(received).toBe(expected) // Object.is equality Expected: 0 Received: 1 at Object.toBe (e2e/__tests__/preserveLoadOrder.test.ts:21:27)

Check failure on line 21 in e2e/__tests__/preserveLoadOrder.test.ts

View workflow job for this annotation

GitHub Actions / Ubuntu with shard 2/4 / Node LTS using jest-jasmine2

works when you do provide the option

expect(received).toBe(expected) // Object.is equality Expected: 0 Received: 1 at Object.toBe (e2e/__tests__/preserveLoadOrder.test.ts:21:27)

Check failure on line 21 in e2e/__tests__/preserveLoadOrder.test.ts

View workflow job for this annotation

GitHub Actions / Ubuntu with shard 2/4 / Node v18.x

works when you do provide the option

expect(received).toBe(expected) // Object.is equality Expected: 0 Received: 1 at Object.toBe (e2e/__tests__/preserveLoadOrder.test.ts:21:27)

Check failure on line 21 in e2e/__tests__/preserveLoadOrder.test.ts

View workflow job for this annotation

GitHub Actions / Ubuntu with shard 2/4 / Node v18.x

works when you do provide the option

expect(received).toBe(expected) // Object.is equality Expected: 0 Received: 1 at Object.toBe (e2e/__tests__/preserveLoadOrder.test.ts:21:27)

Check failure on line 21 in e2e/__tests__/preserveLoadOrder.test.ts

View workflow job for this annotation

GitHub Actions / Ubuntu with shard 2/4 / Node v18.x

works when you do provide the option

expect(received).toBe(expected) // Object.is equality Expected: 0 Received: 1 at Object.toBe (e2e/__tests__/preserveLoadOrder.test.ts:21:27)

Check failure on line 21 in e2e/__tests__/preserveLoadOrder.test.ts

View workflow job for this annotation

GitHub Actions / Ubuntu with shard 2/4 / Node v20.x

works when you do provide the option

expect(received).toBe(expected) // Object.is equality Expected: 0 Received: 1 at Object.toBe (e2e/__tests__/preserveLoadOrder.test.ts:21:27)

Check failure on line 21 in e2e/__tests__/preserveLoadOrder.test.ts

View workflow job for this annotation

GitHub Actions / Ubuntu with shard 2/4 / Node v20.x

works when you do provide the option

expect(received).toBe(expected) // Object.is equality Expected: 0 Received: 1 at Object.toBe (e2e/__tests__/preserveLoadOrder.test.ts:21:27)

Check failure on line 21 in e2e/__tests__/preserveLoadOrder.test.ts

View workflow job for this annotation

GitHub Actions / Ubuntu with shard 2/4 / Node v20.x

works when you do provide the option

expect(received).toBe(expected) // Object.is equality Expected: 0 Received: 1 at Object.toBe (e2e/__tests__/preserveLoadOrder.test.ts:21:27)

Check failure on line 21 in e2e/__tests__/preserveLoadOrder.test.ts

View workflow job for this annotation

GitHub Actions / Ubuntu with shard 2/4 / Node v21.x

works when you do provide the option

expect(received).toBe(expected) // Object.is equality Expected: 0 Received: 1 at Object.toBe (e2e/__tests__/preserveLoadOrder.test.ts:21:27)

Check failure on line 21 in e2e/__tests__/preserveLoadOrder.test.ts

View workflow job for this annotation

GitHub Actions / Ubuntu with shard 2/4 / Node v21.x

works when you do provide the option

expect(received).toBe(expected) // Object.is equality Expected: 0 Received: 1 at Object.toBe (e2e/__tests__/preserveLoadOrder.test.ts:21:27)

Check failure on line 21 in e2e/__tests__/preserveLoadOrder.test.ts

View workflow job for this annotation

GitHub Actions / Ubuntu with shard 2/4 / Node v21.x

works when you do provide the option

expect(received).toBe(expected) // Object.is equality Expected: 0 Received: 1 at Object.toBe (e2e/__tests__/preserveLoadOrder.test.ts:21:27)

Check failure on line 21 in e2e/__tests__/preserveLoadOrder.test.ts

View workflow job for this annotation

GitHub Actions / Ubuntu with shard 2/4 / Node v22.x

works when you do provide the option

expect(received).toBe(expected) // Object.is equality Expected: 0 Received: 1 at Object.toBe (e2e/__tests__/preserveLoadOrder.test.ts:21:27)

Check failure on line 21 in e2e/__tests__/preserveLoadOrder.test.ts

View workflow job for this annotation

GitHub Actions / Ubuntu with shard 2/4 / Node v22.x

works when you do provide the option

expect(received).toBe(expected) // Object.is equality Expected: 0 Received: 1 at Object.toBe (e2e/__tests__/preserveLoadOrder.test.ts:21:27)

Check failure on line 21 in e2e/__tests__/preserveLoadOrder.test.ts

View workflow job for this annotation

GitHub Actions / Ubuntu with shard 2/4 / Node v22.x

works when you do provide the option

expect(received).toBe(expected) // Object.is equality Expected: 0 Received: 1 at Object.toBe (e2e/__tests__/preserveLoadOrder.test.ts:21:27)

Check failure on line 21 in e2e/__tests__/preserveLoadOrder.test.ts

View workflow job for this annotation

GitHub Actions / macOS with shard 2/3 / Node v16.x

works when you do provide the option

expect(received).toBe(expected) // Object.is equality Expected: 0 Received: 1 at Object.toBe (e2e/__tests__/preserveLoadOrder.test.ts:21:27) at runMicrotasks (<anonymous>)

Check failure on line 21 in e2e/__tests__/preserveLoadOrder.test.ts

View workflow job for this annotation

GitHub Actions / macOS with shard 2/3 / Node v16.x

works when you do provide the option

expect(received).toBe(expected) // Object.is equality Expected: 0 Received: 1 at Object.toBe (e2e/__tests__/preserveLoadOrder.test.ts:21:27)

Check failure on line 21 in e2e/__tests__/preserveLoadOrder.test.ts

View workflow job for this annotation

GitHub Actions / macOS with shard 2/3 / Node v16.x

works when you do provide the option

expect(received).toBe(expected) // Object.is equality Expected: 0 Received: 1 at Object.toBe (e2e/__tests__/preserveLoadOrder.test.ts:21:27)

Check failure on line 21 in e2e/__tests__/preserveLoadOrder.test.ts

View workflow job for this annotation

GitHub Actions / macOS with shard 2/3 / Node v18.x

works when you do provide the option

expect(received).toBe(expected) // Object.is equality Expected: 0 Received: 1 at Object.toBe (e2e/__tests__/preserveLoadOrder.test.ts:21:27)

Check failure on line 21 in e2e/__tests__/preserveLoadOrder.test.ts

View workflow job for this annotation

GitHub Actions / macOS with shard 2/3 / Node v18.x

works when you do provide the option

expect(received).toBe(expected) // Object.is equality Expected: 0 Received: 1 at Object.toBe (e2e/__tests__/preserveLoadOrder.test.ts:21:27)

Check failure on line 21 in e2e/__tests__/preserveLoadOrder.test.ts

View workflow job for this annotation

GitHub Actions / macOS with shard 2/3 / Node v18.x

works when you do provide the option

expect(received).toBe(expected) // Object.is equality Expected: 0 Received: 1 at Object.toBe (e2e/__tests__/preserveLoadOrder.test.ts:21:27)

Check failure on line 21 in e2e/__tests__/preserveLoadOrder.test.ts

View workflow job for this annotation

GitHub Actions / macOS with shard 2/3 / Node v20.x

works when you do provide the option

expect(received).toBe(expected) // Object.is equality Expected: 0 Received: 1 at Object.toBe (e2e/__tests__/preserveLoadOrder.test.ts:21:27)

Check failure on line 21 in e2e/__tests__/preserveLoadOrder.test.ts

View workflow job for this annotation

GitHub Actions / macOS with shard 2/3 / Node v20.x

works when you do provide the option

expect(received).toBe(expected) // Object.is equality Expected: 0 Received: 1 at Object.toBe (e2e/__tests__/preserveLoadOrder.test.ts:21:27)

Check failure on line 21 in e2e/__tests__/preserveLoadOrder.test.ts

View workflow job for this annotation

GitHub Actions / macOS with shard 2/3 / Node v20.x

works when you do provide the option

expect(received).toBe(expected) // Object.is equality Expected: 0 Received: 1 at Object.toBe (e2e/__tests__/preserveLoadOrder.test.ts:21:27)

Check failure on line 21 in e2e/__tests__/preserveLoadOrder.test.ts

View workflow job for this annotation

GitHub Actions / macOS with shard 2/3 / Node v21.x

works when you do provide the option

expect(received).toBe(expected) // Object.is equality Expected: 0 Received: 1 at Object.toBe (e2e/__tests__/preserveLoadOrder.test.ts:21:27)

Check failure on line 21 in e2e/__tests__/preserveLoadOrder.test.ts

View workflow job for this annotation

GitHub Actions / macOS with shard 2/3 / Node v21.x

works when you do provide the option

expect(received).toBe(expected) // Object.is equality Expected: 0 Received: 1 at Object.toBe (e2e/__tests__/preserveLoadOrder.test.ts:21:27)

Check failure on line 21 in e2e/__tests__/preserveLoadOrder.test.ts

View workflow job for this annotation

GitHub Actions / macOS with shard 2/3 / Node v21.x

works when you do provide the option

expect(received).toBe(expected) // Object.is equality Expected: 0 Received: 1 at Object.toBe (e2e/__tests__/preserveLoadOrder.test.ts:21:27)

Check failure on line 21 in e2e/__tests__/preserveLoadOrder.test.ts

View workflow job for this annotation

GitHub Actions / macOS with shard 2/3 / Node v22.x

works when you do provide the option

expect(received).toBe(expected) // Object.is equality Expected: 0 Received: 1 at Object.toBe (e2e/__tests__/preserveLoadOrder.test.ts:21:27)

Check failure on line 21 in e2e/__tests__/preserveLoadOrder.test.ts

View workflow job for this annotation

GitHub Actions / macOS with shard 2/3 / Node v22.x

works when you do provide the option

expect(received).toBe(expected) // Object.is equality Expected: 0 Received: 1 at Object.toBe (e2e/__tests__/preserveLoadOrder.test.ts:21:27)

Check failure on line 21 in e2e/__tests__/preserveLoadOrder.test.ts

View workflow job for this annotation

GitHub Actions / macOS with shard 2/3 / Node v22.x

works when you do provide the option

expect(received).toBe(expected) // Object.is equality Expected: 0 Received: 1 at Object.toBe (e2e/__tests__/preserveLoadOrder.test.ts:21:27)

Check failure on line 21 in e2e/__tests__/preserveLoadOrder.test.ts

View workflow job for this annotation

GitHub Actions / macOS with shard 2/3 / Node LTS using jest-jasmine2

works when you do provide the option

expect(received).toBe(expected) // Object.is equality Expected: 0 Received: 1 at Object.toBe (e2e/__tests__/preserveLoadOrder.test.ts:21:27)

Check failure on line 21 in e2e/__tests__/preserveLoadOrder.test.ts

View workflow job for this annotation

GitHub Actions / macOS with shard 2/3 / Node LTS using jest-jasmine2

works when you do provide the option

expect(received).toBe(expected) // Object.is equality Expected: 0 Received: 1 at Object.toBe (e2e/__tests__/preserveLoadOrder.test.ts:21:27)

Check failure on line 21 in e2e/__tests__/preserveLoadOrder.test.ts

View workflow job for this annotation

GitHub Actions / macOS with shard 2/3 / Node LTS using jest-jasmine2

works when you do provide the option

expect(received).toBe(expected) // Object.is equality Expected: 0 Received: 1 at Object.toBe (e2e/__tests__/preserveLoadOrder.test.ts:21:27)

Check failure on line 21 in e2e/__tests__/preserveLoadOrder.test.ts

View workflow job for this annotation

GitHub Actions / Windows with shard 2/4 / Node v16.x

works when you do provide the option

expect(received).toBe(expected) // Object.is equality Expected: 0 Received: 1 at Object.toBe (e2e/__tests__/preserveLoadOrder.test.ts:21:27)

Check failure on line 21 in e2e/__tests__/preserveLoadOrder.test.ts

View workflow job for this annotation

GitHub Actions / Windows with shard 2/4 / Node v16.x

works when you do provide the option

expect(received).toBe(expected) // Object.is equality Expected: 0 Received: 1 at Object.toBe (e2e/__tests__/preserveLoadOrder.test.ts:21:27)

Check failure on line 21 in e2e/__tests__/preserveLoadOrder.test.ts

View workflow job for this annotation

GitHub Actions / Windows with shard 2/4 / Node v16.x

works when you do provide the option

expect(received).toBe(expected) // Object.is equality Expected: 0 Received: 1 at Object.toBe (e2e/__tests__/preserveLoadOrder.test.ts:21:27)

Check failure on line 21 in e2e/__tests__/preserveLoadOrder.test.ts

View workflow job for this annotation

GitHub Actions / Windows with shard 2/4 / Node LTS using jest-jasmine2

works when you do provide the option

expect(received).toBe(expected) // Object.is equality Expected: 0 Received: 1 at Object.toBe (e2e/__tests__/preserveLoadOrder.test.ts:21:27)

Check failure on line 21 in e2e/__tests__/preserveLoadOrder.test.ts

View workflow job for this annotation

GitHub Actions / Windows with shard 2/4 / Node LTS using jest-jasmine2

works when you do provide the option

expect(received).toBe(expected) // Object.is equality Expected: 0 Received: 1 at Object.toBe (e2e/__tests__/preserveLoadOrder.test.ts:21:27)

Check failure on line 21 in e2e/__tests__/preserveLoadOrder.test.ts

View workflow job for this annotation

GitHub Actions / Windows with shard 2/4 / Node LTS using jest-jasmine2

works when you do provide the option

expect(received).toBe(expected) // Object.is equality Expected: 0 Received: 1 at Object.toBe (e2e/__tests__/preserveLoadOrder.test.ts:21:27)

Check failure on line 21 in e2e/__tests__/preserveLoadOrder.test.ts

View workflow job for this annotation

GitHub Actions / Windows with shard 2/4 / Node v18.x

works when you do provide the option

expect(received).toBe(expected) // Object.is equality Expected: 0 Received: 1 at Object.toBe (e2e/__tests__/preserveLoadOrder.test.ts:21:27)

Check failure on line 21 in e2e/__tests__/preserveLoadOrder.test.ts

View workflow job for this annotation

GitHub Actions / Windows with shard 2/4 / Node v18.x

works when you do provide the option

expect(received).toBe(expected) // Object.is equality Expected: 0 Received: 1 at Object.toBe (e2e/__tests__/preserveLoadOrder.test.ts:21:27)

Check failure on line 21 in e2e/__tests__/preserveLoadOrder.test.ts

View workflow job for this annotation

GitHub Actions / Windows with shard 2/4 / Node v18.x

works when you do provide the option

expect(received).toBe(expected) // Object.is equality Expected: 0 Received: 1 at Object.toBe (e2e/__tests__/preserveLoadOrder.test.ts:21:27)

Check failure on line 21 in e2e/__tests__/preserveLoadOrder.test.ts

View workflow job for this annotation

GitHub Actions / Windows with shard 2/4 / Node v20.x

works when you do provide the option

expect(received).toBe(expected) // Object.is equality Expected: 0 Received: 1 at Object.toBe (e2e/__tests__/preserveLoadOrder.test.ts:21:27)

Check failure on line 21 in e2e/__tests__/preserveLoadOrder.test.ts

View workflow job for this annotation

GitHub Actions / Windows with shard 2/4 / Node v20.x

works when you do provide the option

expect(received).toBe(expected) // Object.is equality Expected: 0 Received: 1 at Object.toBe (e2e/__tests__/preserveLoadOrder.test.ts:21:27)

Check failure on line 21 in e2e/__tests__/preserveLoadOrder.test.ts

View workflow job for this annotation

GitHub Actions / Windows with shard 2/4 / Node v20.x

works when you do provide the option

expect(received).toBe(expected) // Object.is equality Expected: 0 Received: 1 at Object.toBe (e2e/__tests__/preserveLoadOrder.test.ts:21:27)

Check failure on line 21 in e2e/__tests__/preserveLoadOrder.test.ts

View workflow job for this annotation

GitHub Actions / Windows with shard 2/4 / Node v21.x

works when you do provide the option

expect(received).toBe(expected) // Object.is equality Expected: 0 Received: 1 at Object.toBe (e2e/__tests__/preserveLoadOrder.test.ts:21:27)

Check failure on line 21 in e2e/__tests__/preserveLoadOrder.test.ts

View workflow job for this annotation

GitHub Actions / Windows with shard 2/4 / Node v21.x

works when you do provide the option

expect(received).toBe(expected) // Object.is equality Expected: 0 Received: 1 at Object.toBe (e2e/__tests__/preserveLoadOrder.test.ts:21:27)

Check failure on line 21 in e2e/__tests__/preserveLoadOrder.test.ts

View workflow job for this annotation

GitHub Actions / Windows with shard 2/4 / Node v21.x

works when you do provide the option

expect(received).toBe(expected) // Object.is equality Expected: 0 Received: 1 at Object.toBe (e2e/__tests__/preserveLoadOrder.test.ts:21:27)

Check failure on line 21 in e2e/__tests__/preserveLoadOrder.test.ts

View workflow job for this annotation

GitHub Actions / Windows with shard 2/4 / Node v22.x

works when you do provide the option

expect(received).toBe(expected) // Object.is equality Expected: 0 Received: 1 at Object.toBe (e2e/__tests__/preserveLoadOrder.test.ts:21:27)
});
10 changes: 10 additions & 0 deletions e2e/esm-load-order/__tests__/circular.js
@@ -0,0 +1,10 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

import '../circular/entry.js';

it('loads the circular dependency', () => {});
12 changes: 12 additions & 0 deletions e2e/esm-load-order/__tests__/mixed-package.js
@@ -0,0 +1,12 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

import '../mixed-package/file1.js';
import '../mixed-package/file3.js';

it('load order is preserved', () =>
expect(globalThis.Registrar['file1']).toEqual({}));
3 changes: 3 additions & 0 deletions e2e/esm-load-order/__tests__/package.json
@@ -0,0 +1,3 @@
{
"type": "module"
}
12 changes: 12 additions & 0 deletions e2e/esm-load-order/__tests__/packages.js
@@ -0,0 +1,12 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

import '../esm-package';
import '../cjs-package';

it('load order is preserved', () =>
expect(globalThis.Registrar['esm-package']).toEqual({}));
8 changes: 8 additions & 0 deletions e2e/esm-load-order/circular/entry.js
@@ -0,0 +1,8 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

import './file1.js';
8 changes: 8 additions & 0 deletions e2e/esm-load-order/circular/file1.js
@@ -0,0 +1,8 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

import './file2.js';
8 changes: 8 additions & 0 deletions e2e/esm-load-order/circular/file2.js
@@ -0,0 +1,8 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

import './file1.js';
3 changes: 3 additions & 0 deletions e2e/esm-load-order/circular/package.json
@@ -0,0 +1,3 @@
{
"type": "module"
}
8 changes: 8 additions & 0 deletions e2e/esm-load-order/cjs-package/index.cjs
@@ -0,0 +1,8 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

require('../esm-package/index.cjs');
8 changes: 8 additions & 0 deletions e2e/esm-load-order/cjs-package/index.js
@@ -0,0 +1,8 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

import '../esm-package/index.cjs';
4 changes: 4 additions & 0 deletions e2e/esm-load-order/cjs-package/package.json
@@ -0,0 +1,4 @@
{
"type": "commonjs",
"main": "./index.cjs"
}
8 changes: 8 additions & 0 deletions e2e/esm-load-order/default/__tests__/circular.js
@@ -0,0 +1,8 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

import '../../__tests__/circular.js';
8 changes: 8 additions & 0 deletions e2e/esm-load-order/default/__tests__/mixed-package.js
@@ -0,0 +1,8 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

import '../../__tests__/mixed-package.js';
8 changes: 8 additions & 0 deletions e2e/esm-load-order/default/__tests__/packages.js
@@ -0,0 +1,8 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

import '../../__tests__/packages.js';
7 changes: 7 additions & 0 deletions e2e/esm-load-order/default/package.json
@@ -0,0 +1,7 @@
{
"type": "module",
"jest": {
"transform": {},
"testEnvironment": "node"
}
}
8 changes: 8 additions & 0 deletions e2e/esm-load-order/esm-package/index.cjs
@@ -0,0 +1,8 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

module.exports = globalThis.Registrar['esm-package'];
10 changes: 10 additions & 0 deletions e2e/esm-load-order/esm-package/index.js
@@ -0,0 +1,10 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

globalThis.Registrar = {};

globalThis.Registrar['esm-package'] = {};
11 changes: 11 additions & 0 deletions e2e/esm-load-order/esm-package/package.json
@@ -0,0 +1,11 @@
{
"type": "module",
"exports": {
".": {
"node": {
"require": "./index.cjs",
"import": "./index.js"
}
}
}
}
10 changes: 10 additions & 0 deletions e2e/esm-load-order/mixed-package/file1.js
@@ -0,0 +1,10 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

globalThis.Registrar = {};

globalThis.Registrar['file1'] = {};
8 changes: 8 additions & 0 deletions e2e/esm-load-order/mixed-package/file2.cjs
@@ -0,0 +1,8 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

globalThis.Registrar['file1'];
8 changes: 8 additions & 0 deletions e2e/esm-load-order/mixed-package/file3.js
@@ -0,0 +1,8 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

import './file2.cjs';
11 changes: 11 additions & 0 deletions e2e/esm-load-order/mixed-package/package.json
@@ -0,0 +1,11 @@
{
"type": "module",
"exports": {
".": {
"node": {
"require": "./index.cjs",
"import": "./index.js"
}
}
}
}
8 changes: 8 additions & 0 deletions e2e/esm-load-order/preserve-load-order/__tests__/circular.js
@@ -0,0 +1,8 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

import '../../__tests__/circular.js';
@@ -0,0 +1,7 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import '../../__tests__/mixed-package.js';
8 changes: 8 additions & 0 deletions e2e/esm-load-order/preserve-load-order/__tests__/packages.js
@@ -0,0 +1,8 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

import '../../__tests__/packages.js';
8 changes: 8 additions & 0 deletions e2e/esm-load-order/preserve-load-order/package.json
@@ -0,0 +1,8 @@
{
"type": "module",
"jest": {
"transform": {},
"testEnvironment": "node",
"preserveLoadOrder": true
}
}
Expand Up @@ -230,6 +230,9 @@ const config: Config = {
// An enum that specifies notification mode. Requires { notify: true }
// notifyMode: "failure-change",

// Load CJS and ESM modules in the same order as node would
// preserveLoadOrder: false,

// A preset that is used as a base for Jest's configuration
// preset: undefined,

Expand Down Expand Up @@ -434,6 +437,9 @@ const config = {
// An enum that specifies notification mode. Requires { notify: true }
// notifyMode: "failure-change",

// Load CJS and ESM modules in the same order as node would
// preserveLoadOrder: false,

// A preset that is used as a base for Jest's configuration
// preset: undefined,

Expand Down Expand Up @@ -638,6 +644,9 @@ const config = {
// An enum that specifies notification mode. Requires { notify: true }
// notifyMode: "failure-change",

// Load CJS and ESM modules in the same order as node would
// preserveLoadOrder: false,

// A preset that is used as a base for Jest's configuration
// preset: undefined,

Expand Down
1 change: 1 addition & 0 deletions packages/jest-config/src/Defaults.ts
Expand Up @@ -64,6 +64,7 @@ const defaultOptions: Config.DefaultOptions = {
notifyMode: 'failure-change',
openHandlesTimeout: 1000,
passWithNoTests: false,
preserveLoadOrder: false,
prettierPath: 'prettier',
resetMocks: false,
resetModules: false,
Expand Down
1 change: 1 addition & 0 deletions packages/jest-config/src/Descriptions.ts
Expand Up @@ -52,6 +52,7 @@ const descriptions: {[key in keyof Config.InitialOptions]: string} = {
notify: 'Activates notifications for test results',
notifyMode:
'An enum that specifies notification mode. Requires { notify: true }',
preserveLoadOrder: 'Load CJS and ESM modules in the same order as node would',
preset: "A preset that is used as a base for Jest's configuration",
projects: 'Run tests from one or more projects',
reporters: 'Use this configuration option to add custom reporters to Jest',
Expand Down
2 changes: 2 additions & 0 deletions packages/jest-config/src/ValidConfig.ts
Expand Up @@ -120,6 +120,7 @@ export const initialOptions: Config.InitialOptions = {
onlyFailures: false,
openHandlesTimeout: 1000,
passWithNoTests: false,
preserveLoadOrder: false,
preset: 'react-native',
prettierPath: '<rootDir>/node_modules/prettier',
projects: ['project-a', 'project-b/'],
Expand Down Expand Up @@ -279,6 +280,7 @@ export const initialProjectOptions: Config.InitialProjectOptions = {
modulePathIgnorePatterns: ['<rootDir>/build/'],
modulePaths: ['/shared/vendor/modules'],
openHandlesTimeout: 1000,
preserveLoadOrder: false,
preset: 'react-native',
prettierPath: '<rootDir>/node_modules/prettier',
reporters: [
Expand Down
2 changes: 2 additions & 0 deletions packages/jest-config/src/index.ts
Expand Up @@ -116,6 +116,7 @@ const groupOptions = (
openHandlesTimeout: options.openHandlesTimeout,
outputFile: options.outputFile,
passWithNoTests: options.passWithNoTests,
preserveLoadOrder: options.preserveLoadOrder,
projects: options.projects,
randomize: options.randomize,
replname: options.replname,
Expand Down Expand Up @@ -178,6 +179,7 @@ const groupOptions = (
modulePathIgnorePatterns: options.modulePathIgnorePatterns,
modulePaths: options.modulePaths,
openHandlesTimeout: options.openHandlesTimeout,
preserveLoadOrder: options.preserveLoadOrder,
prettierPath: options.prettierPath,
reporters: options.reporters,
resetMocks: options.resetMocks,
Expand Down