Upgrade to Pro — share decks privately, control downloads, hide ads and more …

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

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

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

Dc52871050369929247b69f3767e8737?s=128

Hiroyuki ANAI

February 10, 2021
Tweet

Transcript

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

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

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

    ԿΛ͢Ε͹͍͍͔஌Γ͔ͨͬͨͷͰௐ΂ͯΈͨ
  4. DZCP[VFTMJOUDPOpH&4-JOUSVMFTGPS$ZCP[V IUUQTHJUIVCDPNDZCP[VFTMJOUDPOpH

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

  6. ઌʹ݁࿦ w ϓϥάΠϯ͸ɺQFFS%FQFOEFODJFTͰ͸ͳ͘ EFQFOEFJODJFT w ςετΛॻ͘ w ͦͷଞ w SFOPWBUFΛઃఆ͢Δ

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

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

  9. ςετͷΠϝʔδ

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

  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 }); ૝ఆͨ͠ΤϥʔΛు͍͍ͯΔ͔
  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Λ࣮ߦ
  13. ͦͷଞ w 3FOPWBUFΛઃఆ w ϝϯςޮ཰Λ্͛Δ w ઃఆˠIUUQTHJUIVCDPNDZCP[VSFOPWBUFDPOpH w ར༻ଆʹ΋ઃఆͯ͋͠Δͱঘྑ w

    ϝϯς͢Δਓ͕ܾ·͍ͬͯΔ w લ৬Ͱ͸୭΋ϝϯς͠ͳ͘ͳͬͨ w ۀ຿ͱͯ͠ϝϯς͢Δਓ͕ܾ·͍ͬͯΔํ͕͏·͍͖ͦ͘͏
  14. ·ͱΊ

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

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

  17. ͓ΘΓ