diff --git a/.eslintrc.js b/.eslintrc.cjs similarity index 96% rename from .eslintrc.js rename to .eslintrc.cjs index 8e4aec244a31..8ee5a68dfe67 100644 --- a/.eslintrc.js +++ b/.eslintrc.cjs @@ -5,11 +5,21 @@ * LICENSE file in the root directory of this source tree. */ -const {getPackages} = require('./scripts/buildUtils'); +const fs = require('fs'); +const path = require('path'); +const {sync: readPkg} = require('read-pkg'); -const internalPackages = getPackages() - .map(({pkg}) => pkg.name) - .sort(); +function getPackages() { + const PACKAGES_DIR = path.resolve(__dirname, 'packages'); + const packages = fs + .readdirSync(PACKAGES_DIR) + .map(file => path.resolve(PACKAGES_DIR, file)) + .filter(f => fs.lstatSync(path.resolve(f)).isDirectory()); + return packages.map(packageDir => { + const pkg = readPkg({cwd: packageDir}); + return pkg.name; + }); +} module.exports = { env: { @@ -254,7 +264,7 @@ module.exports = { }, { env: {node: true}, - files: ['*.js', '*.jsx'], + files: ['*.js', '*.jsx', '*.mjs', '*.cjs'], }, { files: [ @@ -325,7 +335,7 @@ module.exports = { 'scripts/**', 'babel.config.js', 'testSetupFile.js', - '.eslintrc.js', + '.eslintrc.cjs', ], }, ], @@ -507,7 +517,9 @@ module.exports = { 'import/ignore': ['react-native'], // using `new RegExp` makes sure to escape `/` 'import/internal-regex': new RegExp( - internalPackages.map(pkg => `^${pkg}$`).join('|'), + getPackages() + .map(pkg => `^${pkg}$`) + .join('|'), ).source, 'import/resolver': { typescript: {}, diff --git a/.github/workflows/nodejs.yml b/.github/workflows/nodejs.yml index 7281963ff76c..2a653491fdaa 100644 --- a/.github/workflows/nodejs.yml +++ b/.github/workflows/nodejs.yml @@ -177,7 +177,7 @@ jobs: yarn jest-coverage --color --config jest.config.ci.js --max-workers ${{ steps.cpu-cores.outputs.count }} --shard=${{ matrix.shard }} yarn test-leak - name: map coverage - run: node ./scripts/mapCoverage.js + run: node ./scripts/mapCoverage.mjs if: always() - uses: codecov/codecov-action@v2 if: always() diff --git a/e2e/watch-plugins/cjs/my-watch-plugin.cjs b/e2e/watch-plugins/cjs/my-watch-plugin.cjs index 6fa3d51d68d4..b68701c9893c 100644 --- a/e2e/watch-plugins/cjs/my-watch-plugin.cjs +++ b/e2e/watch-plugins/cjs/my-watch-plugin.cjs @@ -6,8 +6,7 @@ */ class MyWatchPlugin { // Add hooks to Jest lifecycle events - apply(jestHooks) { - } + apply(jestHooks) {} // Get the prompt information for interactive plugins getUsageInfo(globalConfig) { @@ -15,8 +14,7 @@ class MyWatchPlugin { } // Executed when the key from `getUsageInfo` is input - run(globalConfig, updateConfigAndRun) { - } + run(globalConfig, updateConfigAndRun) {} } module.exports = MyWatchPlugin; diff --git a/e2e/watch-plugins/mjs/my-watch-plugin.mjs b/e2e/watch-plugins/mjs/my-watch-plugin.mjs index 873aaed19d58..f313583a7bb4 100644 --- a/e2e/watch-plugins/mjs/my-watch-plugin.mjs +++ b/e2e/watch-plugins/mjs/my-watch-plugin.mjs @@ -6,8 +6,7 @@ */ class MyWatchPlugin { // Add hooks to Jest lifecycle events - apply(jestHooks) { - } + apply(jestHooks) {} // Get the prompt information for interactive plugins getUsageInfo(globalConfig) { @@ -15,8 +14,7 @@ class MyWatchPlugin { } // Executed when the key from `getUsageInfo` is input - run(globalConfig, updateConfigAndRun) { - } + run(globalConfig, updateConfigAndRun) {} } export default MyWatchPlugin; diff --git a/package.json b/package.json index da9da1721c48..d93abceea817 100644 --- a/package.json +++ b/package.json @@ -87,31 +87,31 @@ "scripts": { "build-clean": "rimraf './packages/*/build' './packages/*/dist' './packages/*/tsconfig.tsbuildinfo' './packages/*/api-extractor.json' './api-extractor.json'", "build": "yarn build:js && yarn build:ts && yarn bundle:ts", - "build:js": "node ./scripts/build.js", - "build:ts": "node ./scripts/buildTs.js", - "bundle:ts": "node ./scripts/bundleTs.js", - "check-copyright-headers": "node ./scripts/checkCopyrightHeaders.js", + "build:js": "node ./scripts/build.mjs", + "build:ts": "node ./scripts/buildTs.mjs", + "bundle:ts": "node ./scripts/bundleTs.mjs", + "check-copyright-headers": "node ./scripts/checkCopyrightHeaders.mjs", "clean-all": "yarn clean-e2e && yarn build-clean && rimraf './packages/*/node_modules' && rimraf './node_modules'", - "clean-e2e": "node ./scripts/cleanE2e.js", + "clean-e2e": "node ./scripts/cleanE2e.mjs", "crowdin:upload": "echo 'Uploading sources to Crowdin' && crowdin upload sources --config ./crowdin.yaml", "crowdin:download": "echo 'Downloading translations from Crowdin' && crowdin download --config ./crowdin.yaml", "jest": "node ./packages/jest-cli/bin/jest.js", "jest-jasmine": "JEST_JASMINE=1 yarn jest", "jest-jasmine-ci": "yarn jest-jasmine --color --config jest.config.ci.js", "jest-coverage": "yarn jest --coverage", - "lint": "eslint . --cache --ext js,jsx,ts,tsx,md", + "lint": "eslint . --cache --ext js,jsx,cjs,mjs,ts,tsx,md", "lint:prettier": "prettier '**/*.{json,md,yml,yaml}' 'website/**/*.{css,js}' --write", "lint:prettier:ci": "prettier '**/*.{json,md,yml,yaml}' 'website/**/*.{css,js}' --check", - "remove-examples": "node ./scripts/remove-examples.js", + "remove-examples": "node ./scripts/remove-examples.mjs", "test-types": "yarn jest --config jest.config.tsd.js", "test-ci-partial": "yarn test-ci-partial:parallel -i", "test-ci-partial:parallel": "yarn jest --color --config jest.config.ci.js", "test-pretty-format-perf": "node packages/pretty-format/perf/test.js", "test-leak": "yarn jest -i --detectLeaks --color jest-mock jest-diff jest-repl pretty-format", "test": "yarn lint && yarn jest", - "verify-old-ts": "node ./scripts/verifyOldTs.js", - "verify-pnp": "node ./scripts/verifyPnP.js", - "watch": "yarn build:js && node ./scripts/watch.js", + "verify-old-ts": "node ./scripts/verifyOldTs.mjs", + "verify-pnp": "node ./scripts/verifyPnP.mjs", + "watch": "yarn build:js && node ./scripts/watch.mjs", "watch:ts": "yarn build:ts --watch" }, "workspaces": [ diff --git a/scripts/build.js b/scripts/build.mjs similarity index 83% rename from scripts/build.js rename to scripts/build.mjs index fa6c025ea2cf..4fa3eb2662d1 100644 --- a/scripts/build.js +++ b/scripts/build.mjs @@ -12,36 +12,39 @@ * Non-js files not matching IGNORE_PATTERN will be copied without transpiling. * * Example: - * node ./scripts/build.js - * node ./scripts/build.js /users/123/jest/packages/jest-111/src/111.js - * - * NOTE: this script is node@6 compatible + * node ./scripts/build.mjs + * node ./scripts/build.mjs /users/123/jest/packages/jest-111/src/111.js */ -'use strict'; - -const assert = require('assert'); -const fs = require('fs'); -const path = require('path'); -const babel = require('@babel/core'); -const chalk = require('chalk'); -const glob = require('glob'); -const micromatch = require('micromatch'); -const prettier = require('prettier'); -const transformOptions = require('../babel.config.js'); -const {getPackages, adjustToTerminalWidth, OK} = require('./buildUtils'); +import assert from 'assert'; +import path from 'path'; +import {fileURLToPath} from 'url'; +import babel from '@babel/core'; +import chalk from 'chalk'; +import glob from 'glob'; +import fs from 'graceful-fs'; +import micromatch from 'micromatch'; +import prettier from 'prettier'; +import transformOptions from '../babel.config.js'; +import { + OK, + PACKAGES_DIR, + adjustToTerminalWidth, + getPackages, +} from './buildUtils.mjs'; const SRC_DIR = 'src'; const BUILD_DIR = 'build'; const JS_FILES_PATTERN = '**/*.js'; const TS_FILES_PATTERN = '**/*.ts'; const IGNORE_PATTERN = '**/__{tests,mocks}__/**'; -const PACKAGES_DIR = path.resolve(__dirname, '../packages'); const INLINE_REQUIRE_EXCLUDE_LIST = /packages\/expect|(jest-(circus|diff|get-type|jasmine2|matcher-utils|message-util|regex-util|snapshot))|pretty-format\//; -const prettierConfig = prettier.resolveConfig.sync(__filename); +const prettierConfig = prettier.resolveConfig.sync( + fileURLToPath(import.meta.url), +); prettierConfig.trailingComma = 'none'; prettierConfig.parser = 'babel'; @@ -110,7 +113,10 @@ function buildFile(file, silent) { // The excluded modules are injected into the user's sandbox // We need to guard some globals there. options.plugins.push( - require.resolve('./babel-plugin-jest-native-globals'), + path.resolve( + path.dirname(fileURLToPath(import.meta.url)), + 'babel-plugin-jest-native-globals.js', + ), ); } else { options.plugins = options.plugins.map(plugin => { diff --git a/scripts/buildTs.js b/scripts/buildTs.mjs similarity index 93% rename from scripts/buildTs.js rename to scripts/buildTs.mjs index 5faf8bd38bd0..6ab57279aced 100644 --- a/scripts/buildTs.js +++ b/scripts/buildTs.mjs @@ -5,18 +5,16 @@ * LICENSE file in the root directory of this source tree. */ -'use strict'; - -const assert = require('assert'); -const fs = require('fs'); -const os = require('os'); -const path = require('path'); -const chalk = require('chalk'); -const execa = require('execa'); -const globby = require('globby'); -const stripJsonComments = require('strip-json-comments'); -const throat = require('throat'); -const {getPackages} = require('./buildUtils'); +import assert from 'assert'; +import os from 'os'; +import path from 'path'; +import chalk from 'chalk'; +import execa from 'execa'; +import globby from 'globby'; +import fs from 'graceful-fs'; +import stripJsonComments from 'strip-json-comments'; +import throat from 'throat'; +import {getPackages} from './buildUtils.mjs'; (async () => { const packages = getPackages(); diff --git a/scripts/buildUtils.js b/scripts/buildUtils.mjs similarity index 83% rename from scripts/buildUtils.js rename to scripts/buildUtils.mjs index 1136a369308d..67a721d1eb3b 100644 --- a/scripts/buildUtils.js +++ b/scripts/buildUtils.mjs @@ -5,26 +5,30 @@ * LICENSE file in the root directory of this source tree. */ -'use strict'; - -const assert = require('assert'); -const fs = require('fs'); -const path = require('path'); -const chalk = require('chalk'); -const {sync: readPkg} = require('read-pkg'); -const stringLength = require('string-length'); -const rootPackage = require('../package.json'); - -const PACKAGES_DIR = path.resolve(__dirname, '../packages'); - -const OK = chalk.reset.inverse.bold.green(' DONE '); +import assert from 'assert'; +import {createRequire} from 'module'; +import path from 'path'; +import {fileURLToPath} from 'url'; +import chalk from 'chalk'; +import fs from 'graceful-fs'; +import {sync as readPkg} from 'read-pkg'; +import stringLength from 'string-length'; + +export const PACKAGES_DIR = path.resolve( + path.dirname(fileURLToPath(import.meta.url)), + '../packages', +); + +export const OK = chalk.reset.inverse.bold.green(' DONE '); // Get absolute paths of all directories under packages/* -module.exports.getPackages = function getPackages() { +export function getPackages() { const packages = fs .readdirSync(PACKAGES_DIR) .map(file => path.resolve(PACKAGES_DIR, file)) .filter(f => fs.lstatSync(path.resolve(f)).isDirectory()); + const require = createRequire(import.meta.url); + const rootPackage = require('../package.json'); const nodeEngineRequirement = rootPackage.engines.node; @@ -104,9 +108,9 @@ module.exports.getPackages = function getPackages() { return {packageDir, pkg}; }); -}; +} -module.exports.adjustToTerminalWidth = function adjustToTerminalWidth(str) { +export function adjustToTerminalWidth(str) { const columns = process.stdout.columns || 80; const WIDTH = columns - stringLength(OK) + 1; const strs = str.match(new RegExp(`(.{1,${WIDTH}})`, 'g')); @@ -115,7 +119,4 @@ module.exports.adjustToTerminalWidth = function adjustToTerminalWidth(str) { lastString += Array(WIDTH - lastString.length).join(chalk.dim('.')); } return strs.slice(0, -1).concat(lastString).join('\n'); -}; - -module.exports.OK = OK; -module.exports.PACKAGES_DIR = PACKAGES_DIR; +} diff --git a/scripts/bundleTs.js b/scripts/bundleTs.mjs similarity index 89% rename from scripts/bundleTs.js rename to scripts/bundleTs.mjs index bdf20f05cc56..4cac2d4a4b08 100644 --- a/scripts/bundleTs.js +++ b/scripts/bundleTs.mjs @@ -5,25 +5,26 @@ * LICENSE file in the root directory of this source tree. */ -'use strict'; - -const fs = require('fs'); -const path = require('path'); -const { +import {createRequire} from 'module'; +import path from 'path'; +import {fileURLToPath} from 'url'; +import { CompilerState, Extractor, ExtractorConfig, -} = require('@microsoft/api-extractor'); -const chalk = require('chalk'); -const {sync: pkgDir} = require('pkg-dir'); -const prettier = require('prettier'); -const rimraf = require('rimraf'); -const {getPackages} = require('./buildUtils'); +} from '@microsoft/api-extractor'; +import chalk from 'chalk'; +import fs from 'graceful-fs'; +import {sync as pkgDir} from 'pkg-dir'; +import prettier from 'prettier'; +import rimraf from 'rimraf'; +import {getPackages} from './buildUtils.mjs'; const prettierConfig = prettier.resolveConfig.sync( - __filename.replace(/\.js$/, '.d.ts'), + fileURLToPath(import.meta.url).replace(/\.js$/, '.d.ts'), ); +const require = createRequire(import.meta.url); const typescriptCompilerFolder = pkgDir(require.resolve('typescript')); const copyrightSnippet = ` @@ -104,7 +105,10 @@ const copyrightSnippet = ` }; await fs.promises.writeFile( - path.resolve(__dirname, '../api-extractor.json'), + path.resolve( + path.dirname(fileURLToPath(import.meta.url)), + '../api-extractor.json', + ), JSON.stringify(sharedExtractorConfig, null, 2), ); diff --git a/scripts/checkCopyrightHeaders.js b/scripts/checkCopyrightHeaders.mjs similarity index 95% rename from scripts/checkCopyrightHeaders.js rename to scripts/checkCopyrightHeaders.mjs index 8d490d570f6c..78467692b227 100755 --- a/scripts/checkCopyrightHeaders.js +++ b/scripts/checkCopyrightHeaders.mjs @@ -5,11 +5,9 @@ * LICENSE file in the root directory of this source tree. */ -'use strict'; - -const {execSync} = require('child_process'); -const fs = require('fs'); -const {isBinaryFileSync} = require('isbinaryfile'); +import {execSync} from 'child_process'; +import fs from 'graceful-fs'; +import {isBinaryFileSync} from 'isbinaryfile'; const getFileContents = path => fs.readFileSync(path, {encoding: 'utf-8'}); const isDirectory = path => fs.lstatSync(path).isDirectory(); @@ -149,7 +147,7 @@ function check() { ${invalidFiles.join('\n ')} -Please include the header or exclude the files in \`scripts/checkCopyrightHeaders.js\``); +Please include the header or exclude the files in \`scripts/checkCopyrightHeaders.mjs\``); process.exit(1); } } diff --git a/scripts/cleanE2e.js b/scripts/cleanE2e.mjs similarity index 65% rename from scripts/cleanE2e.js rename to scripts/cleanE2e.mjs index 6292e749343d..09ee9d620f1d 100644 --- a/scripts/cleanE2e.js +++ b/scripts/cleanE2e.mjs @@ -5,11 +5,10 @@ * LICENSE file in the root directory of this source tree. */ -'use strict'; - -const {normalize, resolve} = require('path'); -const {sync: glob} = require('glob'); -const {sync: rimraf} = require('rimraf'); +import {dirname, normalize, resolve} from 'path'; +import {fileURLToPath} from 'url'; +import glob from 'glob'; +import rimraf from 'rimraf'; const excludedModules = [ 'e2e/global-setup-node-modules/node_modules/', @@ -22,12 +21,13 @@ const excludedModules = [ 'e2e/retain-all-files/node_modules/', ].map(dir => normalize(dir)); -const e2eNodeModules = glob('e2e/*/node_modules/') - .concat(glob('e2e/*/*/node_modules/')) +const e2eNodeModules = glob + .sync('e2e/*/node_modules/') + .concat(glob.sync('e2e/*/*/node_modules/')) .filter(dir => !excludedModules.includes(dir)) - .map(dir => resolve(__dirname, '..', dir)) + .map(dir => resolve(dirname(fileURLToPath(import.meta.url)), '..', dir)) .sort(); e2eNodeModules.forEach(dir => { - rimraf(dir, {glob: false}); + rimraf.sync(dir, {glob: false}); }); diff --git a/scripts/mapCoverage.js b/scripts/mapCoverage.mjs similarity index 87% rename from scripts/mapCoverage.js rename to scripts/mapCoverage.mjs index cf0a5e47f028..b78fe3da6418 100644 --- a/scripts/mapCoverage.js +++ b/scripts/mapCoverage.mjs @@ -25,9 +25,11 @@ * produce a full coverage report. */ -const istanbulCoverage = require('istanbul-lib-coverage'); -const istanbulReport = require('istanbul-lib-report'); -const istanbulReports = require('istanbul-reports'); +import {createRequire} from 'module'; +import istanbulCoverage from 'istanbul-lib-coverage'; +import istanbulReport from 'istanbul-lib-report'; +import istanbulReports from 'istanbul-reports'; +const require = createRequire(import.meta.url); const coverage = require('../coverage/coverage-final.json'); const map = istanbulCoverage.createCoverageMap(); diff --git a/scripts/remove-examples.js b/scripts/remove-examples.js deleted file mode 100644 index d77654f6fdc9..000000000000 --- a/scripts/remove-examples.js +++ /dev/null @@ -1,22 +0,0 @@ -/** - * 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 {writeFileSync} = require('fs'); -const {resolve} = require('path'); -const rimraf = require('rimraf'); - -const configFile = require.resolve('../jest.config'); - -const config = require(configFile); - -delete config.projects; - -writeFileSync(configFile, `module.exports = ${JSON.stringify(config)};\n`); - -rimraf.sync(resolve(__dirname, '../examples/')); diff --git a/scripts/remove-examples.mjs b/scripts/remove-examples.mjs new file mode 100644 index 000000000000..d1a22e519c57 --- /dev/null +++ b/scripts/remove-examples.mjs @@ -0,0 +1,23 @@ +/** + * 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. + */ + +import {createRequire} from 'module'; +import {dirname, resolve} from 'path'; +import {fileURLToPath} from 'url'; +import fs from 'graceful-fs'; +import rimraf from 'rimraf'; +const require = createRequire(import.meta.url); + +const configFile = require.resolve('../jest.config'); + +const config = require(configFile); + +delete config.projects; + +fs.writeFileSync(configFile, `module.exports = ${JSON.stringify(config)};\n`); + +rimraf.sync(resolve(dirname(fileURLToPath(import.meta.url)), '../examples/')); diff --git a/scripts/verifyOldTs.js b/scripts/verifyOldTs.mjs similarity index 90% rename from scripts/verifyOldTs.js rename to scripts/verifyOldTs.mjs index 113febee9909..481c500ad49e 100644 --- a/scripts/verifyOldTs.js +++ b/scripts/verifyOldTs.mjs @@ -5,15 +5,16 @@ * LICENSE file in the root directory of this source tree. */ -'use strict'; - -const fs = require('fs'); -const path = require('path'); -const chalk = require('chalk'); -const execa = require('execa'); -const rimraf = require('rimraf'); -const stripJsonComments = require('strip-json-comments'); -const tempy = require('tempy'); +import {createRequire} from 'module'; +import path from 'path'; +import {fileURLToPath} from 'url'; +import chalk from 'chalk'; +import execa from 'execa'; +import fs from 'graceful-fs'; +import rimraf from 'rimraf'; +import stripJsonComments from 'strip-json-comments'; +import tempy from 'tempy'; +const require = createRequire(import.meta.url); const baseTsConfig = JSON.parse( stripJsonComments( @@ -35,7 +36,10 @@ const tsConfig = { const tsVersion = '4.2'; function smoketest() { - const jestDirectory = path.resolve(__dirname, '../packages/jest'); + const jestDirectory = path.resolve( + path.dirname(fileURLToPath(import.meta.url)), + '../packages/jest', + ); const cwd = tempy.directory(); @@ -71,7 +75,7 @@ function smoketest() { } function typeTests() { - const cwd = path.resolve(__dirname, '../'); + const cwd = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '../'); const rootPackageJson = require('../package.json'); const currentTsdTypescriptVersion = diff --git a/scripts/verifyPnP.js b/scripts/verifyPnP.mjs similarity index 80% rename from scripts/verifyPnP.js rename to scripts/verifyPnP.mjs index cd49c4aae500..294ca451544c 100644 --- a/scripts/verifyPnP.js +++ b/scripts/verifyPnP.mjs @@ -5,18 +5,20 @@ * LICENSE file in the root directory of this source tree. */ -'use strict'; +import path from 'path'; +import {fileURLToPath} from 'url'; +import chalk from 'chalk'; +import dedent from 'dedent'; +import execa from 'execa'; +import fs from 'graceful-fs'; +import yaml from 'js-yaml'; +import rimraf from 'rimraf'; +import tempy from 'tempy'; -const fs = require('fs'); -const path = require('path'); -const chalk = require('chalk'); -const dedent = require('dedent'); -const execa = require('execa'); -const yaml = require('js-yaml'); -const rimraf = require('rimraf'); -const tempy = require('tempy'); - -const rootDirectory = path.resolve(__dirname, '..'); +const rootDirectory = path.resolve( + path.dirname(fileURLToPath(import.meta.url)), + '..', +); const cwd = tempy.directory(); diff --git a/scripts/watch.js b/scripts/watch.mjs similarity index 83% rename from scripts/watch.js rename to scripts/watch.mjs index 8c93185108fd..a4734d14ea3d 100644 --- a/scripts/watch.js +++ b/scripts/watch.mjs @@ -9,14 +9,18 @@ * Watch files for changes and rebuild (copy from 'src/' to `build/`) if changed */ -const {execSync} = require('child_process'); -const fs = require('fs'); -const path = require('path'); -const chalk = require('chalk'); -const chokidar = require('chokidar'); -const {PACKAGES_DIR, getPackages} = require('./buildUtils'); +import {execSync} from 'child_process'; +import path from 'path'; +import {fileURLToPath} from 'url'; +import chalk from 'chalk'; +import chokidar from 'chokidar'; +import fs from 'graceful-fs'; +import {PACKAGES_DIR, getPackages} from './buildUtils.mjs'; -const BUILD_CMD = `node ${path.resolve(__dirname, './build.js')}`; +const BUILD_CMD = `node ${path.resolve( + path.dirname(fileURLToPath(import.meta.url)), + 'build.mjs', +)}`; let filesToBuild = new Map();