$30 off During Our Annual Pro Sale. View Details »

@cybozu/eslint-configから学ぶ、全社共通ESLint configの運用

Hiroyuki ANAI
February 10, 2021

@cybozu/eslint-configから学ぶ、全社共通ESLint configの運用

The lightning talk for フロントエンドカンファレンス福岡スピンオフ テーマ: ESLint
https://fec-fukuoka.connpass.com/event/201334/

Hiroyuki ANAI

February 10, 2021
Tweet

More Decks by Hiroyuki ANAI

Other Decks in Programming

Transcript

  1. !DZCP[VFTMJOUDPOpH͔ΒֶͿ
    શࣾڞ௨&4-JOUDPOpHͷӡ༻
    !QJSPTJLJDL
    !'&$'εϐϯΦϑ

    View Slide

  2. w ݀Ҫ!QJSPTJLJDL
    w αΠϘ΢ζגࣜձࣾ
    ϑϩϯτΤϯυΤΩεύʔτνʔϜ
    w ෱Ԭݝେ໺৓ࢢʹॅΜͰ͍·͢
    w Ϗʔϧ͕޷͖Ͱ͢🍺

    View Slide

  3. ࠓ೔ͷ࿩
    w !DZCP[VFTMJOUDPOpH͕ศརɻ
    ϓϥΠϕʔτͷ։ൃ΍෭ۀઌͰ΋࢖͍ͬͯΔɻ
    w νʔϜͰϝϯς͍ͯ͠Δ͕ɺ
    ೖࣾલʹ࡞ΒΕͨ΋ͷͰத਎ΛͪΌΜͱ
    ݟͨ͜ͱͳ͍
    w ಉ͡Α͏ʹڞ༗&4-JOUDPOpHΛ࡞Δ৔߹ɺ
    ԿΛ͢Ε͹͍͍͔஌Γ͔ͨͬͨͷͰௐ΂ͯΈͨ

    View Slide

  4. DZCP[VFTMJOUDPOpH&4-JOUSVMFTGPS$ZCP[V
    IUUQTHJUIVCDPNDZCP[VFTMJOUDPOpH

    View Slide

  5. ศར
    w ಋೖָ͕
    w OQNJ%!DZCP[VFTMJOUDPOpH͚ͩ
    w ϓϦηοτɺϧʔϧͷԘക͕Α͍ʢݸਓͷײ૝ʣ
    w QSFUUJFS༗ແɺ54༗ແɺ/PEFKTɺ3FBDUɺɺɺ

    View Slide

  6. ઌʹ݁࿦
    w ϓϥάΠϯ͸ɺQFFS%FQFOEFODJFTͰ͸ͳ͘
    EFQFOEFJODJFT
    w ςετΛॻ͘
    w ͦͷଞ
    w SFOPWBUFΛઃఆ͢Δ
    w ܾ·ͬͨϝϯόʔ͕ϝϯςɺ
    ܾ·ͬͨλΠϛϯάͰߋ৽͢Δ

    View Slide

  7. ϓϥάΠϯ͸ɺ
    QFFS%FQFOEFODJFTͰ͸ͳ͘EFQFOEFODJFT
    w ར༻ऀଆͷख͕ؒগͳ͍ʢಋೖ࣌ɺӡ༻࣌ʣ
    w ϓϥάΠϯ͕ผͷϓϥάΠϯʹґଘ͍ͯ͠Δ৔߹ɺ
    յΕΔՄೳੑ͕͋ΔͷͰ࢖͍͍ͨϓϥάΠϯ࣍ୈͰ
    ͸͋Δ
    w ࣾ಺ʹดͯ͡޿͘࢖Θͳ͍ͷͰ͋Ε͹ɺ͏·͍͘͘
    ͸ͣ👍

    View Slide

  8. ςετΛॻ͘
    w ϧʔϧ܊͝ͱʹςετ͕͋Δ
    w ґଘ͍ͯ͠ΔϓϥάΠϯͷߋ৽͕εϜʔζͳͷͰɺ
    ݹ͘ͳΓͮΒ͍

    View Slide

  9. ςετͷΠϝʔδ

    View Slide

  10. ςετͷΠϝʔδ
    ςετͰ͸ɺPLKTͰΤϥʔ͕ग़ͳ͍͜ͱɺFSSPSKTͰ૝ఆͨ͠Τϥʔ͕ग़Δ͜ͱΛ֬ೝ

    View Slide

  11. ςετίʔυྫ
    ςετͷίʔυ
    1 const assert = require("assert");
    2 const runLintWithFixtures = require("./lib/runLintWithFixtures");
    3
    4 describe("node", () => {
    5 it("should get expected errors and warninigs with node config", async () => {
    6 const result = await runLintWithFixtures("node");
    7 assert.deepStrictEqual(result, {
    8 "error.js": {
    9 errors: [
    10 "node/no-missing-require",
    11 "node/no-unsupported-features/es-syntax",
    12 ],
    13 },
    14 "ok.js": {},
    15 });
    16 });
    17 });
    ૝ఆͨ͠ΤϥʔΛు͍͍ͯΔ͔

    View Slide

  12. ςετίʔυྫ
    ςετͷίʔυ
    1 "use strict";
    2
    3 const { ESLint } = require("eslint");
    4 const path = require("path");
    5
    6 /**
    7 * Run ESlint and return the result per files
    8 * @param type lint type, which is in lib directory
    9 * @returns {Object} …
    10 */
    11 const runLintWithFixtures = async (type, configFile = `lib/${type}.js`) => {
    12 const eslint = new ESLint({
    13 overrideConfigFile: path.resolve(process.cwd(), configFile),
    14 ignore: false,
    15 useEslintrc: false,
    16 extensions: [".js", ".jsx", ".ts", ".tsx"]
    17 });
    18 const targetDir = path.resolve(__dirname, "..", "fixtures", type);
    19 const lintResult = await eslint.lintFiles([targetDir]);
    20 // console.log(JSON.stringify(lintResult, null, 2));
    21 return lintResult.reduce((results, { filePath, messages }) => { … }, {});
    22 };
    23
    24 module.exports = runLintWithFixtures;
    ςετ༻ͷ+4ϑΝΠϧʹରͯ͠&4-JOUΛ࣮ߦ

    View Slide

  13. ͦͷଞ
    w 3FOPWBUFΛઃఆ
    w ϝϯςޮ཰Λ্͛Δ
    w ઃఆˠIUUQTHJUIVCDPNDZCP[VSFOPWBUFDPOpH
    w ར༻ଆʹ΋ઃఆͯ͋͠Δͱঘྑ
    w ϝϯς͢Δਓ͕ܾ·͍ͬͯΔ
    w લ৬Ͱ͸୭΋ϝϯς͠ͳ͘ͳͬͨ
    w ۀ຿ͱͯ͠ϝϯς͢Δਓ͕ܾ·͍ͬͯΔํ͕͏·͍͖ͦ͘͏

    View Slide

  14. ·ͱΊ

    View Slide

  15. w ࣾ಺Ͱ࢖͏ͳΒQFFS%FQFOEFODJFTΑΓ
    EFQFOEFODJFTʹ
    ϓϥάΠϯΛೖΕͨ΄͏͕࢖͍উख͕Α͍
    w ςετ΍3FOPWBUFͰɺϝϯςͷίετΛԼ͛Δ
    w ϝϯς͢ΔਓΛఆΊΔ

    View Slide

  16. 8FSFIJSJOH
    4QFBLFSEFDLʹνʔϜ঺հࢿྉ͕͋Γ·͢
    IUUQTTQFBLFSEFDLDPNDZCP[VJOTJEFPVUGSPOUFOEFYQFSUUFBN

    View Slide

  17. ͓ΘΓ

    View Slide