diff --git a/.changeset/nine-apricots-cough.md b/.changeset/nine-apricots-cough.md new file mode 100644 index 00000000..0d6f54ca --- /dev/null +++ b/.changeset/nine-apricots-cough.md @@ -0,0 +1,5 @@ +--- +"prettier-eslint": major +--- + +feat! add support for prettier v3 diff --git a/.eslintrc.js b/.eslintrc.js index 9c6d945d..95563ec1 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -1,5 +1,8 @@ const config = { extends: ['kentcdodds', 'kentcdodds/jest'], + parserOptions: { + ecmaVersion: 2021, + }, rules: { 'valid-jsdoc': 'off', 'max-len': 'off', diff --git a/package-scripts.js b/package-scripts.js index 008403b2..17f218ce 100644 --- a/package-scripts.js +++ b/package-scripts.js @@ -18,9 +18,13 @@ module.exports = { }, }, test: { - default: crossEnv('NODE_ENV=test jest --coverage'), - update: crossEnv('NODE_ENV=test jest --coverage --updateSnapshot'), - watch: crossEnv('NODE_ENV=test jest --watch'), + // Note: The `--experimental-vm-modules` flag is required for Jest to work + // with ESM. ESM support is needed due to prettier v3’s use of a dynamic + // `import()` in its `.cjs` file. The flag can be removed when node + // supports modules in the VM API or the import is removed from prettier. + default: crossEnv('NODE_ENV=test NODE_OPTIONS=--experimental-vm-modules jest --coverage'), + update: crossEnv('NODE_ENV=test NODE_OPTIONS=--experimental-vm-modules jest --coverage --updateSnapshot'), + watch: crossEnv('NODE_ENV=test NODE_OPTIONS=--experimental-vm-modules jest --watch'), openCoverage: 'open coverage/lcov-report/index.html', }, build: { diff --git a/package.json b/package.json index 49a9532c..0ec8047b 100644 --- a/package.json +++ b/package.json @@ -29,28 +29,28 @@ "indent-string": "^4.0.0", "lodash.merge": "^4.6.0", "loglevel-colored-level-prefix": "^1.0.0", - "prettier": "^2.5.1", + "prettier": "^3.0.1", "pretty-format": "^23.0.1", "require-relative": "^0.8.7", "typescript": "^4.5.4", "vue-eslint-parser": "^9.1.0" }, "devDependencies": { - "@babel/cli": "^7.4.4", - "@babel/core": "^7.4.5", - "@babel/preset-env": "^7.4.5", + "@babel/cli": "^7.22.9", + "@babel/core": "^7.22.9", + "@babel/preset-env": "^7.22.9", "acorn": "^6.1.1", "ajv": "^6.12.2", "all-contributors-cli": "^6.7.0", - "babel-jest": "^25.0.0", + "babel-jest": "^29.6.2", "chalk": "^2.1.0", - "eslint-config-kentcdodds": "^20.0.1", + "eslint-config-kentcdodds": "^20.5.0", "husky": "^8.0.1", - "jest": "^25.0.0", - "jest-cli": "^25.0.0", + "jest": "^29.6.2", + "jest-cli": "^29.6.2", "nps": "^5.7.1", "nps-utils": "^1.3.0", - "prettier-eslint-cli": "^7.0.0", + "prettier-eslint-cli": "^7.1.0", "rimraf": "^2.5.4", "semantic-release": "^15.13.16", "strip-indent": "^3.0.0" diff --git a/src/index.js b/src/index.js index 89ff725d..a4129599 100644 --- a/src/index.js +++ b/src/index.js @@ -19,14 +19,14 @@ module.exports = format; /** * Formats the text with prettier and then eslint based on the given options * @param {String} options.filePath - the path of the file being formatted - * can be used in leu of `eslintConfig` (eslint will be used to find the + * can be used in lieu of `eslintConfig` (eslint will be used to find the * relevant config for the file). Will also be used to load the `text` if * `text` is not provided. * @param {String} options.text - the text (JavaScript code) to format * @param {String} options.eslintPath - the path to the eslint module to use. * Will default to require.resolve('eslint') * @param {String} options.prettierPath - the path to the prettier module. - * Will default to require.resovlve('prettier') + * Will default to require.resolve('prettier') * @param {Object} options.eslintConfig - the config to use for formatting * with ESLint. * @param {Object} options.prettierOptions - the options to pass for @@ -62,7 +62,9 @@ async function format(options) { const prettierOptions = merge( {}, - filePath && { filepath: filePath }, + // Let prettier infer the parser using the filepath, if present. Otherwise + // assume the file is JS and default to the babel parser. + filePath ? { filepath: filePath } : { parser: 'babel' }, getPrettierConfig(filePath, prettierPath), options.prettierOptions ); @@ -111,14 +113,11 @@ async function format(options) { } if (['.ts', '.tsx'].includes(fileExtension)) { - formattingOptions.eslint.parser = - formattingOptions.eslint.parser || - require.resolve('@typescript-eslint/parser'); + formattingOptions.eslint.parser ||= require.resolve('@typescript-eslint/parser'); } if (['.vue'].includes(fileExtension)) { - formattingOptions.eslint.parser = - formattingOptions.eslint.parser || require.resolve('vue-eslint-parser'); + formattingOptions.eslint.parser ||= require.resolve('vue-eslint-parser'); } const eslintFix = await createEslintFix(formattingOptions.eslint, eslintPath); @@ -127,11 +126,11 @@ async function format(options) { const eslintFixed = await eslintFix(text, filePath); return prettify(eslintFixed); } - return eslintFix(prettify(text), filePath); + return eslintFix(await prettify(text), filePath); } function createPrettify(formatOptions, prettierPath) { - return function prettify(text) { + return async function prettify(text) { logger.debug('calling prettier on text'); logger.trace( stripIndent` @@ -143,7 +142,7 @@ function createPrettify(formatOptions, prettierPath) { const prettier = requireModule(prettierPath, 'prettier'); try { logger.trace('calling prettier.format with the text and prettierOptions'); - const output = prettier.format(text, formatOptions); + const output = await prettier.format(text, formatOptions); logger.trace('prettier: output === input', output === text); logger.trace( stripIndent`