Skip to content

Commit 151c286

Browse files
authored
Convert package to ESM (#113)
Converts this package to an ESM module. Kudos to [this guide](https://tsmx.net/convert-existing-nodejs-project-from-commonjs-to-esm/) and this issue: TypeStrong/ts-node#1997 In our organization, this is only possible for this package because it is not used anywhere else, and we rely on CommonJS extensively. Changes in detail: - Update `package.json` for ESM compatibility - Replace all `require()` with `import` statements - Add `.js` file extension to all file imports in TypeScript source files - Update TypeScript, ESLint, and Jest configs for ESM compatibility and recommended best practices - TypeScript (`tsconfig.json`) - Update the `module`/`moduleResolution` fields to `Node16`. - I chose `Node16` over `NodeNext`, as the behavior of `NodeNext` may change in the future. See [here](https://www.typescriptlang.org/docs/handbook/modules/reference.html#node16-nodenext) for details. - ESLint (`.eslintrc.cjs`) - `parseOptions.sourceType = 'module'` - Jest (`jest.config.cjs`) - Update the `moduleNameMapper` to strip the `.js` from local file imports. See [here](https://kulshekhar.github.io/ts-jest/docs/guides/esm-support/) for details. - Replace `ts-node` with `tsx`, which has better ESM compatibility. - Specifically, the former does not work with Node v20 at the moment: TypeStrong/ts-node#1997 - Update `jest-it-up` - This is so that we can use its `--config` option (thank you @PeterYinusa! rbardini/jest-it-up#12) to target our new `.cjs` config file.
1 parent 66c90b4 commit 151c286

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+577
-393
lines changed

.eslintrc.js renamed to .eslintrc.cjs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@ module.exports = {
33

44
extends: ['@metamask/eslint-config', '@metamask/eslint-config-nodejs'],
55

6+
parserOptions: {
7+
sourceType: 'module',
8+
},
9+
610
rules: {
711
// This makes integration tests easier to read by allowing setup code and
812
// assertions to be grouped together better
File renamed without changes.

bin/create-release-branch.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
#!/usr/bin/env node
22

3-
/* eslint-disable-next-line import/no-unassigned-import,import/no-unresolved */
4-
require('../dist/cli');
3+
// eslint-disable-next-line import/no-unassigned-import,import/no-unresolved
4+
import '../dist/cli';

jest.config.js renamed to jest.config.cjs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
* https://jestjs.io/docs/configuration
44
*/
55

6+
// This file needs to be .cjs for compatibility with jest-it-up.
67
module.exports = {
78
// All imported modules in your tests should be mocked automatically
89
// automock: false,
@@ -87,7 +88,11 @@ module.exports = {
8788
// ],
8889

8990
// A map from regular expressions to module names or to arrays of module names that allow to stub out resources with a single module
90-
// moduleNameMapper: {},
91+
moduleNameMapper: {
92+
// Strip the file extension from imports, so that e.g. `import { foo } from './foo.js'`
93+
// becomes `import { foo } from './foo'`. This is for compatibility with ESM.
94+
'^(\\.\\.?\\/.+)\\.js$': '$1',
95+
},
9196

9297
// An array of regexp pattern strings, matched against all module paths before considered 'visible' to the module loader
9398
// modulePathIgnorePatterns: [],

package.json

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
"type": "git",
77
"url": "https://github.com/MetaMask/create-release-branch.git"
88
},
9+
"type": "module",
10+
"exports": null,
911
"bin": "bin/create-release-branch.js",
1012
"files": [
1113
"bin/",
@@ -19,12 +21,12 @@
1921
"lint:fix": "yarn lint:eslint --fix && yarn lint:misc --write",
2022
"lint:misc": "prettier '**/*.json' '**/*.md' '!CHANGELOG.md' '**/*.yml' '!.yarnrc.yml' --ignore-path .gitignore --no-error-on-unmatched-pattern",
2123
"prepack": "./scripts/prepack.sh",
22-
"test": "jest && jest-it-up",
24+
"test": "jest && jest-it-up --config jest.config.cjs",
2325
"test:watch": "jest --watch"
2426
},
2527
"dependencies": {
2628
"@metamask/action-utils": "^1.0.0",
27-
"@metamask/utils": "^8.1.0",
29+
"@metamask/utils": "^8.2.1",
2830
"debug": "^4.3.4",
2931
"execa": "^5.1.1",
3032
"pony-cause": "^2.1.9",
@@ -58,15 +60,15 @@
5860
"eslint-plugin-node": "^11.1.0",
5961
"eslint-plugin-prettier": "^4.2.1",
6062
"jest": "^29.5.0",
61-
"jest-it-up": "^2.0.2",
63+
"jest-it-up": "^3.0.0",
6264
"jest-when": "^3.5.2",
6365
"nanoid": "^3.3.4",
6466
"prettier": "^2.2.1",
6567
"prettier-plugin-packagejson": "^2.3.0",
6668
"rimraf": "^4.0.5",
6769
"stdio-mock": "^1.2.0",
6870
"ts-jest": "^29.1.0",
69-
"ts-node": "^10.7.0",
71+
"tsx": "^4.6.1",
7072
"typescript": "~5.1.6"
7173
},
7274
"packageManager": "[email protected]",
@@ -79,7 +81,8 @@
7981
},
8082
"lavamoat": {
8183
"allowScripts": {
82-
"@lavamoat/preinstall-always-fail": false
84+
"@lavamoat/preinstall-always-fail": false,
85+
"tsx>esbuild": false
8386
}
8487
}
8588
}

src/cli.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { main } from './main';
1+
import { main } from './main.js';
22

33
/**
44
* The entrypoint to this tool.

src/editor.test.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { when } from 'jest-when';
2-
import { determineEditor } from './editor';
3-
import * as envModule from './env';
4-
import * as miscUtils from './misc-utils';
2+
import { determineEditor } from './editor.js';
3+
import * as envModule from './env.js';
4+
import * as miscUtils from './misc-utils.js';
55

66
jest.mock('./env');
77
jest.mock('./misc-utils');

src/editor.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import { getEnvironmentVariables } from './env';
2-
import { debug, resolveExecutable } from './misc-utils';
1+
import { getEnvironmentVariables } from './env.js';
2+
import { debug, resolveExecutable } from './misc-utils.js';
33

44
/**
55
* Information about the editor present on the user's computer.

src/env.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { getEnvironmentVariables } from './env';
1+
import { getEnvironmentVariables } from './env.js';
22

33
describe('env', () => {
44
describe('getEnvironmentVariables', () => {

src/fs.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import path from 'path';
33
import { rimraf } from 'rimraf';
44
import { when } from 'jest-when';
55
import * as actionUtils from '@metamask/action-utils';
6-
import { withSandbox } from '../tests/helpers';
6+
import { withSandbox } from '../tests/helpers.js';
77
import {
88
readFile,
99
writeFile,
@@ -12,7 +12,7 @@ import {
1212
fileExists,
1313
ensureDirectoryPathExists,
1414
removeFile,
15-
} from './fs';
15+
} from './fs.js';
1616

1717
jest.mock('@metamask/action-utils');
1818

0 commit comments

Comments
 (0)