Typescript: tsc seharusnya tidak peduli dan gagal dengan file ts di luar rootDir

Dibuat pada 21 Jul 2016  ·  87Komentar  ·  Sumber: microsoft/TypeScript

TypeScript: 2.0.0

Saya memiliki folder fixtures yang berisi file .ts . Di tsconfig.json saya, saya menetapkan rootDir ke src yang berisi semua kode sumber saya (termasuk tes).

File perlengkapan ada untuk kasus uji. tsc seharusnya tidak mengeluhkan keberadaan mereka dan gagal dalam kompilasi.

Working as Intended

Komentar yang paling membantu

Bleh, ini benar-benar berfungsi sebagaimana dimaksud? Saya baru saja mengalami ini, saya memberi tahu TypeScript bahwa semua sumber saya ada di folder tertentu (melalui rootDir ) dan kemudian melanjutkan ke _benar-benar mengabaikan apa yang saya katakan_ karena saya kebetulan memiliki satu file dengan .ts Ekstensi

Ini benar-benar terasa seperti kesalahan, jika saya memberi tahu kompiler di mana sumber saya melalui rootDir , seharusnya tidak sepenuhnya mengabaikan pengaturan itu dan mengubah struktur folder keluaran saya karena dianggap mungkin saya melakukan sesuatu yang salah. Seharusnya mengabaikan file apa pun yang tidak ada di rootDir . Atau, itu akan gagal, tidak terus memancarkan output yang tidak selaras dengan struktur folder output yang saya inginkan sama sekali!


Bagi siapa pun yang mengejar saya, berikut ini akan melakukan apa yang Anda _sebenarnya_ inginkan:

{
    "compilerOptions": {
        "outDir": "./output",
        "rootDir": "./source",
    },
    "include": [
        "source"
    ]
}

Semua 87 komentar

Untuk menyiasatinya, saya menambahkan "kecualikan" kembali ke tsconfig.json

rootDir digunakan untuk membangun struktur folder keluaran. semua file harus berada di bawah rootDir agar kompiler mengetahui di mana harus menulis output. tanpa batasan ini, jika ada file yang tidak berada di bawah rootDir, kompilator memiliki dua opsi 1. apakah mereka akan dipancarkan di tempat yang sama sekali tidak terduga, atau 2. tidak dipancarkan sama sekali. saya akan mengatakan pesan kesalahan jauh lebih baik daripada kegagalan diam.

@mhegazy Terima kasih atas klarifikasinya. Dengan nama rootDir Saya menganggapnya sebagai direktori root dari kode sumber, seperti baseURL untuk browser. Tidak tahu itu hanya untuk struktur folder keluaran.

Ini tsconfig.json saya:

{
    "compilerOptions": {
        "target": "es5",
        "module": "commonjs",
        "moduleResolution": "node",
        "sourceMap": true,
        "emitDecoratorMetadata": true,
        "experimentalDecorators": true,
        "removeComments": true,
        "noImplicitAny": true,
        "rootDir": "src",
        "outDir": "build"
    },
    "exclude": [
        ".idea",
        "build",
        "node_modules",
        "typings/globals",
        "typings/modules"
    ]
}

Struktur folder saya terlihat seperti ini:

  • proyek

    • membangun

    • node_modules (symlink ke ../node_modules)

    • simpul_modul

    • src

Saya ingin file .ts saya di folder src dikompilasi dan dikeluarkan dengan struktur folder yang sama ke folder build. Saya melakukan ini agar saya dapat mengatur root dokumen saya ke folder build dan menjauhkan src saya dari root doc. Saya mendapatkan pesan kesalahan tentang file .ts di folder node_modules, pesan kesalahan yang sama dengan OP. Catatan di atas, saya mengecualikan node_modules. Mengapa tsc mengeluh tentang itu?

@HillTravis masalah Anda tampaknya sama dengan https://github.com/Microsoft/TypeScript/issues/9552.

@mhegazy Saya tidak yakin itu sama. Ya, struktur saya menyertakan symlink, tetapi di mana pun symlink itu ada harus diabaikan.

Di #9552, tidak ada folder src, artinya folder node_modules ada di jalur yang sedang dibangun. Dalam skenario saya, direktori root yang harus dilihat tsc adalah src, yang tidak mengandung node_modules. Jadi seharusnya tidak melihat folder itu sama sekali. Selain itu, saya memiliki folder node_modules yang secara eksplisit dikecualikan melalui tsconfig.json saya. Jadi itu harus diabaikan dua kali lipat. Saya juga mengecualikan folder build , dan itu harus mencakup symlink ke node_modules di dalamnya.

Juga, di #9552, tidak disebutkan pesan kesalahan atau kompilasi yang gagal.

Saya juga harus menyebutkan bahwa saya menggunakan TypeScript 1.8.10.

Secara khusus, pesan kesalahan berbunyi:

kesalahan TS6059: File '/Users/thill/Projects/nrc/client/node_modules/ng2-datetime/src/ng2-datetime/ng2-datetime.module.ts' tidak berada di bawah 'rootDir' '/Users/thill/Projects/ nrc/klien/src'. 'rootDir' diharapkan berisi semua file sumber.

kesalahan TS6059: File '/Users/thill/Projects/nrc/client/node_modules/ng2-datetime/src/ng2-datetime/ng2-datetime.ts' tidak berada di bawah 'rootDir' '/Users/thill/Projects/nrc/ klien/src'. 'rootDir' diharapkan berisi semua file sumber.

kesalahan TS6059: File '/Users/thill/Projects/nrc/client/node_modules/ng2-datetime/src/ng2-datetime/timepicker-event-interface.ts' tidak berada di bawah 'rootDir' '/Users/thill/Projects/ nrc/klien/src'. 'rootDir' diharapkan berisi semua file sumber.

@HillTravis Anda dapat mempercayai saya dalam hal ini :) penanganan symlink kami yang tidak konsisten yang membuat kompiler tidak aktif. kami mengikuti symlink hanya untuk resolusi modul node, lalu gunakan nama itu sebagai nama file; kemudian kami melakukan pemeriksaan untuk memastikan semua file berada di bawah direktori sumber menggunakan jalur nyata, bukan jalur yang ditentukan pengguna. dan itulah yang menghasilkan kesalahan.

Sebagai ujian, saya mencoba menghapus symlink. Sebenarnya, saya menghapus seluruh folder build . Kemudian saya menjalankan tsc lagi, dan masih melihat kesalahan.

Selama pengujian lebih lanjut, saya mencoba mengomentari impor kode dan penggunaan modul simpul tertentu (ng2-datetime) dan kesalahannya hilang. Jadi hanya ketika saya mencoba mengimpor modul simpul itu saya melihat kesalahan, terlepas dari symlink.

Jika Anda melihat sumber untuk paket itu di GitHub, Anda akan melihat bahwa file package.json memiliki parameter "main" yang disetel ke "ng2-datetime.js", meskipun penulis juga menerbitkan file .ts dengan parameter yang sama. nama. Ini tampaknya menyebabkan masalah. Jika saya membuat file .d.ts dan menghapus file .ts, masalahnya akan hilang. Itu dikompilasi tanpa masalah bahkan setelah menambahkan symlink kembali.

Jadi dengan segala hormat, saya tidak melihat bagaimana masalah ini dapat dikaitkan dengan symlink secara khusus. Tampaknya hanya menyebabkan masalah ketika penulis menyertakan file .ts dalam paket.

Apakah Anda tahu jika ada solusi untuk ini? OP di atas mengatakan cara mengatasinya dengan menambahkan "kecualikan" kembali ke tsconfig.json. Saya sudah mengecualikan direktori, tetapi masih mencoba mengompilasinya.

Apakah Anda tahu jika ada solusi untuk ini? OP di atas mengatakan cara mengatasinya dengan menambahkan "kecualikan" kembali ke tsconfig.json. Saya sudah mengecualikan direktori, tetapi masih mencoba mengompilasinya.

Ini mungkin terkait dengan yang lain, tetapi saya tidak dapat menemukannya sekarang. Saat menyelesaikan suatu jenis, tsc selalu mencoba mencarinya dari node_modules , sementara itu tidak ada (terkait dengan typings ).

"tsc seharusnya tidak peduli dan gagal dengan file ts di luar rootDir" Saya setuju.

Saya tidak mengerti mengapa TypeScript akan melihat file JS di luar rootDir, karena di situlah semua sumber seharusnya.
Pesan kesalahan mengatakan "'rootDir' diharapkan berisi semua file sumber", maka apa pun di luar direktori itu tidak boleh diharapkan atau dianggap sebagai file sumber, sejauh menyangkut TS!

Jika ini adalah "Bekerja seperti yang Diinginkan", lalu apa sebenarnya maksud atau motivasi dari perilaku ini? Apakah ada kasus di mana TS ingin mengkompilasi file sumber yang terletak di luar rootDir?

Di sisi lain, menambahkan bagian "sertakan" di tsconfig memecahkan masalah. Ketika diberikan file atau direktori untuk disertakan, TS tidak akan melihat file lain di luar itu.

dengan TypeScript 1.8.10

Saya memiliki folder node_modules di homedir saya ~/node_modules . Menjalankan tsc dari direktori proyek saya ~/projects/myProject/ menyebabkan TypeScript mengeluh tentang file-file berikut

../../node_modules/aws-sdk/index.d.ts(7,1): error TS1128: Declaration or statement expected.
../../node_modules/aws-sdk/index.d.ts(7,11): error TS1005: ';' expected.
../../node_modules/aws-sdk/index.d.ts(7,24): error TS1005: '{' expected.
../../node_modules/aws-sdk/lib/config.d.ts(1,1): error TS1084: Invalid 'reference' directive syntax.
../../node_modules/aws-sdk/lib/config.d.ts(29,84): error TS1110: Type expected.
../../node_modules/aws-sdk/lib/config.d.ts(36,62): error TS1110: Type expected.
../../node_modules/aws-sdk/lib/config.d.ts(68,133): error TS1110: Type expected.
../../node_modules/aws-sdk/lib/config.d.ts(75,111): error TS1110: Type expected.
../../node_modules/aws-sdk/lib/request.d.ts(1,1): error TS1084: Invalid 'reference' directive syntax.
../../node_modules/aws-sdk/lib/services/glacier.d.ts(1,1): error TS1084: Invalid 'reference' directive syntax.

sangat membingungkan - meskipun tidak yakin mengapa saya memiliki folder modul simpul di direktori rumah saya untuk memulai.

@iwllyu dapatkah Anda memeriksa proyek Anda di [email protected] dan mengajukan masalah baru jika Anda masih mengalami masalah.

Masih memiliki masalah dengan 2.1.4 meskipun mengeluh tentang kumpulan file yang berbeda

Using tsc v1.8.10
../../node_modules/aws-sdk/index.d.ts(7,1): error TS1128: Declaration or statement expected.
../../node_modules/aws-sdk/index.d.ts(7,11): error TS1005: ';' expected.
../../node_modules/aws-sdk/index.d.ts(7,24): error TS1005: '{' expected.
../../node_modules/aws-sdk/lib/config.d.ts(27,84): error TS1110: Type expected.
../../node_modules/aws-sdk/lib/config.d.ts(34,62): error TS1110: Type expected.
../../node_modules/aws-sdk/lib/config.d.ts(66,133): error TS1110: Type expected.
../../node_modules/aws-sdk/lib/config.d.ts(73,111): error TS1110: Type expected.
Using tsc v2.1.4
../../node_modules/aws-sdk/lib/config.d.ts(38,37): error TS2304: Cannot find name 'Promise'.
../../node_modules/aws-sdk/lib/request.d.ts(164,16): error TS2304: Cannot find name 'Promise'.
../../node_modules/aws-sdk/lib/s3/managed_upload.d.ts(15,16): error TS2304: Cannot find name 'Promise'.

Saya akan membuat proyek untuk mengisolasi kasus uji

Yah saya mencoba dengan proyek baru dan itu tidak terjadi. Karena ini adalah proyek yang lebih lama dan saya sudah memperbaikinya dengan menghapus folder node_modules tambahan, saya tidak akan menghabiskan waktu lagi untuk mencoba membuatnya kembali. Terima kasih untuk bantuannya!

Tentang kasus ini. Jika semua yang Anda impor adalah tipe (seperti saya benar-benar berselancar di gelombang "ketik depan, skrip belakang" ini) dari luar - mungkin tsc dapat membedakan apa yang saya lakukan?
Saya hanya membagikan jenis entitas saya dari backend - ke aplikasi frontend saya. Output tentu saja tanpa jenis dan impor kelas-kelas tersebut (karena mereka hanya digunakan untuk waktu kompilasi dan intellisense).

Punya ini juga.
TypeScript terlalu membatasi untuk tim kami - mempertimbangkan aliran sekarang.

guys, ada resolusi tentang ini sekarang? menggunakan jenis dari kode klien di dalam kode backend dan sebaliknya.

apa pilihan terbaik? salin-tempel di sana-sini dan ubah jika saya mengubah jenis?

membuat satu direktori root untuk 2 proyek bukanlah suatu pilihan, karena mengapa backend tsconfig.json akan memiliki info tentang jsx dan kompilasi menjadi commonjs ketika saya dapat menggunakan es2015

Apakah baseUrl bekerja untuk Anda?

@unional tidak akan mengubah baseUrl merusak semua impor node_modules - tidak perlu menulis

import * as request from "superagent";

tetapi

import * as request from "node_modules/superagent/..something";

?

Bleh, ini benar-benar berfungsi sebagaimana dimaksud? Saya baru saja mengalami ini, saya memberi tahu TypeScript bahwa semua sumber saya ada di folder tertentu (melalui rootDir ) dan kemudian melanjutkan ke _benar-benar mengabaikan apa yang saya katakan_ karena saya kebetulan memiliki satu file dengan .ts Ekstensi

Ini benar-benar terasa seperti kesalahan, jika saya memberi tahu kompiler di mana sumber saya melalui rootDir , seharusnya tidak sepenuhnya mengabaikan pengaturan itu dan mengubah struktur folder keluaran saya karena dianggap mungkin saya melakukan sesuatu yang salah. Seharusnya mengabaikan file apa pun yang tidak ada di rootDir . Atau, itu akan gagal, tidak terus memancarkan output yang tidak selaras dengan struktur folder output yang saya inginkan sama sekali!


Bagi siapa pun yang mengejar saya, berikut ini akan melakukan apa yang Anda _sebenarnya_ inginkan:

{
    "compilerOptions": {
        "outDir": "./output",
        "rootDir": "./source",
    },
    "include": [
        "source"
    ]
}

Saya memberi tahu TypeScript bahwa semua sumber saya ada di folder tertentu (melalui rootDir)

Ini bukan maksud rootDir ! rootDir berarti "Gunakan folder ini sebagai basis relatif untuk menghitung jalur di outDir ". File mana yang merupakan bagian dari kompilasi Anda adalah pertanyaan terpisah yang dijawab oleh files dan/atau include / exclude

Bahkan jika saya menerimanya, perilaku saat ini masih dalam kesalahan IMO. Jika saya memiliki file TS di luar direktori yang ditentukan maka rootDir akan _not_ menjadi dasar untuk menghitung jalur di outDir , artinya konfigurasi yang saya tentukan akan diabaikan sepenuhnya.

Saya pikir kegagalan keras akan jauh lebih baik karena kompiler secara efektif mengira saya telah memberikan konfigurasi yang tidak valid. Mengabaikan konfigurasi ketika tidak valid adalah (IMO) bukan cara yang tepat untuk menangani kelas kegagalan ini.

Contoh pesan kesalahan yang akan jauh lebih jelas (bersama dengan kegagalan keras):

TSC menemukan file TypeScript di luar rootDir dan karena itu tidak dapat melanjutkan kompilasi. Ubah rootDir untuk menyertakan semua file TypeScript, atau mengecualikan file di luar rootDir, atau hanya menyertakan file di dalam rootDir.

Catatan: Sebagian besar alasan mengapa perilaku rootDir saat ini terasa sangat salah justru karena tidak masuk akal untuk memiliki file di luar rootDir. Ketika seseorang bertanya pada diri sendiri (atau kompiler) apa artinya mengkompilasi file di luar rootDir , satu-satunya jawaban adalah "tidak masuk akal". Oleh karena itu orang sampai pada kesimpulan alami bahwa rootDir menentukan sourceDir juga.

Kejahatan ada dalam penamaan. Ini benar-benar berarti relativePathBaseDir atau sesuatu seperti itu.

Saya juga memperhatikan bahwa include biasanya berarti "lihat di sini juga" tetapi dalam hal ini berarti "hanya lihat di sini".
Saya akan masuk akal jika memiliki nama lain dan wajib.

IMO komentar ini harus dipertimbangkan secara khusus untuk mengonfirmasi bahwa ini memang bug dan harus dibuka kembali seperti itu:

Catatan: Sebagian besar alasan mengapa perilaku rootDir saat ini terasa sangat salah justru karena tidak masuk akal untuk memiliki file di luar rootDir. Ketika seseorang bertanya pada diri sendiri (atau kompiler) apa artinya mengkompilasi file di luar rootDir , satu-satunya jawaban adalah "tidak masuk akal".

Memang, itu tidak masuk akal . "File sumber di luar rootDir " sama sekali bukan file sumber , tidak peduli ekstensi file atau kontennya. Kompiler tidak akan pernah mengompilasinya. Jadi mengapa dia mengeluh tentang keberadaan mereka? Apakah dia cemburu bahwa ada file yang tidak berada di bawah kekuasaannya?

+100 ini adalah bug (yang sebenarnya buruk). Pertimbangkan struktur direktori berikut:

- src/
  - module.ts
- test/
  - module.test.ts
- out/
  - module.js

Saya ingin tsc untuk mengkompilasi hanya src , karena saya menjalankan tes dengan ts-node . Memiliki rootDir: 'src' akan menyebabkan kesalahan kompilasi saat ini. Jika Anda menandai tes dan hal-hal lain yang hanya ingin Anda jalankan dengan ts-node (atau bahkan mungkin dikompilasi secara terpisah?) sebagai "dikecualikan", maka hal-hal buruk mulai terjadi (misalnya penyorotan vscode menjadi rusak dalam tes )

Faktanya, tidak ada kombinasi dari rootDir , excluded dan semua opsi lain yang memenuhi semua persyaratan (tidak termasuk tes dari kompilasi saat masih dapat menjalankannya dan bekerja dengannya).

Dan saya rasa use case saya tidak unik, jadi ada baiknya mempertimbangkan kembali label "bekerja sebagaimana dimaksud" setidaknya dari sudut pandang UX.

Pengaturan src / test / out adalah skenario utama yang ditangani oleh referensi proyek

Saya menemukan masalah ini karena saya googling mengapa TypeScript mencoba mengkompilasi file webpack.config.js saya setelah saya menetapkan rootDir .

Saya memberi tahu TypeScript bahwa semua sumber saya ada di folder tertentu (melalui rootDir)

Ini bukan maksud rootDir! rootDir berarti "Gunakan folder ini sebagai basis relatif untuk menghitung jalur di outDir". File mana yang merupakan bagian dari kompilasi Anda adalah pertanyaan terpisah yang dijawab oleh file dan/atau sertakan/kecualikan

Ini adalah jawabannya! Dokumen untuk rootDir mengatakan

Menentukan direktori root dari file input

Yang saya maksud adalah "masukkan file _source_". Saya merekomendasikan agar komentar @RyanCavanaugh menggantikan penjelasan saat ini untuk opsi ini.

Menautkan di sini - https://github.com/Microsoft/TypeScript/issues/11299 adalah duplikat dari masalah ini. (Solusi: gunakan include/exclude untuk menentukan file yang akan dikompilasi, rootDir TIDAK menentukan file mana yang akan dikompilasi.)

@mhegazy Maukah Anda menambahkan komentar di utas itu untuk efek ini? Tampaknya itulah yang dimaksud penanya (bingung tentang mengapa TS melihat file apa pun di luar RootDir, kesalahpahaman yang sama tentang apa arti rootDir).

Saya juga menghadapi masalah ini dan tidak dapat menyelesaikannya.

kompilasi tsc berjalan keluar dari direktori saya yang disertakan dan masuk ke folder induk, menyebabkan kesalahan tipe duplikat.

Saya memiliki struktur folder bersarang yang terlihat seperti ini:

└─src
└─package.json
└─node_modules
└─tsconfig.json
└─example
│ └─src
│ └─package.json
│ └─node_modules
│ └─tsconfig.json

Sekarang ketika saya mencoba dan menjalankan tsc dari dalam direktori contoh, saya mendapatkan kesalahan berikut:

node_modules/@types/react/index.d.ts:2809:14 - error TS2300: Duplicate identifier 'LibraryManagedAttributes'.

2809         type LibraryManagedAttributes<C, P> = C extends React.MemoExoticComponent<infer T> | React.LazyExoticComponent<infer T>
                  ~~~~~~~~~~~~~~~~~~~~~~~~

  ../node_modules/@types/react/index.d.ts:2814:14
    2814         type LibraryManagedAttributes<C, P> = C extends React.MemoExoticComponent<infer T> | React.LazyExoticComponent<infer T>
                      ~~~~~~~~~~~~~~~~~~~~~~~~
    'LibraryManagedAttributes' was also declared here.

Seperti yang Anda lihat dari kesalahan, tsc berjalan di atas pohon dan keluar dari folder contoh, dan mencari di folder node_modules dari direktori induk! Yang terasa lebih buruk adalah saya telah mencoba secara eksplisit mengabaikan direktori node_modules induk dengan sedikit efek.

Berikut adalah tsconfig dari direktori contoh:

{
  "compilerOptions": {
    "target": "es5",
    "experimentalDecorators": true,
    "module": "commonjs",
    "sourceMap": true,
    "outDir": "./dist",
    "rootDir": "./src",
    "strict": true,
    "moduleResolution": "node",
    "lib": ["es2017", "dom"],
    "jsx": "react"
  }
,
  "typeRoots": [
    "./node_modules/@types"
  ],
  "include": [
    "src"
  ],
  "exclude": [
    "node_modules",
    "../node_modules"
  ]
}

Bagaimana saya bisa menyelesaikan masalah ini? Tidak satu pun dari hal di atas yang berhasil untuk saya

@lexwebb Saya memiliki masalah yang sama, periksa file yarn.lock bahwa @types/react memiliki versi yang sama.
Lihat https://stackoverflow.com/questions/52399839/typescript-duplicate-identifier-librarymanagedattributes.

Saya mendarat di sini karena folder aset saya berisi file video "MPEG Transport Stream" dengan ekstensi .ts sehingga membuat tsc crash meskipun folder itu tidak ada di jalur rootDir saya

Saya memperbaikinya dengan menambahkan folder aset di jalur exclude tetapi itu adalah perilaku yang mengganggu

Jadi ternyata saya memiliki versi reaksi yang sedikit berbeda di paket induk dan anak json. Mencocokkan versi persis menghapus masalah. Masih menyebalkan bahwa Anda tidak dapat mengecualikan pemeriksaan jenis formulir direktori induk.

Saya kira ini tidak akan pernah diperbaiki. Baru saja mengalami masalah yang sama. Bagaimana ini "bekerja sebagaimana dimaksud" berada di luar jangkauan saya. Saya kira tujuannya adalah untuk membuat kompiler berjalan dengan cara yang tidak masuk akal.

Dari pengalaman pribadi saya sendiri, alasan pembuatan TypeScript keluar dari pohon rootDir dan mencoba membangun hal-hal yang tidak Anda harapkan adalah kenyataan bahwa Anda (sengaja atau tidak sengaja) secara langsung atau tidak langsung mereferensikan sesuatu di dalamnya area dari dalam rootDir . Jika Anda melakukannya maka build akan mengikuti pohon referensi terlepas dari apakah Anda telah mencoba mengecualikan area yang berisi file yang direferensikan atau tidak. Kadang-kadang bisa menjadi PITA yang mencoba mencari tahu bagaimana/di mana Anda melakukannya - tetapi selalu saya menemukan itu adalah kesalahan saya sendiri - bukan kesalahan tsc . Itu hanya melakukan apa yang saya perintahkan.

Setiap kali ini mengenai saya, itu karena tipe. Saya mengimpor antarmuka atau sesuatu yang hidup dalam file yang mengimpor sesuatu yang lain yang hidup dalam file yang mengimpor sesuatu yang lain......sampai akhirnya saya mengimpor sesuatu yang hidup dalam file di luar rootDir dan sangat sering dalam sesuatu yang saya coba kecualikan secara eksplisit di konfigurasi saya.

HTH beberapa dari Anda sampai ke akar rasa sakit Anda. Tidak ada jumlah konfigurasi yang akan membuat Anda keluar darinya - Anda hanya perlu menjaga kontrol ketat terhadap struktur impor Anda.

@kpturner Kedengarannya sangat masuk akal, tetapi — proyek uji barebone tanpa impor lintas-folder akan menghasilkan perilaku yang dikeluhkan semua orang.

Betulkah? Yang belum pernah saya lihat :)

Folder yang dikecualikan selalu dikecualikan di semua proyek saya kecuali di mana keadaan yang saya singgung hadir.

Apakah ada contoh tulang telanjang di utas ini? Sulit untuk mengatakan dari ponsel saya.

Maaf, pengecualian bukanlah bagian dari situasi 'telanjang tulang' yang saya maksud. Saya hanya mencatat bahwa impor tampaknya tidak menjadi penyebab perilaku tersebut (meskipun akan lebih masuk akal jika itu masalahnya).

yaitu kompilasi sesuatu seperti ini akan menghasilkan kesalahan.

-src / src.ts <- no imports -test / test.ts -out -tsconfig.json {"rootDir": "src", "outDir": "out"}

Tetapi jika tsconfig.json terlihat seperti itu, saya mengharapkan TypeScript untuk mengkompilasi semua yang ada di direktori src dan semua yang ada di direktori test . Jika Anda hanya ingin mentranspile hanya hal-hal di src dan output ke direktori out maka tsconfig.json harus

{
    "compilerOptions": {
        "rootDir": "src",
        "outDir": "out"
    }
}

Maka itu akan menimbulkan kesalahan TS6059 karena Anda memiliki beberapa file di luar rootDir . Jadi, Anda harus mengecualikan itu:

{
    "compilerOptions": {
        "rootDir": "src",
        "outDir": "out"
    },
    "exclude": [
        "test"
    ]
}

yang, ketika ditranspilasikan, akan menghasilkan folder bernama out dengan subfolder src berisi src.js . Folder test diabaikan sepenuhnya. Inilah yang saya harapkan terjadi - bukan?

Er, memang, contoh saya tsconfig seharusnya menyertakan rootDir dan outDir bawah compilerOptions seperti yang Anda tunjukkan pada contoh pertama Anda. Anda juga benar bahwa ketika Anda mengecualikan test , test dan file-filenya dikecualikan. Awalnya, saya pikir Anda mengatakan bahwa (atau) penyebab kesalahan TS6059 adalah file di rootDir mengimpor sesuatu dari luar rootDir —meskipun saya pikir saya salah membaca Anda. Terlepas dari itu, saya setuju dengan orang lain di sini karena terkejut bahwa direktori di luar rootDir harus secara eksplisit dikecualikan seperti yang Anda jelaskan.

Tidak, saya (sebelumnya) mengatakan bahwa pohon referensi dapat menyebabkan hal-hal ditranspilasikan dalam daftar pengecualian Anda - sedikit berbeda.

Kesalahan TS6059 awalnya sedikit membingungkan - tetapi saya melihatnya sebagai TS mencoba membantu mencegah saya membuat kesalahan. Jika saya mengalami kesulitan mendefinisikan rootDir dan kemudian TypeScript plonk terbang di luar rootDir itu, maka TS secara efektif mengatakan "oi - Anda telah membuat TypeScript yang tidak dapat saya dapatkan - benarkah?"

Saya juga menjawab "tidak, itu tidak benar, saya kacau" dan memindahkan file ke rootDir
ATAU
Saya mengatakan "ya itu benar dan saya minta maaf saya tidak memberi tahu Anda" - dan kemudian saya menambahkannya ke daftar file yang dikecualikan.

Ini terlalu rumit. Saya memiliki monorepo dan sepertinya saya tidak dapat menemukan cara untuk mengkompilasi dengan benar setiap paket untuk dirinya sendiri, memancarkan struktur direktori yang benar, saat mengimpor paket lokal (dari monorepo yang sama) menggunakan opsi paths .

Entah struktur direktori di direktori keluaran berisi folder induk yang tidak diinginkan atau tsc mengeluh tentang file yang berada di luar direktori root.

Tidak bisa serumit ini kan?

Tidak peduli opsi mana dalam kombinasi apa pun yang saya gunakan, tsc tampaknya tidak dapat menangani monorepo dengan paths merujuk paket lokal di monorepo yang sama. Saya mencoba --build , --project , references , paths , extends , rootDir , rootDirs , include , exclude , baseUrl , outDir dalam semua jenis kombinasi dengan nilai yang berbeda dan pada akhirnya mengeluh tentang file yang tidak berada dalam rootDir atau kacau dengan memancarkan struktur direktori yang salah di dalam outDir .

Saya tidak akan menjelaskan apa yang saya miliki sebagai monorepo tetapi saya memiliki tiga proyek berbeda dalam repo yang sama - dan saya dapat mengubah masing-masing secara mandiri tanpa masalah atau gangguan dari yang lain. Setiap proyek memiliki tsconfig sendiri

Setelah beberapa lama mencoba dan mengutak-atik, saya bisa menjalankan monorepo dengan lerna dan TypeScript . Konfigurasi TypeScript menggunakan references dalam kombinasi dengan paths dan tidak tersedak lagi saat menggunakan rootDir .

rootDir digunakan untuk membangun struktur folder keluaran. semua file harus berada di bawah rootDir agar kompiler mengetahui di mana harus menulis output.

Bagaimana dengan file yang tidak memerlukan output apa pun? Memiliki file json di luar root:

const errors = require("../../../../errors.json");

Karena saya tidak dapat mengkompilasi versi ES6:

import * as errors from "../../../../errors.json";

Namun, dengan versi pertama, saya kehilangan keamanan tipe.

@mhegazy Masalah ini ditutup 3 tahun yang lalu. Namun tampaknya itu masih menjadi sumber kebingungan 3 tahun kemudian.

Bisakah Anda meninjau kembali status "Bekerja seperti yang Dimaksudkan" ini? Mengingat reaksi komunitas di utas ini, cukup aman untuk mengatakan bahwa komunitas tersebut tidak berperilaku seperti yang diharapkan komunitas tersebut . Baik itu masalah dokumentasi, mengganti nama opsi itu, mengubah perilakunya, atau menambahkan opsi baru, saya yakin sebenarnya ada item tindakan di pihak Anda yang harus ditentukan.

Saya dapat mengerti bahwa Anda memiliki prioritas yang jauh lebih tinggi daripada yang ini, tetapi menutup masalah ini tanpa ada tanda bahwa umpan balik yang diberikan di sini pernah dihargai tidak benar-benar menyampaikan citra yang sangat baik untuk TypeScript sejujurnya.

@ngryman Apa langkah selanjutnya yang kita miliki? rootDir memiliki definisi - ini adalah akar umum dari file sumber saya. Ketika sebuah file tidak berada di root yang sama, menurut definisi rootDir , itu adalah kesalahan. Definisi itu didokumentasikan. Saya tidak bisa berbuat apa-apa tentang fakta bahwa orang telah menemukan definisi mereka sendiri untuk rootDir dan kemudian terkejut.

Ini seperti pergi ke Starbucks dan mengatakan bahwa meminta latte tidak akan menghasilkan campuran espresso dan susu kukus. Itu tidak dapat ditindaklanjuti karena Anda berdebat dengan definisi . Jika Anda ingin minuman yang berbeda, pesanlah yang lain. Jika Starbucks tidak menawarkan jenis minuman yang Anda inginkan, buatlah saran tentang minuman apa yang seharusnya dan terbuat dari apa.

Seperti yang saya sebutkan di https://github.com/microsoft/TypeScript/issues/9858#issuecomment -370653478 , saya pikir solusi untuk masalah ini adalah pesan kesalahan yang lebih baik. Kembali ketika saya mengalaminya, dan akhirnya menemukan masalah GitHub ini, frustrasi terbesar saya berasal dari berapa banyak waktu yang saya buang untuk mencari tahu masalahnya, dan kemudian berpikir itu adalah bug kompiler, dan kemudian membuat kasus repro, dan kemudian menemukan bug duplikat yang mengatakan "bekerja sebagaimana dimaksud". Gagal cepat dengan pesan kesalahan yang jelas akan menyelamatkan saya dari semua itu.

Jika ada file sumber di luar rootDir maka itu berarti proyek TypeScript tidak dikonfigurasi dengan benar. Memberi pengguna pesan yang jelas yang menunjukkan ini bersama dengan panduan tentang cara memperbaikinya, saya pikir akan menyelesaikan masalah bagi banyak orang.

@RyanCavanaugh Terima kasih atas jawaban cepat Anda.

Jika saya pergi ke halaman ini: https://www.typescriptlang.org/docs/handbook/compiler-options.html. Saya membaca definisi berikut:

Menentukan direktori root dari file input. Hanya gunakan untuk mengontrol struktur direktori keluaran dengan --outDir.

Saya benar-benar memahami bahwa itu " hanya digunakan untuk mengontrol struktur direktori keluaran" dan hanya itu. "Satu- satunya penggunaan " penting di sini. Bagaimana saya bisa menebak bahwa itu bukan satu-satunya hal yang dilakukan kompiler dalam kenyataan, tetapi itu juga akan memancarkan kesalahan jika saya memiliki file TypeScript di luar direktori itu.

Mungkin saya kehilangan sesuatu, tetapi jika itu masalahnya, saya jauh dari satu-satunya. Jadi, jika Anda memiliki produk, dan sejumlah besar pengguna Anda tidak memahami produk Anda, hanya ada 2 jalur yang harus diambil: apakah Anda menganggap pengguna Anda bodoh, atau Anda gagal mengomunikasikan sesuatu dengan jelas. Saya harap Anda tidak condong ke arah yang pertama

Untuk mengakhiri contoh Starbuck Anda, tulis dengan baik "campuran expresso & susu kukus" di daftar bahan, jadi saya tahu apa itu latte, dan saya tidak perlu menebaknya.

Implikasi dari file di luar rootDir adalah bahwa TS akan menampilkan file di luar outDir , yang menurut saya merupakan perilaku yang jelas-jelas buruk.

Pesan kesalahan bisa lebih baik - saya ingin saran atau PR untuk itu.

Dokumen selalu bisa lebih baik - sekali lagi, akan menyukai ide-ide konkret di sana tentang cara mengomunikasikan berbagai hal dengan lebih jelas.

Menyindir bahwa saya menyebut orang bodoh bukanlah sesuatu yang saya suka lagi.

Implikasi dari file di luar rootDir adalah bahwa TS akan menampilkan file di luar outDir, yang menurut saya merupakan perilaku yang jelas-jelas buruk.

Saya masih sangat tidak jelas tentang mengapa kompiler tidak hanya "chroot" ke rootDir dan tidak mempertimbangkan file di luar direktori itu. Sebagai pengguna, mungkin kurang konteks tentang internal dan sejarah tsc , ini jelas bukan perilaku yang dapat diprediksi bagi saya.

Salah satu contoh yang dapat saya berikan dari kepala saya adalah Jest yang menawarkan opsi yang sama: https://jestjs.io/docs/en/configuration#rootdir -string. AFAIK Jest tidak mempertimbangkan file uji di luar rootDir . Saya mengharapkan perilaku yang sama di sini misalnya.

Dokumen selalu bisa lebih baik - sekali lagi, akan menyukai ide-ide konkret di sana tentang cara mengomunikasikan berbagai hal dengan lebih jelas.

Saya senang Anda mempertimbangkan perbaikan di sini. Saran dari @MicahZoltu bisa jadi menarik untuk dijelajahi.

Pada akhirnya, saya dapat menyatakan kembali bahwa menurut saya rootDir tidak dapat diprediksi (karenanya reaksi orang), tetapi seperti yang saya pahami, mengubah perilaku opsi itu bukanlah sesuatu yang perlu dipertimbangkan. Jadi sebagai kompromi, satu hal yang juga bisa saya usulkan adalah mengganti nama rootDir menjadi nama yang lebih bermakna, outBaseDir bisa menjadi kandidat. Tapi mungkin ada nama yang lebih baik.

Menyindir bahwa saya menyebut orang bodoh bukanlah sesuatu yang saya suka lagi.

Saya tidak menyindir apa pun dan saya minta maaf jika Anda mengambilnya seperti itu. Saya hanya menyatakan fakta yang sangat sederhana: ketika pengguna mengeluh tentang sesuatu yang mereka tidak mengerti, secara efektif hanya ada 2 jalur yang harus diambil. Saya menyimpulkan bahwa saya harap Anda tidak condong ke yang pertama. Fakta bahwa Anda mengasosiasikan diri Anda dengan salah satu jalan ini sejujurnya diserahkan kepada Anda.

Saya pikir saya telah mengatakan apa yang harus saya katakan, terutama dalam memberikan umpan balik yang jujur ​​tentang bagaimana utas ini ditangani. Jadi saya akan meninggalkan ruang bagi orang lain untuk mengusulkan solusi.

@ngryman Saya setuju bahwa definisi rootDir dan apa yang sebenarnya dilakukannya tampaknya tidak sejalan. Saat Anda membuat proyek ts baru (melalui tsc --init ) komentar di tsconfig.json untuk rootDir mirip dengan yang Anda kutip /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ . Jika saya menyediakan direktori file _input_, saya berharap satu-satunya yang akan dipertimbangkan untuk dikompilasi ada di direktori itu, menurut definisi input.

@RyanCavanaugh Mungkin masuk akal untuk melaporkan kesalahan seperti ini 4 tahun yang lalu ketika TypeScript hanya digunakan untuk dikompilasi ke dalam javascript. Tentu saja saya tidak ingin file hilang! Tetapi sekarang dengan popularitas eksekusi TypeScript, seperti ts-node , sepertinya tsc sedikit cemburu kepada saya.

Dan gagasan bahwa file TypeScript di luar rootDir menyiratkan konfigurasi proyek yang salah adalah salah. Saya tidak perlu tes unit saya, yang ditulis dalam TypeScript, untuk dikompilasi ke javascript. ts-node lebih cepat dan saya dapat menikmati semua manfaat dari TypeScript saat menulis tes.

Saya setuju dengan @CodySchrank . Saya setuju dengan kesalahan TS ketika beberapa file sumber di dalam rootDir mereferensikan/mengimpor file di luarnya - itulah yang diharapkan.

Namun, saya tidak dapat memahami TypeScript untuk dengan sendirinya melihat melalui file yang tidak terkait di luar rootDir dan membuat kesalahan sementara itu hanyalah file konfigurasi untuk alat yang berbeda, seperti lelucon atau apa pun. Maksudku, apa gunanya? Ini bahkan bukan bagian dari aplikasi saya dan tidak direferensikan/diimpor ke mana pun secara langsung, dan Tuhan, mengapa saya ingin mereka digabungkan ke dalam build yang dihasilkan di tempat pertama ...

Saya ingin tahu apa implikasi dari mengubah kesalahan ini menjadi peringatan. Setelah membaca sekilas kode, tampaknya mungkin, tetapi saya jelas bukan ahli dalam proses pembuatan tsc. Sepertinya media yang menyenangkan antara memberi tahu kami tentang masalah potensial tetapi juga membiarkan kami melewatinya jika kami mau.

Pengaturan src / test / out adalah skenario utama yang ditangani oleh referensi proyek

Ini memerlukan setidaknya konfigurasi proyek terpisah untuk setiap folder root (https://www.typescriptlang.org/docs/handbook/project-references.html). Setelah membaca instruksinya, saya pergi tanpa pemahaman yang baik tentang bagaimana menerapkan pola dan saya merasa seperti sedang diberikan palu ketika apa yang saya minta adalah pemukul lalat.

Tentu, mempertahankan modul tambahan sebagai sub-proyek terpisah dalam folder sumber saya lebih efisien, tetapi saya tidak mengkompilasi lodash di sini. Yang saya inginkan adalah memasukkan banyak file, seperti file uji dan benchmark, di bawah folder proyek umum untuk analisis statis, dan ketika tiba saatnya untuk mengkompilasi, hanya memancarkan satu direktori untuk digunakan oleh dunia luar. Ini tampaknya cukup mudah untuk ditentukan dan saya berjuang untuk melihat mengapa tidak hanya sulit bagi pengguna untuk melakukannya, tetapi tampaknya _verboten_ dari perspektif spesifikasi TS.

Yang ingin saya tekankan adalah bahwa satu-satunya alasan fitur ini tidak diizinkan adalah karena asumsi kompiler tentang niat korup dari pihak pengembang. Ketika pengembang menetapkan "outDir" ke ./src dan kompiler menemukan file TS di ./test , ia _could_ menganggap bahwa file ini tidak perlu dipancarkan (tentu saja dengan asumsi bahwa itu tidak direferensikan dari file apa pun di "outDir").

Tapi tidak. Diasumsikan bahwa pengembang _ingin_ untuk memancarkan file ini, dan karena ketidakmampuan atau kedengkian menentukan subdirektori yang tidak memuatnya. Dengan kata lain, kompiler memiliki kesempatan untuk mencocokkan instruksi pengembang dengan kasus penggunaan yang umum dan masuk akal, dan sebaliknya mencocokkannya dengan sesuatu yang tidak masuk akal dan menolak untuk melanjutkan.

Seperti berdiri, saya bahkan tidak melihat apa kasus penggunaan yang sah untuk "outDir" itu. Saya berasumsi itu untuk mendukung struktur proyek di mana tsconfig.json berada di tingkat atas bersama dengan file konfigurasi dan metadata lainnya, dan pemilik ingin folder yang dikompilasi hanya mewakili folder sumber yang bersarang di dalamnya. (Pastikan tidak ada file meta yang diakhiri dengan .ts : itu tidak masuk akal.)

Tampak bagi saya bahwa desain spesifikasinya bersifat antagonis terhadap pengguna. Ada referensi yang dibuat untuk memesan minuman di Starbucks dan marah ketika itu tidak seperti yang Anda harapkan, meskipun bahan-bahannya tercantum di menu. Sejauh ini memang tepat, tetapi saya akan menyamakan fitur ini lebih banyak dengan stan hot dog yang tidak menjual hot dog.

Tentu, pelanggan yang kesal seharusnya kembali dan melihat tanda besar yang dengan berani menyatakan bahwa stan hot dog tidak menjual hot dog. Tetapi ketika kebingungan menumpuk, mungkin ada peluang bagi pemilik kedai hot dog untuk merenungkan bagaimana mereka mengomunikasikan kemampuan produk mereka kepada pelanggan.

Hmm, mempertimbangkan ini lebih lanjut, saya bertanya-tanya apakah ada semacam invarian di pihak tim inti yang mendasari masalah ini:

Semua kode sumber harus dikompilasi. Jika tidak dikompilasi, itu bukan kode sumber.

Di userland, ada kebutuhan untuk melewati ini entah bagaimana. Saya tidak tahu apakah kita melakukan ini dengan memperluas definisi kode sumber yaitu. TypeScript, atau dengan membuat kategori kedua ("kode pendukung", "kode validasi", "kode periferal"...). Ini akan menjadi kode yang diharapkan beroperasi di bawah definisi tipe yang sama dengan sumbernya, dan yang harus berhasil divalidasi agar sumber dianggap benar, tetapi yang bukan merupakan bagian dari fungsi sebenarnya program sehubungan dengan antarmukanya.

Sebagai konsumen TypeScript, saya kurang menghargai kesulitan khusus dalam mengimplementasikan kategori semacam itu. Namun, sepertinya itu akan cocok dengan "outDir" : apa pun di dalam "outDir" adalah bagian dari sumbernya, apa pun di luarnya tetapi di dalam folder proyek adalah bagian dari kode pendukung. Hal utama yang membuat ini berguna/perlu adalah munculnya ts-node, yang berarti saya dapat mengeksekusi kode pendukung ini sebagai langkah terpisah, sepenuhnya independen dari kompilasi; dan tentu saja saya ingin dapat memanfaatkannya.

tidak secara implisit menyertakan file input apa pun yang disediakan untuk alat ini

Masalah ini disebabkan persis _karena_ pengguna secara implisit mencoba mengkompilasi file di luar rootDir . Anda pada dasarnya memberi tahu kompiler, "hanya kompilasi file di direktori ini" dan kemudian Anda melanjutkan ke file referensi di luar direktori itu. Kompiler bingung dan tidak tahu bagaimana melanjutkannya.


/project/source/index.ts

import '../external.ts'

/project/tsconfig.json

{
  "compilerOptions": {
    "rootDir": "./source"
  }
}

Dalam contoh ini, Anda memberi tahu kompiler "file sumber hanya ada di direktori 'sumber'". Kemudian salah satu file tersebut mereferensikan file yang _not_ di direktori sumber. TypeScript sekarang memiliki dua instruksi yang saling bertentangan, yang satu mengatakan untuk hanya mengkompilasi file di direktori sumber, yang lain mengatakan untuk mengkompilasi file di luar direktori sumber.

@MattiasMartens Anda secara implisit menggabungkan include dan rootDir . Jika Anda memiliki /src dan /test , jika include adalah src/* maka Anda tidak bisa mendapatkan kesalahan tentang hal-hal di /test kecuali sesuatu dari src salah mengimpor sesuatu dari test , yang seharusnya membuat Anda senang!

Tidaklah memusuhi pengguna atau antagonis untuk menyediakan mekanisme untuk menuliskan seperti apa impor yang salah dalam program Anda dan untuk mengeluarkan kesalahan ketika impor yang salah seperti itu terjadi. Sekali lagi saya pikir ini datang dari tempat kesalahpahaman apa bendera rata - mereka terutama opt-in cek penegakan hukum untuk membantu Anda memvalidasi bahwa program Anda dikonfigurasi dengan benar.


Bagaimanapun!

Mengingat definisi rootDir , ketika TypeScript melihat file di luar rootDir disediakan, ia memiliki beberapa opsi:

  • Keluarkan file di atas outDir (dengan asumsi ini bahkan mungkin!), yang bertentangan dengan instruksi pengguna tentang lokasi keluaran
  • Proses file tetapi jangan memancarkannya, yang tidak ada langkah pembuatan lainnya akan menghasilkan program yang tidak berfungsi
  • Mengeluarkan kesalahan karena proyek tampaknya salah dikonfigurasi

Saya sangat keberatan dengan gagasan bahwa memancarkan program yang tidak berfungsi harus menjadi default. Jika permintaan fitur di sini hanya untuk memperlakukan file .ts ditemukan di luar rootDir sebagai .d.ts , itu wajar, itu hanya hal yang terpisah dari arti rootDir sesuatu selain rootDir . Apa yang akan Anda sebut bendera seperti itu?

@MattiasMartens Anda secara implisit menggabungkan include dan rootDir . Jika Anda memiliki /src dan /test , jika include adalah src/* maka Anda tidak bisa mendapatkan kesalahan tentang hal-hal di /test kecuali sesuatu dari src salah mengimpor sesuatu dari test , yang seharusnya membuat Anda senang!

Itu benar. Saya bingung dengan include dan menemukan bahwa itu bekerja lebih baik daripada yang saya kira untuk kasus ini, termasuk dengan perkakas VSCode.

Saya masih ingin memiliki kode yang divalidasi pada kompilasi tetapi tidak dipancarkan pada kompilasi, yang merupakan sesuatu yang tidak dicakup oleh include . Tapi itu adalah permintaan terpisah yang tidak perlu dibahas di sini.

Saya pikir ini berasal dari tempat kesalahpahaman apa yang dimaksud dengan flag _mean_ - mereka terutama _opt-in enforcement checks_ untuk membantu Anda memvalidasi bahwa program Anda dikonfigurasi dengan benar.

Saya bingung dengan ini. Apakah Anda menganggap rootDir sebagai pemeriksaan penegakan keikutsertaan? Ini memengaruhi apa yang akhirnya dipancarkan sehingga jelas bukan _hanya_ pemeriksaan penegakan.

Beberapa tanda, seperti target , secara drastis mengubah apa yang akan dipancarkan -- itu bukan pemeriksaan penegakan tetapi instruksi kompiler. rootDir dibaca seperti, dan didokumentasikan seperti, instruksi kompiler.

Saya sangat keberatan dengan gagasan bahwa _emit a non-working program_ harus menjadi default.

Dari apa yang saya baca tentang utas ini sejauh ini tampaknya ada konsensus luas bahwa referensi dari file di dalam rootDir ke file di luar rootDir _harus menjadi kesalahan_. Aspek fitur yang saya dan orang lain merasa frustasi adalah tidak berhenti di situ, tetapi sebenarnya menimbulkan kesalahan jika menemukan file TS di folder proyek di luar rootDir apakah file di rootDir mengimpornya atau tidak.

Ini berulang: Saya menetapkan rootDir ke folder tempat kode sumber saya berada, kompiler memperhatikan kode TS lain dalam proyek yang tidak ada hubungannya dengan apa yang ada di rootDir , dan berhenti! Perilaku khusus ini tidak membantu saya memahami kode saya. Ini hanya mengganggu.

Memang benar bahwa dari perspektif definisi TypeScript dari rootDir , seperti yang diuraikan di utas ini, perilakunya sangat masuk akal, dan semua orang yang datang ke sini untuk mengungkapkan rasa frustrasi mereka tentang hal itu adalah kesalahan. Tapi itu tidak masuk akal dari definisi konvensional yang diharapkan dari direktori root. Saya katakan kepada Anda bahwa dalam hampir semua konteks di mana saya menyediakan direktori root, saya memberi tahu program di mana harus mulai melintasi struktur file, tidak menanyakan apakah itu benar-benar yakin tidak ada sesuatu yang lain di sistem file saya mungkin juga berminat.

Definisi bisa salah. Mereka dapat diubah. Untuk kompatibilitas mundur, tidak perlu mempertahankan definisi, hanya fungsionalitas.

Jika permintaan fitur di sini hanya untuk memperlakukan file .ts ditemukan di luar rootDir sebagai .d.ts

Saya... tidak berpikir saya menginginkannya, untuk alasan yang hampir sama dengan saya ingin kompiler membuat kesalahan ketika sesuatu di rootDir mengimpor kode dari luarnya. Saya pikir konten rootDir jika saya berikan harus dienkapsulasi dari kode di sekitarnya.

Saya pikir cara paling sederhana untuk menghindari perilaku yang saya dan orang lain tidak inginkan adalah secara implisit mengecualikan file di luar rootDir jika file dalam rootDir tidak merujuknya. Jika file dalam rootDir jangan merujuk kepada mereka, kesalahan harus dibuang, karena saat ini.

Setiap paragraf tampaknya bermuara pada " rootDir harus mengubah nilai default include ", yang merupakan hal yang masuk akal untuk disarankan jika kita menambahkan flag tersebut hari ini pada waktu yang sama, tetapi bukanlah perubahan besar yang bisa kita buat saat ini. Meskipun bisa dibilang membuat semua flag konfigurasi berinteraksi satu sama lain lebih meningkatkan beban kognitif daripada menguranginya.

Mungkin kita harus mengeluarkan kesalahan khusus ketika include tidak disetel secara eksplisit dan file yang disertakan berada di luar rootDir .

File "tests/foo.ts" berada di luar 'src' rootDir. Apakah Anda lupa menyetel pola "sertakan"?

Tercatat #33515

Saya mengalami masalah dengan ini, juga di https://github.com/microsoft/TypeScript/issues/31757#event -2480427393

Interaksi antara rootDir, sertakan dan kecualikan hanya dirancang dengan sangat aneh.

Saya selalu berpikir bahwa rootDir adalah folder yang mulai dilintasi oleh kompiler dan termasuk folder tambahan (misalnya folder vendor) yang mungkin dirujuk dari rootDir.

Definisi saat ini sangat aneh dan sangat tidak intuitif.

Ironisnya, yang membingungkan adalah mereka tidak berinteraksi: Pengaturan tidak mempengaruhi satu sama lain sama sekali. include 100% mengontrol apa yang ada dalam program dan rootDir 100% mengontrol komputasi tata letak outDir .

Hanya untuk menambahkan contoh lain dari masalah, ini adalah struktur folder saya:

tsconfig.json
package.json
src/index.ts

Saya punya di tsconfig saya:

"rootDir": "src",
"outDir": "lib",

Dan di "index.ts" saya (folder src)

import pkg from '../package.json'; // I read the package.json object

export class SomeClass {
  public version = pkg.version;
}

Saya _tahu_ bahwa, setelah build, file "index.js" akan berada di dalam folder "lib". Dan saya _tahu_ bahwa package.json akan naik 1 level.
Saya tidak berpikir bahwa TypeScript harus tahu lebih baik daripada saya tentang struktur folder saya dan merusak build. Seharusnya hanya mencatat peringatan tentang beberapa file di luar folder rootDir yang tidak termasuk dalam folder output.

@sebelga Saya mungkin akan menganggap itu bug - mengizinkan .json dari luar rootDir akan baik-baik saja karena TS tidak menyalinnya ke folder output

@sebelga Saya mungkin akan menganggap bahwa bug - mengizinkan .json dari luar rootDir akan baik-baik saja karena TS tidak menyalinnya ke folder output

Terima kasih tidak benar .. Kami memiliki beberapa aturan khusus untuk memancarkan file .json ... Jika file tersebut akan dipancarkan di lokasi yang sama pada dirinya sendiri maka hanya itu yang tidak dipancarkan. Dalam semua kasus itu dipancarkan (misalnya ketika --outDir ditentukan, itu akan dipancarkan ke folder itu)

@RyanCavanaugh Saya memiliki kasus penggunaan yang mirip dengan @sebelga di mana saya ingin console.log mengeluarkan nomor versi dari package.json saat runtime.

Jadi solusi saya adalah mengubah "rootDir": "." , lalu saya menyertakan ini

"include": [
    "src",
    "typings"
  ]

Dan karena file package.json disertakan dalam folder lib (buatan), yang berisi subfolder "src", saya menulis skrip bash yang berjalan tepat setelah pembuatan untuk membersihkan berbagai hal.

#!/bin/bash

rm lib/package.json
mv $(pwd)/lib/src/* $(pwd)/lib
rm -rf lib/src

Itu berhasil, tetapi bagi saya terasa cukup hacky.

@sebelga Apakah Anda memiliki .ts file dalam typings folder? Jika tidak, adalah sah untuk menetapkan rootDir ke src dan lewati skrip.

@sebelga Alih-alih const { version } require('../../package.json') atau import { version } from 'package.json') , sudahkah Anda mencoba melakukan sesuatu seperti ini:

import { sync as loadJsonFileSync } from 'load-json-file';

const { version } = loadJsonFileSync('../../package.json');

TypeScript tidak akan peduli jika itu berada di luar rootDir dengan cara ini.

https://github.com/sindresorhus/load-json-file

Jika Anda ingin menghindari hardcoding semua ../.. Anda dapat mencoba ini:
https://github.com/sindresorhus/read-pkg-up

@RyanCavanaugh saya tidak bisa mengaturnya ke "src" seperti yang disebutkan di atas. Saya mengimpor "package.json" di luar src kami ( import pkg from '../package.json'; ) dan tsc tidak mengizinkannya.

Terima kasih telah berbagi @dylang ini! Saya akan mencobanya.

Saya memberi tahu TypeScript bahwa semua sumber saya ada di folder tertentu (melalui rootDir)

Ini bukan maksud rootDir ! rootDir berarti "Gunakan folder ini sebagai basis relatif untuk menghitung jalur di outDir ". _File mana yang merupakan bagian dari kompilasi Anda_ adalah pertanyaan terpisah yang dijawab oleh files dan/atau include / exclude

@RyanCavanaugh Tapi itu adalah apa rootDir seharusnya berarti, dan ini adalah apa masalah ini adalah tentang.

Saya tidak pandai menjaga ketenangan saya ketika saya melihat masalah yang telah terbuka sejak 2016 yang mungkin bisa sangat diperbaiki tanpa memperkenalkan masalah baru untuk pengguna yang ada dengan memperkenalkan "compilerOption" baru untuk memberi tahu kompiler bahwa itu dapat mengabaikan kesalahan dalam kasus penggunaan yang diberikan.

Untuk ini, saya minta maaf. Saya tidak bisa menahannya, karena saya diandalkan untuk memberikan layanan yang baik, namun saya kadang-kadang menemukan utas masalah seperti ini. Mengapa begitu sulit bagi penulis TypeScript untuk mengimplementasikan satu flag konfigurasi sederhana?

Saya tidak berpikir itu karena pengembangnya malas, atau karena mereka tidak mau membantu. Saya tidak berpikir siapa pun di sini adalah orang jahat, kecuali saya sendiri.

Konflik inilah, perdebatan ini, yang telah berlangsung selama bertahun-tahun mengenai apa yang tampaknya menjadi definisi properti "rootDir". Dan apa yang harus dilakukan tentang masalah ini.

Orang-orang terlempar ke dalam perdebatan ini karena mereka percaya bahwa mereka benar. Ya, "rootDir" berfungsi sebagai direktori dasar untuk kode sumber. Ya, kesalahannya valid.

Namun, masalah mendasar masih berlanjut. Perkakas saya mengkompilasi kode dengan sempurna, namun IDE saya menampilkan kesalahan ini di layar saya. Ini adalah penyimpangan. Saya ingin garis merah itu hilang. File saya tidak memiliki kesalahan di dalamnya. Dan jika ya, saya harus fokus pada itu daripada terganggu oleh non-isu ini.

Yang saya inginkan hanyalah menekan pesan kesalahan ini. Saya pikir itulah yang kebanyakan dari kita inginkan. Saya tidak tahu apakah ada kasus lain di sini dan mungkin ada orang yang ingin angkat bicara tentang itu.

Bisakah kita bekerja sama dan menyelesaikan masalah ini? Itu akan membuat saya sangat senang melihat garis merah itu hilang ...

@nullquery Jika tsc berfungsi tetapi IDE Anda menunjukkan coretan merah Anda maka itu berarti IDE Anda tidak menggunakan versi atau konfigurasi kompiler yang sama dengan tsc .

@nullquery mengajukan bug yang menunjukkan cara mereproduksi masalah dan kami akan memperbaikinya atau memberi tahu Anda apa yang salah dengan konfigurasi proyek Anda

Melanjutkan dari solusi @sebelga , berikut adalah variasi yang cocok untuk masuk ke dalam skrip npm Anda

tsc --module commonjs --target ESNext --outDir ./edition-esnext --project tsconfig.json && test -d edition-esnext/source && ( mv edition-esnext/source edition-temp && rm -Rf edition-esnext && mv edition-temp edition-esnext ) || true

Contoh penggunaan di sini.

Batasan akan menerapkannya untuk Anda secara otomatis.

Solusinya adalah Referensi Proyek .

Untuk menggunakan ini, edit file "tsconfig.json" Anda dan tambahkan ini ke akhir file (di luar "compilerOptions"):

"references": [
    { "path": "../common" }
]

Ini akan memungkinkan Anda untuk mereferensikan file di folder "../common/" (dan semua sub-folder).


Kebingungan saya sebelumnya berasal dari fakta bahwa IntelliJ dan tugas gulp-typescript saya yang tidak ternoda memberi saya hasil yang berbeda meskipun menggunakan file "tsconfig.json" yang sama.

Ternyata untuk beberapa alasan, "gulp-typescript" mencoba pendekatan upaya terbaik untuk kompilasi.

Kesalahan dalam TypeScript (seperti let z: number = '' ) akan ditandai di IntelliJ tetapi "gulp-Typescript" mengompilasinya dengan baik.
Hanya kesalahan sintaks JavaScript (seperti let 1z = '' ) yang ditandai oleh "gulp-typescript".

Jadi, jika Anda adalah pengguna "gulp-typescript", Anda mungkin mengalami masalah seperti itu tergantung pada versi "gulp-typescript" dan konfigurasi Anda. (Saya menggunakan versi terbaru pada saat penulisan, tetapi saya berasumsi seseorang dari masa depan mungkin membaca ini. Saya harap waktunya lebih baik untuk Anda.)


Saya tahu penggunaan Referensi Proyek terkubur di suatu tempat di longsoran tanggapan ini, tetapi akan lebih baik jika ini didokumentasikan dengan lebih baik.

3 hasil teratas untuk "TS6059" di Google semuanya mengarah ke masalah GitHub. Akan jauh lebih jelas bagi saya jika ada halaman yang mendokumentasikan kesalahan umum ini dan solusinya.

@MicahZoltu Apakah ini sesuatu yang bisa diatasi? Haruskah saya membuat masalah baru, atau ini sesuatu yang akan berjalan lebih cepat jika dibahas secara internal antara kontributor utama?

(FWIW saya bukan bagian dari tim TypeScript)

Secara umum, saya menyarankan untuk tidak menggunakan path s kecuali Anda benar-benar harus melakukannya. Saya percaya tujuannya adalah untuk memungkinkan kompatibilitas dengan proyek JS lawas dengan struktur ketergantungan yang aneh, tetapi saya tidak percaya itu dimaksudkan untuk digunakan pada proyek baru apa pun, dan jika Anda membutuhkannya, Anda mungkin ingin mempertimbangkan untuk bermigrasi darinya ketika Anda memiliki kesempatan. Saya tidak menggunakannya secara pribadi jadi saya tidak dapat membantu dengan masalah yang mungkin Anda miliki dengannya, tetapi saya telah melihat banyak orang berjuang dengannya dan solusinya biasanya "berhenti menggunakannya".

Adapun gulp-typescript, sepertinya versi TSC yang digunakan oleh gulp-typescript berbeda dari versi TSC yang digunakan oleh IntelliJ. Ketika Anda melihat gejala seperti yang Anda gambarkan, biasanya itulah masalahnya (yang lainnya adalah mereka tidak menggunakan tsconfig.json ).

Versi yang digunakan oleh "gulp-typescript" harus identik; kedua versi diturunkan dari node_modules . Saya telah mencoba berbagai cara untuk menangkap kesalahan dan memodifikasi pengaturan yang terkait dengannya (termasuk bermain-main dengan berbagai "reporter" yang disediakan oleh "gulp-typescript" dan mencoba mengesampingkan pengaturan untuk menghasilkan lebih banyak kesalahan. Sepertinya tidak ada yang berhasil.

Ini baik-baik saja. Selama IntelliJ memberi saya kesalahan, saya senang menerima bahwa tugas Gulp akan mengabaikannya.


Saya bukan penggemar merombak metode saya demi metode pilihan minggu ini. Struktur proyek yang saya miliki masuk akal bagi saya. Itu membuat semuanya tetap terkandung namun memberi saya fleksibilitas untuk membagi hal-hal menjadi beberapa komponen.

Saya tidak percaya pada "mengizinkan kompatibilitas untuk alasan warisan," dan terutama ketika menyangkut referensi proyek. Ini _harus_ memungkinkan untuk mereferensikan file di luar rootDir atau Anda tidak akan memiliki kebebasan untuk menentukan struktur proyek dengan cara yang masuk akal bagi Anda & tim Anda.


Ketika saya pertama kali mulai bekerja dengan TypeScript, saya mengalami banyak masalah. Diantara mereka:

  • Untuk memasukkan file JavaScript, solusi masuk tampaknya adalah AMD pada saat itu. Situs web terdengar resmi dan ada banyak contoh online AMD dalam penggunaan produksi. Namun ternyata, Webpack adalah hal besar yang baru sehingga beberapa proyek tidak berfungsi di lingkungan AMD. Hal yang dipelajari: Tidak semua orang akan mengadopsi metode baru, jadi Anda selalu kacau.

  • Jalan dari TypeScript ke JavaScript yang diperkecil (dengan pemetaan sumber) tidak jelas bagi saya. Beberapa metode berbeda tersedia pada saat itu, tetapi tidak satupun dari metode tersebut yang tampaknya bekerja secara native dengan file "tsconfig.json" dan/atau IDE saya pada saat itu. Hal yang dipelajari: Jika Anda ingin sesuatu dilakukan dengan benar, Anda harus melakukannya sendiri; jangan mengandalkan orang lain untuk melakukan pekerjaan untuk Anda, tidak peduli seberapa baik niat mereka, tidak ada yang sempurna dan tidak ada yang bisa memprediksi ruang kerja _Anda_.

  • Ada satu hal khusus yang saya inginkan: cara untuk mengonversi konten file HTML ke kamus JavaScript untuk dimasukkan. Ini seharusnya menjadi satu-satunya batu sandungan saya, tetapi pada akhirnya, ini ternyata menjadi salah satu skrip yang lebih mudah untuk ditulis.

Saya akhirnya harus mengembangkan Gulpfile saya sendiri untuk menangani semuanya. Ini melakukan hal berikut:

  • Salin file JavaScript yang diperkecil untuk didistribusikan dari folder node_modules ke webroot saya. Kedengarannya sederhana, tetapi hampir setiap pustaka JavaScript yang saya coba sertakan memiliki tempat berbeda untuk menyimpan file JavaScript yang diperkecil. Tidak ada konfigurasi, tidak ada jalur yang jelas ke file. Saya akhirnya harus menulis skrip terpisah untuk setiap pustaka JavaScript yang ingin saya sertakan. Ini berfungsi, dengan asumsi lokasi tidak berubah di versi mendatang, tetapi jika ya, saya selalu dapat mengubah skrip salin.

  • Mengkompilasi TypeScript sesuai dengan file "tsconfig.json" lokal yang menghasilkan file terpisah di direktori output (menggunakan outDir ) sehingga saya dapat yakin bahwa TypeScript dikompilasi dengan cara yang sama di IDE saya seperti di Gulp (hahahahaha!), lalu gunakan plugin "rollup" untuk mengompresi file-file itu menjadi satu file JavaScript, lalu jalankan UglifyJS untuk mengecilkan file ini, sambil mempertahankan pemetaan sumber yang memetakan kembali ke file TypeScript asli.

  • (Tugas khusus) Menghasilkan file JavaScript yang berisi kamus bernama html_templates untuk setiap file HTML di root sumber TypeScript dan menempatkannya di folder webroot saya sebagai file JavaScript yang diperkecil.

Mungkin ada cara yang lebih elegan di luar sana, tetapi setelah melompat dari satu proyek sumber terbuka ke proyek sumber terbuka berikutnya, saya cukup banyak menyulap di antara solusi yang ditawarkan masing-masing dari mereka.

Pendekatan yang saya pilih berhasil, cukup sederhana untuk dipahami (terutama sekarang setelah saya mengerti bahwa "teguk-typescript" melakukan sesuatu yang berbeda) dan saya mungkin akan terus menggunakan ini selama bertahun-tahun yang akan datang.

Solusi terbaik adalah solusi yang Anda pahami sendiri. Meskipun ini tidak membantu siapa pun yang mencoba membantu saya (yang sangat saya hargai! bantuan yang saya maksud, bukan kebingungan) saya dapat berbicara dari pengalaman bahwa akan selalu ada sesuatu yang salah dengan solusi _any_ jadi lebih baik untuk tetap dengan sesuatu Anda memiliki diri sendiri daripada sesuatu yang dirancang, dikembangkan, dan diproduksi oleh tim multikultural dari berbagai keyakinan, orientasi seksual, dan identitas gender .


tl; dr tolong jangan rusak referensi proyek. Saya membutuhkan itu agar perkakas saya berfungsi. Terima kasih

Saya menyerah mengatur pengaturan TS multi-proyek dengan benar dan hanya melakukan tsc -w di setiap proyek dan npm link , dan kemudian Anda dapat mengabaikan semua kerumitan tsconfig multi-proyek dan hanya merujuk ke yang lain proyek seperti itu dependensi node.js biasa di node_modules .

Tetapi hari ini dalam satu proyek saya mengubah target dari es5 menjadi es6 dan tidak dapat dikompilasi lagi karena File '.../lib.ts' is not under 'rootDir' .

Struktur berkas:

/app
 - tsconfig.json // rootDir = "."
 - app.ts (

/app/node_modules/lib
 - tsconfig.json // rootDir = "."
 - lib.ts
 - lib.js
 - lib.d.ts

Mengapa tsc di /app peduli dengan file /app/node_modules/lib/lib.ts ? Seharusnya tidak menggunakan file itu sama sekali. Ada yang dikompilasi /app/node_modules/lib/lib.js dan /app/node_modules/lib/lib.d.ts .

Jika /app/node_modules/lib/lib.ts dihapus - kejutan - itu dikompilasi dengan baik.

@alexeypetrushin Anda dapat melihat beberapa proyek saya. Tampaknya bekerja dengan baik. misalnya:

import * as pkg from '../package.json';

TIDAK. Dan tidak ada cara untuk mematikan kesalahan ini yang dapat saya temukan.

@SephReed : Saya telah menghabiskan 200 poin rep di StackOverflow dan seseorang menyumbangkan solusi yang sangat sederhana ini untuk mengimpor ../package.json . Yang harus Anda lakukan adalah menempatkan file typings.d.ts di direktori yang sama dengan package.json , dengan konten ini:

declare module '*.json';

Saya tidak tahu bagaimana ini bekerja, tapi jujur, saya tidak peduli. Pada tahap itu, TS melakukan forking untuk dirinya sendiri, bukan untuk saya.

Saya terkejut ini adalah perdebatan yang begitu panas. Tapi saya mengerti alasannya. Bagi saya, tentu saja saya memiliki folder sumber, tetapi saya juga telah membuat skrip di luar folder itu yang tidak dimaksudkan untuk dikompilasi tetapi pasti menyertakan dukungan jenis, karena jujur ​​​​saja IntelliSense terbaik Anda adalah TypeScript.

repo/
⊢ config/  << provide TS support, but don't build this directory
  ⨽ webpack.config.ts 
⊢ scripts/  << provide TS support, but don't build this directory
  ⨽ release.ts
⊢ src/        << build this directory
  ⨽ example.ts
⨽ tsconfig.json

Jadi saya menggunakan "rootDir": "src" untuk memastikan file diarahkan ke dist dan bukan dist/src . Tapi tentu saja, TypeScript suka mengeluh tentang pengaturan ini, tetapi karena saya menggunakan Webpack, itu tidak membuat saya salah.

Saya akhirnya mendapatkan apa arti sebenarnya dari bendera ini tanpa beberapa komentar yang tidak membuatnya lebih jelas. Hanya bersorak dengan ini.

Opsi yang menetapkan folder dan file untuk tsc untuk diperhitungkan ke dalam kepatuhan: "file", "include", "exclude".

Lalu untuk apa Anda menggunakan "rootDir"?
rootDir adalah akar dari struktur direktori (hierarki) ke file sumber Anda, yang digunakan tsc untuk memancarkan struktur direktori yang sama mulai dari direktori tsconfig.json atau "outDir" jika ditentukan. Jadi ini bukan jalur yang digunakan tsc sebagai jalur dasar untuk "outDir". "outDir" hanyalah root yang tsc memancarkan file output.
Sebagai contoh, katakanlah proyek Java Anda memiliki struktur direktori ini.

- src
  - main
    - java
    - resources
      - static
        - js
        - ts
          test.ts

Ketika Anda mengatur "include" dan "rootDir" seperti di bawah ini, tsc akan menghasilkan output sebagai:

"include": "src/main/resources/static/ts" *
"rootDir": "." *

- src
  - main
    - java
    - resources
      - static
        - js
        - ts
          test.js *
          test.ts

Ketika Anda juga mengatur "outDir" seperti di bawah ini, tsc akan menghasilkan output sebagai:

"include": "src/main/resources/static/ts"
"rootDir": "."
"outDir": "build" *

- build
  - src
    - main
      - resources
        - static
          - ts
            test.js *
- src
  - main
    - java
    - resources
      - static
        - js
        - ts
          test.ts

Mungkin Anda ingin memiliki ini dengan mengatur opsi "rootDir" dan mengubah opsi "outDir" seperti di bawah ini.

"include": "src/main/resources/static/ts"
"rootDir": "src/main/resources/static/ts" *
"outDir": "src/main/resources/static/js" *

- src
  - main
    - java
    - resources
      - static
        - js
          test.js *
        - ts
          test.ts

Jadi ketika Anda telah menetapkan opsi "rootDir" yang tidak mencakup cakupan file kecuali dari opsi "kecualikan", tsc gagal membangun karena tidak masuk akal dengan tujuan opsi "rootDir".

Ya itu benar-benar praktik penamaan yang buruk. Seharusnya hanya "rootOfStructureOfInputs" atau semacamnya. Dan juga, "outDir" seharusnya hanya "rootOfOutputs".

Apa yang Anda lihat di SS bukanlah masalah WebStorm - ini berasal dari TS DevServer.
Impor yang direkomendasikan kedua adalah omong kosong. Ini mengambil dari folder sumber "komunikasi". Saya tidak tahu siapa yang seharusnya menginginkan itu. Mengkompilasi file dengan impor semacam itu menghasilkan banyak masalah.

Saya juga mencoba:

"exclude": ["lib", "node_modules",
        "..", "../..", "../../..", "../../../..", "../../../../..", "../../../../../.."
    ]

Tidak menyelesaikan masalah juga

Bildschirmfoto 2020-07-22 um 10 08 28

@mhegazy Anda memberi label masalah ini dengan "Bekerja seperti yang Dimaksudkan" tapi itu tidak benar. Seperti yang Anda lihat di tangkapan layar saya, tsc-server menyediakan file di luar rootDir saya (dalam hal ini mobiservice/src) sebagai saran impor. Bagi saya ini terlihat seperti bug ...

Apakah halaman ini membantu?
0 / 5 - 0 peringkat

Masalah terkait

MartynasZilinskas picture MartynasZilinskas  ·  3Komentar

wmaurer picture wmaurer  ·  3Komentar

remojansen picture remojansen  ·  3Komentar

weswigham picture weswigham  ·  3Komentar

jbondc picture jbondc  ·  3Komentar