Tslint: Proposal: Konfigurasi serat bersyarat

Dibuat pada 3 Nov 2017  ·  42Komentar  ·  Sumber: palantir/tslint

Ada beberapa situasi di mana kami ingin menerapkan pemeriksaan lint secara kondisional berdasarkan apakah kode yang dilinting adalah kode uji atau bukan. Misalnya, kami ingin melarang 'apa pun' dari kode produksi, karena tidak aman. Tetapi dalam pengujian, 'any' dapat berguna untuk menyediakan implementasi layanan palsu atau tiruan, atau untuk mentransmisikannya sehingga Anda dapat memanggil metode pribadi. Atau kita mungkin ingin melarang serangkaian metode yang berbeda dalam pengujian vs dalam kode produksi, misalnya.

Apa yang saya usulkan adalah cara untuk mengaktifkan pemeriksaan lint secara kondisional berdasarkan kecocokan regex pada nama file. Ini juga dapat berguna untuk menonaktifkan pemeriksaan lint untuk direktori tertentu (berisi kode "warisan", misalnya), atau untuk file .tsx atau .d.ts, dll.

Berikut adalah beberapa ide sintaksis strawman; Saya juga terbuka untuk saran.

Objek bagian

{
  "rules": {
    "no-any": {"other": true},
    "no-console":
        {
          "test": [true, "warn", "error"], 
          "other": [true, "log", "warn", "error"]
        }
  },
  "sections": {
    "test": ".*\\.spec\\.ts$"
  }
}

"Lainnya" akan menjadi hal-hal yang tidak cocok dengan salah satu regex. Ini cukup ringkas, tetapi saya pikir keterbacaan bagian aturan sedikit berkurang.

Aturan "Ganti"

{
  "rules": {
    "no-any": true,
    "no-console": [true, "log", "warn", "error"]
  },
  "override": {
    "match": ".*\\.spec\\.ts$",
    "rules": {
      "no-any": false,
      "no-console": [true, "warn", "error"]
    }
  }
}

(ini mungkin harus berupa array, untuk memungkinkan beberapa penggantian juga).

Declined Enhancement

Komentar yang paling membantu

Bersarang tidak menyelesaikan masalah yang dibahas di sini. Banyak orang melakukan ingin tes mereka di struktur direktori yang sama seperti kode itu tes, dan ada cara sederhana tidak baik untuk melakukan itu dengan tslint sekarang.

Semua 42 komentar

Jika Anda meletakkan pengujian dan kode produksi di direktori terpisah, Anda tidak memerlukan fitur seperti itu. Jika Anda tidak memberikan file konfigurasi sebagai argumen CLI, TSLint menggunakan tslint.json . Oleh karena itu Anda dapat memiliki pengaturan yang berbeda untuk folder yang berbeda. Dengan menggunakan "extends" Anda dapat menggunakan konfigurasi dasar yang sama dan hanya mengesampingkan aturan tertentu.

Saya mendapatkan bahwa banyak proyek Angular dan React melakukan tes di direktori yang sama dengan kode produksi yang sesuai. Secara pribadi saya pikir ini adalah praktik yang buruk. Saya telah melihat cukup banyak orang (secara tidak sengaja) mengimpor simbol dari tes dalam kode produksi.

IMO fitur yang diusulkan menambah banyak kerumitan. Implementasinya mungkin tidak terlalu sulit, tetapi membuat file konfigurasi sulit untuk dibaca dan dipahami.
Jika kita akan menerapkan ini, saya lebih suka saran kedua.

Kami juga perlu mendiskusikan cara kerjanya saat memperluas konfigurasi. Dalam urutan apa penggantian diterapkan?

Benar, Anda bisa saja memisahkan kodenya, tetapi itu merusak ergonomi. Entah kamu punya

src/
  tslint.json
  a/
    b/
      c/
test/
  tslint.json (extends ../src)
  a/
    b/
      c/

dan c/foo.spec.ts harus import {symbol} from '../../../a/b/c/foo';

Jalur itu menjadi jelek di monorepo kami di mana file seringkali sangat jauh di dalam pohon.

atau kamu punya

  a/
    src/
      tslint.json
    test/
      tslint.json (extends ../src)
    b/
      src/
        tslint.json
      test/
        tslint.json (extends ../src)
      c/
        src/
           tslint.json
        test/
          tslint.json (extends ../src)

yang terlalu banyak file tslint.json

Tentang topik penggantian: Saya akan mengatakan penggantian berlaku dalam aturan urutan yang sama diterapkan. Saya tidak tahu apa itu, dan saya tidak dapat menemukan dokumentasi, tetapi secara intuitif saya pikir itu akan seperti ini:

// a.json
{"rules": {"foo": [true, 1]}}

// b.json
{"rules": {"foo": [true, 2]}}

// c.json
{
  "extends": ["a.json", "b.json"],
  "rules": {"foo": [true, 3]}
}

akan menghasilkan aturan "foo" memiliki argumen 3. Jika aturan itu tidak ada di c.json , maka "foo" harus memiliki nilai 2, karena urutan larik "extends".

Untuk penggantian, saya berharap urutan yang sama diterapkan. Masuk akal bagi saya untuk menggunakan penggantian terakhir yang cocok dengan regex yang disediakan, dengan mempertimbangkan urutan aturan 'memperluas'. Contoh file tunggal:

{
  "rules": {"a": [true, 1]},
  "override": [
    {"match": "test|spec", "rules": {"a": [true, 2]}},
    {"match": "test", "rules": {"a": [true, 3]}}
  ]
}

akan memiliki nilai 2 untuk aturan "foo" ketika jalur file berisi "spec", 3 jika berisi "test", dan 1 sebaliknya. (jelas, bukan satu set override yang sangat berguna, karena "test" mungkin juga dihilangkan dari yang pertama, tetapi Anda mendapatkan idenya)

Apakah itu masuk akal dan menjawab pertanyaan Anda?

@calebegg Ada beberapa kasus tepi lain yang perlu dipertimbangkan:

// a.json
{
  "rules": {"foo": [true, 1]},
  "override": {"match": "test|spec", "rules": {"foo": [true, 2]}}
}

// b.json
{
  "extends": "./a.json"
  "rules": {"foo": false}
}

Apa hasil yang diharapkan?

  • 2 karena pesanannya a.json/rules -> b.json/rules -> a.json/override
  • false karena pesanannya a.json/rules -> a.json/override -> b.json/rules

Sama di sini, apa hasil yang diharapkan:

// c.json
{
  "rules": {"foo": [true, 1]},
  "override": {"match": "test|spec", "rules": {"foo": false}}
}

// d.json
{
  "extends": "./a.json"
  "rules": {"foo": {"options": 2}},
  "override": {"match": "test|spec", "rules": {"foo": {"options": 3}}}
}

Hanya pemikiran acak: Mengapa tidak mencocokkan pola secara berurutan dan (sebagian) menimpa kecocokan sebelumnya:

{
  "rules": { // same as "*"
    "rule-one": true,
    "rule-two": true
  },
  "*.js?(x)": { // we could get rid of "jsRules" with this
    "rule-two": false
  },
  "*.{t,j}sx": {
    "jsx-rule": true
  },
  "*.spec.*" {
    "rule-one": false
  }
}

Beberapa contoh:

  • foo.ts : aturan-satu, aturan-dua
  • foo.tsx : aturan-satu, aturan-dua, jsx-rule
  • foo.js : aturan pertama
  • foo.jsx : aturan-satu, jsx-rule
  • foo.spec.tsx : aturan-dua, jsx-rule
  • foo.spec.js : tidak ada

Saya hanya tidak tahu di mana harus meletakkan ini di dalam konfigurasi. Level yang sama dengan "rules" mempermudah penulisan, tetapi dapat membingungkan pengguna, karena levelnya sama dengan "extends" , "rulesDirectory" , ...

Masalah lain adalah memperluas konfigurasi. Jika kita menerapkan semua override dari konfigurasi dasar dan kemudian menimpa dari konfigurasi saat ini, agak sulit untuk dipahami.

Itu juga membuat kode lebih kompleks. Saat ini konfigurasi digabungkan selama penguraian. Dengan proposal ini, konfigurasi terakhir hanya diketahui ketika kita memiliki nama file.

Halo,

Fitur ini akan sangat bagus. Saya pikir Eslint mendukung fitur ini: https://eslint.org/docs/user-guide/configuring#configuration -based-on-glob-patterns. Jadi, sintaks dan semantik bisa sama, untuk menghindari kebingungan.

@minomikula Terima kasih banyak. Saya mencari dokumen ESLint sebelumnya tetapi tidak menemukan bagian ini.

Pendekatan mereka masuk akal. Untuk meringkas:

  • "overrides" bagian dalam konfigurasi berisi array override
  • sebuah override dapat menentukan beberapa pola glob ( "files" ). jika salah satunya cocok, konfigurasinya berlaku
  • anda dapat mengecualikan file dengan pola glob: "excludedFiles"
  • pola glob relatif terhadap file konfigurasi yang ditentukan di
  • pola glob selalu harus cocok dengan seluruh jalur, bukan hanya nama dasarnya
  • penggantian diproses secara berurutan, menimpa yang sebelumnya
  • saat memperluas file konfigurasi, konfigurasi dasar dievaluasi sepenuhnya sebelum melanjutkan ke konfigurasi perluasan

    • base.json/rules

    • base.json/override

    • memperluas.json/rules

    • extend.json/override

Ada beberapa hal yang perlu dipertimbangkan saat mem-porting perilaku ini ke TSLint:

  • kita pasti harus menonaktifkan extends dan linterOptions dalam penggantian
  • kami mungkin juga ingin melarang rulesDirectory
  • apakah kita ingin mengizinkan rules dan jsRules di override atau apakah kita mencela jsRules demi **/*.js?(x) override?

Pikiran atau komentar @adidahiya @calebegg @alexeagle @minomikula?

Oh, wow, ya, pendekatan itu tampaknya masuk akal bagi saya. Saya juga harus mencari prior art.

Ini akan menjadi tambahan yang luar biasa! Pendekatan eslint berfungsi dengan baik saat menonaktifkan beberapa aturan dalam file uji secara kondisional.

@calebegg apakah Anda masih berencana untuk mendorong ini ke depan ketika Anda punya waktu?

Ya, saya pasti ingin mengerjakan ini. @ajafff Apakah Anda biasanya senang memulai dengan pendekatan ESLint dan mengulangi dalam PR? Atau apakah menurut Anda ada pertanyaan desain yang harus kita bicarakan terlebih dahulu?

apakah kita ingin mengizinkan aturan dan jsRules di override atau apakah kita tidak menggunakan jsRules untuk mengganti */ .js?(x)?

Masuk akal bagi saya untuk mencela, tetapi saya juga tidak merasa sangat kuat.

@calebegg Saya baik-baik saja dengan pendekatan ESLint. Saya menerapkan konsep yang sangat mirip di runtime linter POC saya https://github.com/fimbullinter/wotan/tree/master/packages/wotan#overrides

Integrasi dalam API TSLint saat ini mungkin sulit, karena saat ini ia menggabungkan semua konfigurasi saat penguraian. Ini perlu ditunda sampai nama file diketahui dan perlu dilakukan untuk setiap file.

Ini tentu saja merupakan perubahan API yang melanggar.

@calebegg @mitchlloyd @ajafff @alexeagle saya melihat sedikit manfaat dalam fitur ini daripada hanya bersarang file tslint.json untuk menimpa konfigurasi luar. fitur itu sudah berfungsi hari ini dan tidak memerlukan jeda API yang rumit. apakah Anda akan tersinggung jika kami menolak permintaan ini?

Bersarang tidak menyelesaikan masalah yang dibahas di sini. Banyak orang melakukan ingin tes mereka di struktur direktori yang sama seperti kode itu tes, dan ada cara sederhana tidak baik untuk melakukan itu dengan tslint sekarang.

Ada banyak proyek yang menempatkan file spesifikasi di direktori yang sama dengan sumber. Ini telah menjadi praktik terbaik di banyak lingkungan, Angular CLI menghasilkan struktur proyek seperti itu dll. Saya tidak berpikir itu realistis bersarang file konfigurasi tslint akan bekerja untuk semua orang ini.

Saya setuju bahwa struktur proyek saya tidak boleh didikte oleh alat linting. Sebaliknya alat linting harus mendukung pola umum yang ada. Tes kolokasi dan file sumber adalah pola umum.

@giladgray Perubahan yang diminta mendukung skenario di mana pengguna meletakkan file pengujian dan produksi mereka di samping satu sama lain seperti ini:

some-dir/
  my-component.ts
  my-component.test.ts

Bagaimana "bersarang file tslint.json " menangani kasus penggunaan ini ketika kita menginginkan aturan yang berbeda untuk my-component.ts dan my-component.test.ts ?

Panduan sudut

@ohjames Mari tetap pada topik dan hindari membelok ke arah serangan pribadi, oke? Menyarankan bahwa seseorang tidak cocok untuk mempertahankan proyek mereka sendiri bukanlah cara untuk mempengaruhi OSS, dan tentu saja tidak akan membantu apa yang kita semua perdebatkan di sini.

Masuk akal untuk menginginkan penggantian untuk file yang tidak sesuai dengan struktur bersarang seperti yang disebutkan di atas. Sepertinya saya komentar @giladgray dimaksudkan untuk menentukan apakah masih ada minat masyarakat yang signifikan dalam perubahan ini, mengingat tidak ada aktivitas tentang masalah ini selama lebih dari 6 bulan. Ini secara khusus dibuktikan dengan komentarnya pada PR terbuka (#3708):

jika Anda ingin mengejar ini, harap perbarui cabang ini agar kami dapat meninjaunya, atau tutup jika tidak relevan lagi. kami akan menutup ini jika kami tidak mendengar kabar dari Anda dalam dua minggu.

@ohjames Saya sarankan Anda mempertimbangkan kembali komentar Anda - seperti yang disebutkan @DanielSchaffer , serangan pribadi tidak akan membantu Anda di sini, atau di mana pun dalam perangkat lunak sumber terbuka. Setiap orang mencoba yang terbaik untuk membuat perangkat lunak yang baik, andal, dan kaya fitur, dan menyerang orang sama sekali tidak berkontribusi pada hal itu.

Apakah ada pembaruan tentang topik ini?
Ide yang diajukan oleh @ajafff dalam komentar rangkumannya tampaknya masuk akal dan memenuhi berbagai kebutuhan. Menggunakan semantik yang sama dengan eslint adalah cara yang baik.

Seperti yang telah saya komentari pada #1063 terkait, kasus penggunaan saya adalah menggunakan tslint-microsoft-contrib saat ini mengebom komponen file tunggal Vue untuk beberapa aturan. Ini mungkin masalah Vue, atau masalah TSLint, dan tim-tim tersebut mungkin atau mungkin tidak berhasil memperbaiki masalah tertentu - menonaktifkan aturan yang melanggar sampai itu terjadi sepertinya solusi sederhana yang tidak terlalu rumit. Dibandingkan dengan harus menambahkan direktif penonaktifan yang sama ke setiap file .vue, dan memperbaruinya di semua tempat tersebut saat aturan mendukung perubahan. Juga tidak masuk akal untuk membagi proyek menjadi file .vue dan .ts, itu akan menjadi struktur yang sangat canggung.

Saya mendukung fitur ini masuk. Mungkin kita juga dapat menyelesaikan permintaan tslintignore di #73 dengan bersih dengan mengizinkan beberapa penggantian untuk sepenuhnya menonaktifkan semua aturan?

{
    "files": "./src/test-data/*.ts",
    "reset": true // Resets tslint.json to {}
}

tslint-microsoft-contrib saat ini mengebom komponen file tunggal Vue untuk beberapa aturan

Oh @millimoose bisakah Anda mengajukan masalah di tslint-microsoft-contrib?

@JoshuaKGoldberg - Saya sudah melakukan laporan terperinci tentang bug itu di @vuejs/vue-cli yang tampaknya paling tepat. (Ini ditandai sebagai "menunggu reproduksi" jadi saya kira itu tidak terlalu keluar dari tempatnya.) Saya hanya menyebutkannya sebagai motivator untuk berpadu di sini. Ini adalah jenis hal yang dapat dan akan muncul dalam ekosistem yang berkembang, yang seharusnya menjadi argumen untuk alat yang cukup fleksibel untuk mengatasi rintangan tanpa benar-benar menulis peretasan di sekitar bug orang lain.

Setiap pembaruan tentang masalah ini?

Masalah ini saat ini ditandai sebagai 'Memerlukan proposal', tetapi saya rasa kami sudah mengajukan proposal di https://github.com/palantir/tslint/issues/3447#issuecomment -344020834?

Proposal @RoystonS @ajafff menyebutkan beberapa ujung longgar yang harus ditangani:

Ada beberapa hal yang perlu dipertimbangkan saat mem-porting perilaku ini ke TSLint:

  • kita pasti harus menonaktifkan extends dan linterOptions dalam penggantian
  • kami mungkin juga ingin melarang rulesDirectory
  • apakah kita ingin mengizinkan rules dan jsRules di override atau apakah kita mencela jsRules demi **/*.js?(x) override?

Juga harus ada konsensus dari orang-orang di palantirtech org sebelum melanjutkan, karena ini adalah fitur yang cukup substansial.

Baru saja menemukan ini sendiri, dan hanya ingin menyuarakan minat saya untuk fitur semacam ini.

Kami akhirnya melonggarkan beberapa aturan linting yang memengaruhi kode produksi dan mari kita lihat bagaimana kelanjutannya. ):

Saya ingin melihat fitur ini

berlangganan - Juga membutuhkan ini.

aku sangat membutuhkan ini :(

Sama disini! Kami menggunakan TypeScript dengan Vuejs dan file pengujian unit kami tidak bersama dalam direktori tes tetapi di mana-mana di sepanjang kode sumber komponen.

Akan senang melihat fitur ini, saat ini kami menggunakan pengaturan yang sedikit miring yang menghasilkan vscode menyoroti kesalahan linting yang berbeda dari apa yang kami soroti lint baris perintah untuk mengatasi masalah ini.

Saya sangat ragu fitur ini akan pernah diterapkan, tslint tampaknya tidak dipelihara secara aktif secara umum. Saya sarankan beralih ke @typescript-eslint , itu mendapat dukungan penuh dari proyek eslint dan ts dan migrasi lebih mudah dari sebelumnya dengan @typescript-eslint/eslint-plugin-tslint . Dan ada tabel compat dengan tslint dan aturan eslint yang sesuai / alternatif lain yang tersedia. Pengaturan Eslint sangat dapat disesuaikan, jadi saya tidak melihat ada gunanya tetap menggunakan tslint.

Saya mengusulkan untuk menerapkan konsep yang digunakan repositori git untuk file di .gitIgnore... ke aturan tsLint. Penggunaan posisi hierarki Anda saat ini sebagai konteks linter, bersama dengan file penimpaan, saat linting subdirektori tertentu. Kemudian Anda dapat memasukkan atau mengecualikan, mengatur konfigurasi apa pun di tingkat direktori mana pun yang Anda inginkan.

misalnya
Konfigurasi tslint ditempatkan di root, dan pada tingkat tertentu dalam struktur kode sumber Anda, Anda ingin perilaku yang berbeda, cukup timpa dengan file tslint ekstensi di root subdirektori itu.

@redevill Itu membantu orang menulis tes di folder test . Tetapi tidak satu pun tes penulisan sebagai something.test.ts di folder yang sama dari komponen/layanan.

Setuju - tetapi dengan sedikit perubahan: (Yang dapat diotomatiskan dengan generator templat (Gaya CLI)
KomponenSayaDir
---MyComponentTestsDir
------tslint.test.json
------sesuatu.test.ts
---komponenku.komponen.css
---komponensaya.komponen.html
---komponenku.komponen.ts

Idenya masih bisa bekerja.

Penggemar berat proposal ini. YA SILAHKAN! Preferensi saya adalah konsep Overrides.

Btw, mengingat pengumuman penghentian tslint, saya tidak bisa _benar-benar_ membayangkan bahwa perubahan sebesar itu akan dilakukan pada tahap ini, dan tim saya pindah ke eslint, yang sudah memiliki fasilitas per-rule + per-file override.

@RoystonS pada dasarnya benar, fitur sebesar itu tidak akan ditambahkan ke tslint pada saat ini. lihat #4534

Kami menggunakan proyek Angular. Kita membutuhkan konsep override. Kalau tidak, itu menyakitkan untuk dikelola

Apakah halaman ini membantu?
0 / 5 - 0 peringkat