Skip to content

Commit

Permalink
fix: remove airbnb/google in style guides when using ts (#33)
Browse files Browse the repository at this point in the history
* fix: remove airbnb/google in style guides when using ts

as they do not officially support ts

* fix: extends "xo", "xo-typescript"

* fix: question typescript returns val

* fix: ts supports

* Update lib/init/config-initializer.js

* fix: use xo-typescript for ts files

* fix: upgrade esmock
  • Loading branch information
aladdin-add authored Aug 8, 2022
1 parent 7b4aa9c commit bf2a259
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 45 deletions.
105 changes: 64 additions & 41 deletions lib/init/config-initializer.js
Original file line number Diff line number Diff line change
Expand Up @@ -97,21 +97,29 @@ function getModulesList(config, installESLint) {
modules[moduleName] = "latest";
}
}
if (config.extends) {
const extendList = Array.isArray(config.extends) ? config.extends : [config.extends];

for (const extend of extendList) {
if (extend.startsWith("eslint:") || extend.startsWith("plugin:")) {
continue;
}
const moduleName = naming.normalizePackageName(extend, "eslint-config");
const extendList = [];
const overrides = config.overrides || [];

modules[moduleName] = "latest";
Object.assign(
modules,
getPeerDependencies(`${moduleName}@latest`)
);
for (const item of [config, ...overrides]) {
if (typeof item.extends === "string") {
extendList.push(item.extends);
} else if (Array.isArray(item.extends)) {
extendList.push(...item.extends);
}
}

for (const extend of extendList) {
if (extend.startsWith("eslint:") || extend.startsWith("plugin:")) {
continue;
}
const moduleName = naming.normalizePackageName(extend, "eslint-config");

modules[moduleName] = "latest";
Object.assign(
modules,
getPeerDependencies(`${moduleName}@latest`)
);
}

const parser = config.parser || (config.parserOptions && config.parserOptions.parser);
Expand Down Expand Up @@ -146,7 +154,8 @@ function processAnswers(answers) {
rules: {},
env: {},
parserOptions: {},
extends: []
extends: [],
overrides: []
};

config.parserOptions.ecmaVersion = "latest";
Expand All @@ -166,22 +175,16 @@ function processAnswers(answers) {

// add in library information
if (answers.framework === "react") {
config.parserOptions.ecmaFeatures = {
jsx: true
};
config.plugins = ["react"];
config.extends.push("plugin:react/recommended");
} else if (answers.framework === "vue") {
config.plugins = ["vue"];
config.extends.push("plugin:vue/vue3-essential");
}

if (answers.typescript) {
if (answers.framework === "vue") {
config.parserOptions.parser = "@typescript-eslint/parser";
} else {
config.parser = "@typescript-eslint/parser";
}
// if answers.source == "guide", the ts supports should be in the shared config.
if (answers.typescript && answers.source !== "guide") {
config.parser = "@typescript-eslint/parser";

if (Array.isArray(config.plugins)) {
config.plugins.push("@typescript-eslint");
Expand All @@ -190,6 +193,22 @@ function processAnswers(answers) {
}
}

// set config.extends based the selected guide
if (answers.source === "guide") {
if (answers.styleguide === "airbnb" && answers.framework !== "react") {
config.extends.push("airbnb-base");
} else if (answers.styleguide === "xo-typescript") {
config.extends.push("xo");
config.overrides.push({
files: ["*.ts", "*.tsx"],
extends: ["xo-typescript"]
});
} else {
config.extends.push(answers.styleguide);
}
}


// setup rules based on problems/style enforcement preferences
if (answers.purpose === "problems") {
config.extends.unshift("eslint:recommended");
Expand Down Expand Up @@ -349,6 +368,9 @@ function promptUser() {
if (!packageJsonExists) {
throw new Error("A package.json file is necessary to initialize ESLint. Run `npm init` to create a package.json file and try again.");
}

const styleGuides = [];

return enquirer.prompt([
{
type: "select",
Expand Down Expand Up @@ -391,7 +413,25 @@ function promptUser() {
message: "Does your project use TypeScript?",
enabled: "Yes",
disabled: "No",
initial: 0
initial: 0,
result(val) {
if (val) {

// remove airbnb/google javascript style guide, as they do not support ts
styleGuides.push(
{ message: "Standard: https://github.com/standard/eslint-config-standard-with-typescript", name: "standard-with-typescript" },
{ message: "XO: https://github.com/xojs/eslint-config-xo-typescript", name: "xo-typescript" }
);
} else {
styleGuides.push(
{ message: "Airbnb: https://github.com/airbnb/javascript", name: "airbnb" },
{ message: "Standard: https://github.com/standard/standard", name: "standard" },
{ message: "Google: https://github.com/google/eslint-config-google", name: "google" },
{ message: "XO: https://github.com/xojs/eslint-config-xo", name: "xo" }
);
}
return val;
}
},
{
type: "multiselect",
Expand Down Expand Up @@ -423,12 +463,7 @@ function promptUser() {
type: "select",
name: "styleguide",
message: "Which style guide do you want to follow?",
choices: [
{ message: "Airbnb: https://github.com/airbnb/javascript", name: "airbnb" },
{ message: "Standard: https://github.com/standard/standard", name: "standard" },
{ message: "Google: https://github.com/google/eslint-config-google", name: "google" },
{ message: "XO: https://github.com/xojs/eslint-config-xo", name: "xo" }
],
choices: styleGuides,
skip() {
return this.state.answers.source !== "guide";
},
Expand Down Expand Up @@ -480,20 +515,8 @@ function promptUser() {
if (earlyAnswers.installESLint === false && !semver.satisfies(earlyAnswers.localESLintVersion, earlyAnswers.requiredESLintVersionRange)) {
info(`Note: it might not work since ESLint's version is mismatched with the ${earlyAnswers.styleguide} config.`);
}
if (earlyAnswers.styleguide === "airbnb" && earlyAnswers.framework !== "react") {
earlyAnswers.styleguide = "airbnb-base";
}

const config = processAnswers(earlyAnswers);

if (Array.isArray(config.extends)) {
config.extends.push(earlyAnswers.styleguide);
} else if (config.extends) {
config.extends = [config.extends, earlyAnswers.styleguide];
} else {
config.extends = [earlyAnswers.styleguide];
}

const modules = getModulesList(config);

return askInstallModules(modules)
Expand Down
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@
},
"mocha": {
"loader": "esmock",
"ui": "bdd"
"ui": "bdd",
"timeout": 10000
},
"dependencies": {
"@eslint/eslintrc": "^1.0.3",
Expand All @@ -59,7 +60,7 @@
"eslint-plugin-jsdoc": "^37.0.3",
"eslint-plugin-node": "^11.1.0",
"eslint-release": "^3.2.0",
"esmock": "^1.7.5",
"esmock": "^1.8.8",
"espree": "^9.0.0",
"fs-teardown": "^0.3.0",
"lint-staged": "^12.1.2",
Expand Down
14 changes: 12 additions & 2 deletions tests/init/config-initializer.js
Original file line number Diff line number Diff line change
Expand Up @@ -179,9 +179,9 @@ describe("configInitializer", () => {
answers.framework = "react";
const config = init.processAnswers(answers);

assert.strictEqual(config.parserOptions.ecmaFeatures.jsx, true);
assert.strictEqual(config.parserOptions.ecmaVersion, "latest");
assert.deepStrictEqual(config.plugins, ["react"]);
assert.include(config.extends, "plugin:react/recommended");
});

it("should enable vue plugin", () => {
Expand All @@ -208,7 +208,6 @@ describe("configInitializer", () => {
const config = init.processAnswers(answers);

assert.deepStrictEqual(config.extends, ["eslint:recommended", "plugin:vue/vue3-essential", "plugin:@typescript-eslint/recommended"]);
assert.strictEqual(config.parserOptions.parser, "@typescript-eslint/parser");
assert.deepStrictEqual(config.plugins, ["vue", "@typescript-eslint"]);
});

Expand Down Expand Up @@ -273,6 +272,17 @@ describe("configInitializer", () => {
assert.include(modules, "eslint-config-xo@latest");
});

it("should support the xo-typescript style guide", () => {
const config = { extends: "xo", overrides: [{ files: ["*.ts"], extends: ["xo-typescript"] }] };
const modules = init.getModulesList(config);

assert.deepStrictEqual(config.extends, "xo");
assert.deepStrictEqual(config.overrides[0].extends[0], "xo-typescript");
assert.strictEqual(config.installedESLint, true);
assert.include(modules, "eslint-config-xo@latest");
assert.include(modules, "eslint-config-xo-typescript@latest");
});

it("should install required sharable config", () => {
const config = { extends: "google" };

Expand Down

0 comments on commit bf2a259

Please sign in to comment.