index.js 2.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. const { semver } = require('@vue/cli-shared-utils')
  2. /** @param {import('@vue/cli/lib/MigratorAPI')} api MigratorAPI */
  3. module.exports = async (api) => {
  4. const pkg = require(api.resolve('package.json'))
  5. let localESLintRange = pkg.devDependencies.eslint
  6. // if project is scaffolded by Vue CLI 3.0.x or earlier,
  7. // the ESLint dependency (ESLint v4) is inside @vue/cli-plugin-eslint;
  8. // in Vue CLI v4 it should be extracted to the project dependency list.
  9. if (api.fromVersion('^3') && !localESLintRange) {
  10. localESLintRange = '^4.19.1'
  11. api.extendPackage({
  12. devDependencies: {
  13. eslint: localESLintRange,
  14. '@babel/eslint-parser': '^7.12.16',
  15. 'eslint-plugin-vue': '^4.5.0'
  16. }
  17. })
  18. }
  19. const localESLintMajor = semver.major(
  20. semver.maxSatisfying(['4.99.0', '5.99.0', '6.99.0', '7.99.0'], localESLintRange) ||
  21. // in case the user does not specify a typical caret range;
  22. // it is used as **fallback** because the user may have not previously
  23. // installed eslint yet, such as in the case that they are from v3.0.x
  24. // eslint-disable-next-line node/no-extraneous-require
  25. require('eslint/package.json').version
  26. )
  27. if (localESLintMajor > 6) {
  28. return
  29. }
  30. const { getDeps } = require('../eslintDeps')
  31. const newDeps = getDeps(api)
  32. if (pkg.devDependencies['@vue/eslint-config-airbnb']) {
  33. Object.assign(newDeps, getDeps(api, 'airbnb'))
  34. }
  35. if (pkg.devDependencies['@vue/eslint-config-standard']) {
  36. Object.assign(newDeps, getDeps(api, 'standard'))
  37. }
  38. if (pkg.devDependencies['@vue/eslint-config-prettier']) {
  39. Object.assign(newDeps, getDeps(api, 'prettier'))
  40. }
  41. const fields = { devDependencies: newDeps }
  42. if (newDeps['@babel/core'] && newDeps['@babel/eslint-parser']) {
  43. Reflect.deleteProperty(api.generator.pkg.devDependencies, 'babel-eslint')
  44. const minSupportedBabelCoreVersion = '>=7.2.0'
  45. const localBabelCoreVersion = pkg.devDependencies['@babel/core']
  46. if (localBabelCoreVersion &&
  47. semver.satisfies(
  48. localBabelCoreVersion,
  49. minSupportedBabelCoreVersion
  50. )) {
  51. Reflect.deleteProperty(newDeps, '@babel/core')
  52. }
  53. fields.eslintConfig = {
  54. parserOptions: {
  55. parser: '@babel/eslint-parser'
  56. }
  57. }
  58. }
  59. api.extendPackage(fields, { warnIncompatibleVersions: false })
  60. // in case anyone's upgrading from the legacy `typescript-eslint-parser`
  61. if (api.hasPlugin('typescript')) {
  62. api.extendPackage({
  63. eslintConfig: {
  64. parserOptions: {
  65. parser: '@typescript-eslint/parser'
  66. }
  67. }
  68. })
  69. }
  70. api.exitLog(`ESLint upgraded from v${localESLintMajor}. to v7\n`)
  71. // TODO:
  72. // transform `@vue/prettier` to `eslint:recommended` + `plugin:prettier/recommended`
  73. // remove `@vue/prettier/@typescript-eslint`
  74. // transform `@vue/typescript` to `@vue/typescript/recommended` and also fix prettier compatibility for it
  75. }