Skip to content

Commit

Permalink
Remove babel parser and plugin (#450)
Browse files Browse the repository at this point in the history
  • Loading branch information
BPScott authored Dec 21, 2024
1 parent b2bd706 commit 9c5e826
Show file tree
Hide file tree
Showing 18 changed files with 32 additions and 229 deletions.
18 changes: 18 additions & 0 deletions .changeset/weak-rats-explain.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
---
'@shopify/eslint-plugin': major
---

Remove Babel parser and plugin.

The Babel plugin and parser are only useful when authoring JavaScript that uses syntax that has not yet reached stage 4 of the standardisation process.

We do not wish to encourage the usage of non-standard syntax in `.js` files as a default supported behaviour.

If you wish to continue to use non-standard syntax in `.js` files then you should add and configure `@babel/eslint-parser` and `@babel/eslint-plugin` yourself.

- ESLint v8's `semi` and `no-invalid-this` rules provide the behaviour that `@babel/semi`, `@babel/no-invalid-this` were introduced to solve, and thus the babel versions of these rules are no longer requried.
- `@babel/new-cap` exists to handle the non-standard decorator syntax.
- `@babel/object-curly-spacing` exists to handle non-standard `export x from "mod"` syntax.
- `@babel/no-unused-expressions` exists to handle non-standard "do expressions".

Remove all mentions of `@babel/*` rules in your eslint config unless you configure the babel plugin yourself.
25 changes: 1 addition & 24 deletions packages/eslint-plugin/lib/config/esnext.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
const globals = require('globals');
const babelParser = require('@babel/eslint-parser');
const babelEslintPlugin = require('@babel/eslint-plugin');
const promisePlugin = require('eslint-plugin-promise');
const sortClassMembersPlugin = require('eslint-plugin-sort-class-members');
const importPlugin = require('eslint-plugin-import');
Expand All @@ -11,11 +9,9 @@ module.exports = [
...shopifyCoreConfig,
{
languageOptions: {
parser: babelParser,
parserOptions: {
ecmaVersion: '2021',
ecmaVersion: 'latest',
sourceType: 'module',
requireConfigFile: false,
},
globals: {
...globals.es2021,
Expand All @@ -24,13 +20,9 @@ module.exports = [

settings: {
'import/ignore': ['node_modules', '\\.s?css'],
'import/parsers': {
'@babel/eslint-parser': ['.js', '.cjs', '.mjs', '.jsx'],
},
},

plugins: {
'@babel': babelEslintPlugin,
promise: promisePlugin,
'sort-class-members': sortClassMembersPlugin,
import: importPlugin,
Expand Down Expand Up @@ -137,21 +129,6 @@ module.exports = [
// Prefer async/await to the callback pattern
'promise/prefer-await-to-callbacks': 'off',

//
// babel
//

// Ignores capitalized decorators (@Decorator)
'@babel/new-cap': ['error', {newIsCap: true, capIsNew: false}],
// Doesn't complain about export x from "mod"; or export * as x from "mod";
'@babel/object-curly-spacing': ['error', 'never'],
// Doesn't fail when inside class properties
'@babel/no-invalid-this': 'error',
// Doesn't fail when using do expressions or optional chaining
'@babel/no-unused-expressions': 'error',
// Rule to flag missing semicolons
'@babel/semi': 'error',

//
// sort-class-members
//
Expand Down
2 changes: 0 additions & 2 deletions packages/eslint-plugin/lib/config/prettier.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@ module.exports = [
'prettier/prettier': 'error',

// rules to disable to prefer prettier
'@babel/semi': 'off',
'@babel/object-curly-spacing': 'off',
'@shopify/class-property-semi': 'off',
'@shopify/binary-assignment-parens': 'off',
'prefer-arrow-callback': 'off',
Expand Down
5 changes: 0 additions & 5 deletions packages/eslint-plugin/lib/config/typescript.js
Original file line number Diff line number Diff line change
Expand Up @@ -287,11 +287,6 @@ module.exports = [
'space-infix-ops': 'off',
'@typescript-eslint/space-infix-ops': 'error',

// TypeScript provides a better mechanism (explicit `this` type)
// for ensuring proper `this` usage in functions not assigned to
// object properties.
'@babel/no-invalid-this': 'off',

// Handled by TypeScript itself
'no-undef': 'off',
'no-unused-expressions': 'off',
Expand Down
2 changes: 0 additions & 2 deletions packages/eslint-plugin/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,6 @@
},
"homepage": "https://github.com/Shopify/web-configs/blob/main/packages/eslint-plugin/README.md",
"dependencies": {
"@babel/eslint-parser": "^7.25.9",
"@babel/eslint-plugin": "^7.25.9",
"@typescript-eslint/eslint-plugin": "^7.9.0",
"@typescript-eslint/parser": "^7.9.0",
"change-case": "^4.1.2",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ const {RuleTester} = require('eslint');
const rule = require('../../../lib/rules/class-property-semi');

const ruleTester = new RuleTester({
parser: require.resolve('@babel/eslint-parser'),
parserOptions: {ecmaVersion: 'latest'},
});

const classPropNoSemi = 'class Foo { bar = 1 }';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,10 @@ const {fixtureFile} = require('../../utilities');
const rule = require('../../../lib/rules/jsx-no-hardcoded-content');

const ruleTester = new RuleTester({
parser: require.resolve('@babel/eslint-parser'),
parserOptions: {
babelOptions: {
presets: [
['@babel/preset-typescript', {isTSX: true, allExtensions: true}],
],
},
ecmaVersion: 'latest',
ecmaFeatures: {jsx: true},
sourceType: 'module',
},
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,7 @@ const {RuleTester} = require('eslint');
const rule = require('../../../lib/rules/jsx-prefer-fragment-wrappers');

const ruleTester = new RuleTester({
parser: require.resolve('@babel/eslint-parser'),
parserOptions: {
babelOptions: {
presets: [
['@babel/preset-typescript', {isTSX: true, allExtensions: true}],
],
},
},
parserOptions: {ecmaVersion: 'latest', ecmaFeatures: {jsx: true}},
});

function errorWithTagName(tagName) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ const {RuleTester} = require('eslint');
const rule = require('../../../lib/rules/no-fully-static-classes');

const ruleTester = new RuleTester({
parser: require.resolve('@babel/eslint-parser'),
parserOptions: {ecmaVersion: 'latest'},
});

function method(name = 'foo') {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,7 @@ const {RuleTester} = require('eslint');
const rule = require('../../../lib/rules/no-useless-computed-properties');

const ruleTester = new RuleTester({
parser: require.resolve('@babel/eslint-parser'),
parserOptions: {
ecmaVersion: 6,
},
parserOptions: {ecmaVersion: 'latest'},
});
const message = 'Computed property is using a literal key unnecessarily.';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,7 @@ const {RuleTester} = require('eslint');
const rule = require('../../../lib/rules/prefer-class-properties');

const ruleTester = new RuleTester({
parser: require.resolve('@babel/eslint-parser'),
parserOptions: {
ecmaVersion: 6,
},
parserOptions: {ecmaVersion: 'latest', sourceType: 'module'},
});

const classPropErrors = [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ const {RuleTester} = require('eslint');
const rule = require('../../../lib/rules/react-hooks-strict-return');

const ruleTester = new RuleTester({
parser: require.resolve('@babel/eslint-parser'),
parserOptions: {ecmaVersion: 'latest', sourceType: 'module'},
});

const errors = [
Expand Down
104 changes: 1 addition & 103 deletions packages/eslint-plugin/tests/lib/rules/react-initialize-state.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,10 @@ const {RuleTester} = require('eslint');
const rule = require('../../../lib/rules/react-initialize-state');

const ruleTester = new RuleTester({
parser: require.resolve('@babel/eslint-parser'),
parserOptions: {
babelOptions: {
presets: [
['@babel/preset-typescript', {isTSX: true, allExtensions: true}],
],
},
},
parser: require.resolve('@typescript-eslint/parser'),
settings: {react: {version: 'detect'}},
});

const typeScriptParser = require.resolve('@typescript-eslint/parser');

const errors = [
{
type: 'ClassDeclaration',
Expand Down Expand Up @@ -81,63 +72,15 @@ ruleTester.run('react-initialize-state', rule, {
}
}`,
},
{
code: 'class Button extends React.Component {}',
parser: typeScriptParser,
},
{
code: 'class Button extends React.Component<Props, {}> {}',
parser: typeScriptParser,
},
{
code: 'class Button extends React.Component<Props, never> {}',
parser: typeScriptParser,
},
{
code: 'class Button extends React.Component<Props, any> {}',
parser: typeScriptParser,
},
{
code: `class Button extends React.Component<Props, {focused: boolean}> {
state = {focused: false};
}`,
parser: typeScriptParser,
},
{
code: `class Button extends React.Component<Props, State> {
state = {focused: false};
}`,
parser: typeScriptParser,
},
{
code: `class Button extends React.Component<Props, State> {
state = getState();
}`,
parser: typeScriptParser,
},
{
code: `class Button extends React.Component<Props, State> {
constructor() {
this.state = {focused: true};
}
}`,
parser: typeScriptParser,
},
{
code: `class Button extends React.Component<Props, State> {
constructor() {
this.state = getState();
}
}`,
parser: typeScriptParser,
},
{
code: `class Button extends React.Component<Props, State> {
constructor() {
(this as any).state = {};
}
}`,
parser: typeScriptParser,
},
],
invalid: [
Expand Down Expand Up @@ -199,50 +142,5 @@ ruleTester.run('react-initialize-state', rule, {
`,
errors,
},
{
code: 'class Button extends React.Component<Props, {focused: boolean}> {}',
parser: typeScriptParser,
errors,
},
{
code: `class Button extends React.Component<Props, {focused: boolean}> {
state = null;
}`,
parser: typeScriptParser,
errors,
},
{
code: `class Button extends React.Component<Props, State> {
states = {focused: false};
}`,
parser: typeScriptParser,
errors,
},
{
code: `class Button extends React.Component<Props, State> {
constructor() {
this.state = null;
}
}`,
parser: typeScriptParser,
errors,
},
{
code: `class Button extends React.Component<Props, State> {
constructor() {
this.states = {focused: true};
}
}`,
parser: typeScriptParser,
errors,
},
{
code: `
class Button extends React.Component<Props, State> {}
class OtherClass {}
`,
parser: typeScriptParser,
errors,
},
],
});
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ const {RuleTester} = require('eslint');
const rule = require('../../../lib/rules/react-no-multiple-render-methods');

const ruleTester = new RuleTester({
parser: require.resolve('@babel/eslint-parser'),
parserOptions: {ecmaVersion: 'latest'},
settings: {react: {version: 'detect'}},
});

Expand Down
Loading

0 comments on commit 9c5e826

Please sign in to comment.