Rollup-plugin-typescript2: Mengetik file yang dihasilkan di folder yang salah di dalam objek sebagai `input` rollup

Dibuat pada 5 Feb 2019  ·  33Komentar  ·  Sumber: ezolenko/rollup-plugin-typescript2

Apa yang terjadi dan mengapa itu salah

Mungkin ini adalah kesalahan konfigurasi di pihak saya, tetapi sepertinya ini bug. Saat Anda menggunakan object sebagai properti input untuk konfigurasi rollup, file pengetikan untuk file input dibuat di folder root repo (folder yang sama dengan file konfigurasi rollup) dan bukan direktori keluaran target (di sini, ./dist ) bersama dengan file JS yang dibundel.

Versi

  • naskah: 3.2.4
  • rollup: 1.1.2
  • rollup-plugin-typescript2: 0.19.2

rollup.config.js

{
    ...
    input: {
        Lib1: './src/Lib1.tsx',
        Lib2: './src/Lib2.tsx'
    },
    output: {
        dir: './dist',
        format: 'cjs',
        sourcemap: true,
        entryFileNames: '[name].js'
    }
}

tsconfig.json

{
  ...
  "compilerOptions": {
    "outDir": "./dist"
  },
}

Hasil:

// These files are created
./Lib1.d.ts
./Lib2.d.ts

// instead of (expected):
./dist/Lib1.d.ts
./dist/Lib2.d.ts

Anehnya, jika Anda memasukkan entryFileNames: 'dist/[name].js' itu membuat subfolder berlebihan yang disebut dist dalam folder dist dan membuatnya di sana.

bug more info needed

Komentar yang paling membantu

Ya. yang tampaknya menjadi satu-satunya cara kecuali Anda membiarkan tsc melakukan bundling ujung ke ujung.
Plugin rollup ini tampaknya secara efektif meminta tsc untuk melakukan dua tugas berbeda:

  1. "Ketik-periksa dan konversikan semua modul individual ini ke JavaScript" dan biarkan saya (yaitu Rollup) melakukan bundling dan menulis ke disk.
  2. "Buat semua deklarasi untuk folder proyek TS ini dan buang di sana."

Hasil 1 dan 2 tidak, dan tidak cocok saat Anda menggunakan "peta masukan" dan pemecahan kode, dll. – AFAICT.

...kecuali jika Anda membuat plugin rollup lebih terlibat dalam proses pembuatan deklarasi tipe.

Semua 33 komentar

Opsi plugin useTsconfigDeclarationDir adalah solusi untuk saat ini.

Ini mungkin diperbaiki oleh # 142, dirilis di 0.20.0

Hai @ezolenkom & @jakearchibald , sebenarnya tidak beruntung.

Saat menambahkan opsi useTsconfigDeclarationDir di plugin rollup saya, file deklarasi tidak lagi dibuat sama sekali. Dan memperbarui ke 0.20.1 tidak membuat perbedaan, sayangnya.

@benkeen saat menggunakan opsi plugin useTsconfigDeclarationDir: true Anda juga harus memiliki nilai declarationDir di tsconfig.json

memiliki masalah serupa, tata letak proyek saya seperti ini:

export default [ 
  {
    input: 'src/subFolder1/one.ts,
    output: [
                    {
                      file: 'dist/one.js'
                      .....                      
                     }
    ],
    plugins: [
           typescript({
                typescript: require('typescript'),
            }),
    ]
  },
      input: 'src/subFolder2/two.ts,
      output: [
                    {
                      file: 'dist/two.js'
                      .....                      
                     }
    ],
     ...
  },
]

Sebagai output saya punya:

  |---subFolder1
  |          |--------one.d.ts
  |
  |---subFolder2
  |          |---------two.d.ts
  |-----one.js
  |-----two.js

Bekerja untuk saya di 0.20.1 dengan useTsconfigDeclarationDir: false -- file d.ts masuk ke folder yang ditentukan dalam output.[].dir . @benkeen bisa coba lagi?

@AntonPilyak yang dirancang -- jika d.ts masuk ke satu folder tanpa sub jalur, maka jika Anda memiliki subFolder1/one.ts dan subFolder2/one.ts , salah satunya akan menimpa yang lain.

@ezolenko : fitur ini, saya pikir, menciptakan lebih banyak ketidaknyamanan daripada memecahkan masalah nyata (karena sulit untuk mempertahankan semua struktur direktori itu). Saya harus membuat skrip yang menyalin semua deklarasi tipe ini ke root bundel, dan menambahkan direktori ke .npmignore untuk membuat bundel yang mudah disertakan. Saya menyarankan Anda untuk membuat direktori tambahan ini HANYA untuk jenis file dengan nama yang sama. Dan gunakan direktori yang ditentukan di bagian 'output' dari rollup.config.json untuk sisanya.

@AntonPilyak Anda mungkin dapat menggunakan opsi useTsconfigDeclarationDir: true , atur declarationDir di tsconfig, ini seharusnya membiarkan TypeScript itu sendiri menangani jalur keluaran pengetikan.

Memutuskan apakah subdirektori harus digunakan berdasarkan keunikan jalur akan menjadi mimpi buruk dalam proyek yang sedang berkembang, tiba-tiba pengetikan Anda akan pindah ke subfolder hanya karena Anda menambahkan file baru dengan nama yang sama di folder yang berbeda.

Biasanya jika Anda ingin pengetikan yang cantik, Anda tetap ingin menggabungkannya menjadi satu file (ada modul npm saya terus lupa namanya untuk itu)

Saya menggunakan versi 0.22.0 dan saya memiliki masalah yang hampir sama dengan @AntonPilyak

{
    ...
    input: {
        foo: 'src/lorem/foo.ts',
        bar: 'src/ipsum/bar.ts'
    },
    output: {
        dir: 'dist',
        format: 'cjs',
        sourcemap: true,
    }
}

Dan saya mengeluarkan ini:

dist/
    lorem/
        foo.d.ts
    ipsum/
        bar.d.ts
    foo.js
    foo.js.map
    bar.js
    bar.js.map

Jelas, saya ingin file *.d.ts berada di samping file *.js dan *.js.map .

Saya sudah mencoba mengutak-atik useTsconfigDeclarationDir dan declarationDir tidak berhasil.

File definisi selalu berakhir di masing-masing sub-folder lorem dan ipsum , dan tidak pernah dalam daftar datar.

Selain itu sepertinya itu membuat file deklarasi untuk setiap file .ts yang ditemukannya, bukan hanya titik masuk.

dist/
    lorem/
        foo.d.ts
    ipsum/
        utils/
            bar-helper.d.ts
        bar.d.ts
     some_other_ts_file/
         not_imported_by/
             neither_foo_nor_bar/
                  wat.d.ts
    foo.js
    foo.js.map
    bar.js
    bar.js.map

Saya sudah mencoba melingkupi options.tsconfigOverride.input hanya ke titik masuk, tetapi itu tampaknya tidak berpengaruh apa pun. Sebenarnya saya bahkan tidak yakin apakah tsconfigOverride.input berfungsi sama sekali.

Ini semua agak membingungkan.

...

Maksud saya, cukup adil jika perlu membuat file deklarasi untuk utils/bar-helper.ts tetapi setidaknya wat.ts harus dikeluarkan dari semuanya.

Ya, itu menghasilkan deklarasi untuk semua file yang ditemukan oleh tsconfig, jika Anda tidak ingin file tertentu disentuh, pastikan itu dikecualikan atau tidak termasuk dalam tsconfig. Untuk melihat daftar file yang ditemukan oleh TypeScript, jalankan plugin dengan verbositas 3 dan cari entri "parsing tsconfig".

Untuk jalur definisi, di mana dalam contoh Anda Anda ingin definisi untuk 'src/ipsum/foo.ts' duduk?

Karena ini adalah definisi untuk dist/foo.js saya berasumsi itu akan berakhir di sebelahnya - seperti file peta sumber - yaitu di dist/foo.d.ts .

Akankah TypeScript tahu untuk memasangkan dist/foo.js dan dist/lorem/foo.d.ts ?

Skenario lengkap di mana ini rusak adalah:
src/dir1/foo.ts
src/dir2/foo.ts

dir1/foo.ts us ditetapkan sebagai input rollup dan mengimpor dir2/foo.ts. Rollup akan membuat bundel dist/foo.js yang akan berisi bagian yang relevan dari kedua file sumber, tetapi TypeScript perlu membuat 2 file definisi tipe dengan nama yang sama di suatu tempat.

Solusi mudah adalah dengan menggunakan subfolder, mirroring tata letak sumber. Saya pikir itu juga yang dilakukan tsc , kecuali jika Anda memintanya untuk menggabungkan definisi tipe (rpt2 tidak mendukung penggabungan definisi).

Dan ya, TypeScript akan tahu di mana menemukan definisi tipe. Jadi selain sedikit berantakan, ini seharusnya tidak menjadi masalah. Jika Anda ingin menerapkan paket dengan tipe pada npm, setel "types" di package.json ke file d.ts untuk titik masuk Anda. TypeScript akan menemukan sesuatu dari sana.

Ah, jadi plugin ini tidak benar-benar mengelola bagian apa pun dari proses pembuatan deklarasi. Itu hanya menjalankan tsc untuk melakukan hal itu, tidak relevan dengan proses Rollup?

Namun, jika saya hanya mengekspos/menerbitkan beberapa modul, mengapa saya ingin TypeScript menghasilkan file *.d.ts untuk setiap file ts yang ditemuinya? Apakah tidak ada cara untuk membatasinya hanya pada titik masuk?

Masalahnya, saya mengekspor satu set modul mandiri ( import tool1 from 'myTools/tool1'; dll.) jadi tidak ada titik masuk tunggal untuk digunakan dalam pkg.types . Setiap file definisi harus berada di sebelah mitra *.js agar VSCode dapat mengambilnya.

Lebih buruk lagi, jika saya punya

{
    ...
    input: {
        fooscript: 'src/foo/index.ts',
        barscript: 'src/bar/index.ts'
    },
    output: {
        dir: 'dist',
        format: 'cjs',
        sourcemap: true,
    }
}

Saya mendapat:

dist/
    foo/
        index.d.ts
    bar/
        index.d.ts
    fooscript.js
    fooscript.js.map
    barscript.js
    barscript.js.map

Dan sekarang tidak ada cara bagi TypeScript untuk memasangkan dist/fooscript.js dan dist/foo/index.d.ts .

...

Apakah tidak mungkin plugin Anda dapat memberi TypeScript jalur tujuan/output untuk setiap file bundel JavaScript? Tampaknya tsc menerima nama file entri asli dan memegangnya erat-erat saat membuat deklarasi.
...atau untuk setiap file input, cari file *.d.ts sesuai dan pindahkan+ganti namanya ke tujuan peta file input. (Anda mungkin memperhatikan saya berbicara keluar dari pantat saya di sini, jadi ... ;-)

Ini adalah sesuatu yang harus saya coba secara manual setelah Rollup selesai - tetapi akan jauh lebih baik jika plugin menanganinya secara otomatis.

Tidak, plugin menggunakan LanguageServices (biasanya menggunakan IDE API TypeScript yang sama), jadi saya memiliki kendali atas apa yang harus ditulis dan di mana.

Untuk menulis satu definisi tipe per input rollup, kita perlu menggabungkan definisi untuk semua impor untuk input itu. Rollup mungkin melihat satu file input ts, tetapi itu bisa mengimpor dan menggabungkan sejumlah file sumber saat membangunnya, jenis kebutuhan itu juga dihasilkan.

Saat ini saya keliru dalam menghasilkan definisi untuk semua yang ditemukan TypeScript ketika melihat file tsconfig. Jika saya menghasilkan tipe hanya untuk modul yang ditranspilasikan, hanya file yang diketik akan diabaikan.

Saya mungkin harus mengunjungi kembali bagian itu, API berubah cukup besar sejak bagian itu selesai ...

Saya harus melihat bagaimana membuat contoh Anda berfungsi. Mungkin memerlukan dukungan yang lebih baik untuk beberapa bundel dalam satu konfigurasi rollup.

Bagaimana Anda mengkonsumsi paket itu setelah membangunnya? Ini bukan sesuatu yang dapat Anda publikasikan di npm dan impor berdasarkan nama paket...

Saya membuat koleksi utilitas mandiri. Root-folder dari paket yang diterbitkan/diinstal berisi semua file modul yang dibangun dalam daftar datar.

(Saya menulisnya dalam TS/ES6 dalam struktur folder bersarang, dengan file uji yang dicampur, dan mengandalkan Rollup untuk mengonversinya menjadi daftar datar file CJS dengan campuran pemecahan kode dan inlining yang efisien untuk semua kode bersama.)

Saya kemudian menggunakan alat-alat ini dengan mengimpornya dengan nama file - seperti:

import tool1 from 'myTools/tool1';
import tool2 from 'myTools/tool2';

Idenya adalah bahwa dengan tidak memiliki satu titik masuk untuk keseluruhan toolkit (tidak ada entri pkg.main atau pkg.module ), saya dapat dengan bebas menambahkan alat yang jarang digunakan, dan bahkan eksperimental. tanpa menambah bobot/kembung untuk konsumen hilir (yang mungkin tidak memiliki pengocokan pohon yang efisien).

...Saya telah bermain-main dengan tsc pada baris perintah sekarang, dan saya rasa sekarang saya melihat batasan yang Anda hadapi.

Namun, saya perhatikan bahwa jika Anda menjalankan tsc dan mengatur format modul/output ke "amd" atau "system" , itu menghasilkan satu file *.d.ts dengan daftar semua yang rapi blok declare module "..." sebaris.

Saya ingin tahu apakah perilaku ini dapat dieksploitasi entah bagaimana - melalui file rename/move dan unwrapping/write ulang deklarasi modul (utama) terakhir?


Catatan tambahan: Saya juga memperhatikan bahwa tsc tampaknya tidak berusaha keras untuk menggoyahkan file deklarasi itu. Dalam satu kasus saya melihat modul utama (titik masuk) yang mengekspor tanda tangan fungsi tunggal, sangat sederhana, namun file deklarasi memperlihatkan blok deklarasi untuk semua modul pribadi yang digunakan "di belakang layar". Lucu. :-)

Halo lagi.
Untuk saat ini, saya menetapkan declarationDir untuk tsc untuk membuang semua *.d.ts ke dalam, dan kemudian menjalankan skrip mandiri yang mengimpor entri-file-ke- yang sama output-file objek saat saya diumpankan ke Rollup, dan itu menghasilkan file deklarasi tingkat bundel-tujuan yang hanya export * from file deklarasi sebenarnya.

Pada dasarnya, saya menghasilkan dist/fooscript.d.ts yang hanya berisi:

export *  from './__types/foo/index';

Ini adalah peretasan mandiri yang jelek, tetapi memberikan hasil yang benar dan dapat diprediksi.

Saya ingin tahu apakah rollup-plugin-typescript2 dapat melakukan hal serupa?

Itu akan berhasil, ya.

Saya punya beberapa ide (ketika saya membahasnya), misalnya menghasilkan <bundlename>.d.ts yang memiliki banyak /// <reference types=""/> untuk setiap d.ts yang terlibat.

Pertama saya mungkin harus memperbaiki bug terkait yang menghasilkan terlalu banyak deklarasi tipe dan membatasi itu hanya untuk file root dan apa pun yang sebenarnya diimpor.

Beberapa pemikiran:

IMO, satu-satunya bagian yang benar-benar jelek dari peretasan saya adalah kenyataan bahwa itu berbeda dari proses Rollup. Perantara *.d.ts sebenarnya adalah cara yang cukup rapi dan idiomatis untuk menjembatani antara bundel yang dihasilkan Rollup dan definisi tsc .

Karena file deklarasi yang dihasilkan tsc saling merujuk satu sama lain melalui jalur relatif, struktur file/folder itu mungkin sebaiknya dibiarkan sendiri – jangan sampai Anda akhirnya mengimplementasikan kembali bagian dari fungsionalitas Rollup, untuk sintaks bahasa kustom.

Dan jika rollup-plugin-typescript2 menetapkan sesuatu seperti output.dir + '__types' sebagai default declarationDir , maka kekacauan apa pun yang disebabkan oleh keinginan berlebihan tsc akan disingkirkan dengan rapi. pemandangan di dalam folder dengan nama yang jelas. Dengan begitu file definisi asing menjadi perhatian IMO yang sangat kecil.


FWIW, inilah inti dari skrip saya:

const { makeInputMap, getEntrypoints, distFolder, srcFolder } = require('./buildHelpers');
const { writeFileSync } = require('fs');
const { relative } = require('path');

const srcPrefixRe = new RegExp('^' + srcFolder + '/');
const tsExtRe = /\.tsx?$/;

const declDirRelative = './' + relative(
  distFolder,
  require('../tsconfig.json').compilerOptions.declarationDir
);

const tsEntrypoints = getEntrypoints()
  .filter((fileName) => tsExtRe.test(fileName));

Object.entries(makeInputMap(tsEntrypoints))
  .forEach(([moduleName, sourcePath]) => {
    const tscDeclFile = sourcePath
      .replace(srcPrefixRe, declDirRelative + '/')
      .replace(tsExtRe, '');
    const outFile = distFolder + '/' + moduleName + '.d.ts';
    writeFileSync(
      outFile,
      [
        'export * from "' + tscDeclFile + '";',
        'import x from "' + tscDeclFile + '";',
        'export default x;',
        '',
      ].join('\n')
    );
  });

console.info('Created local declaration files for TypeScripted entrypoints.');

Saya memperbarui contoh di atas, karena tampaknya ekspor default harus diekspor kembali secara eksplisit.

Pengujian awal menunjukkan bahwa mengekspor ulang default secara membabi buta dari file deklarasi yang tidak memiliki ekspor default tidak berbahaya, dan diabaikan secara diam-diam. (Setidaknya oleh VSCode.)

Hai, haruskah masalah ini diselesaikan di v0.23.0 ?

(... bertanya-tanya apakah saya harus mencoba dan memperbarui proyek saya untuk menghapus semua faffing khusus)

0.23 tidak akan menghasilkan deklarasi untuk semua yang terlihat, tetapi masih akan menghasilkan deklarasi yang sebenarnya Anda impor di subfolder relatifnya. Anda mungkin dapat memperbarui dan memiliki tipe yang lebih ringan, tetapi belum ada yang menghasilkan deklarasi tipe root.

Skrip build solusi kustom saya (lihat di atas) secara bertahap merayap ke semakin banyak proyek saya. o_O

FYI: Pengembangan paket resmi @rollup/plugin-typescript telah dilanjutkan, dan sekarang fitur pemeriksaan tipe dan keluaran file deklarasi, jadi saya pribadi beralih untuk menggunakannya.
Namun, batasannya hampir sama.

@maranomynet Apakah Anda masih mengandalkan skrip Anda untuk memindahkan file deklarasi setelah rollup melakukan hal itu? Saya tidak memiliki banyak keberuntungan beralih sendiri.

Ya. yang tampaknya menjadi satu-satunya cara kecuali Anda membiarkan tsc melakukan bundling ujung ke ujung.
Plugin rollup ini tampaknya secara efektif meminta tsc untuk melakukan dua tugas berbeda:

  1. "Ketik-periksa dan konversikan semua modul individual ini ke JavaScript" dan biarkan saya (yaitu Rollup) melakukan bundling dan menulis ke disk.
  2. "Buat semua deklarasi untuk folder proyek TS ini dan buang di sana."

Hasil 1 dan 2 tidak, dan tidak cocok saat Anda menggunakan "peta masukan" dan pemecahan kode, dll. – AFAICT.

...kecuali jika Anda membuat plugin rollup lebih terlibat dalam proses pembuatan deklarasi tipe.

Ah ya itu kira-kira yang saya pikirkan, terima kasih! Memberi Anda 👍 untuk jawaban Anda yang bermanfaat, dan adalah untuk perasaan saya tentang hal itu.

Adakah keberuntungan dengan ini?

Untuk setiap jiwa yang berjuang di luar sana yang memiliki struktur folder src yang sama dengan @maranomynet dan saya.

Saya menemukan perbaikan cepat untuk itu, mungkin cara lain yang jelek tetapi berhasil untuk saya.

Saya menggunakan rollup-plugin/typescript2 jadi saya akan menggunakan konfigurasinya dalam jawaban ini:
Tentukan deklarasiDir Anda sendiri di tsconfig.json Anda sehingga proyek Anda dapat membuang semua file *.d.ts di jalurnya sendiri di dist yang dibundel. Dan pastikan untuk mengatur useTsConfigDeclarationDir menjadi true di plugin TypeScript Anda di file konfigurasi rollup.
Juga, di mana Anda menentukan jalur keluaran untuk bundel komponen individual Anda di rollup.config.js Anda (dan package.json), ubah jalur tersebut menjadi sama dengan 'declarationDir' + 'bagaimana rute komponen src Anda'. Jadi jika komponen Anda di src seperti:

src/beranda/foo.tsx

Dan deklarasiDir Anda adalah:

dist/MyDeclarationDir

Jadi jalur keluaran Anda harus seperti:

dist/MyDeclarationDir/homepage/foo.js

Dengan cara ini, rollup akan menyertakan tipe Anda di direktori yang sama dengan komponen main.js Anda dan proyek konsumen TS Anda akan mengambil pengetikan.

Jadi bundel akan terlihat seperti:

dist/

    declarationDirPath/
                  component1/
                        foo.js/
                              foo.js
                              foo.map.js
                        foo.d.ts
                   component2/
                        bar.js/
                               bar.js
                               bar.map.js
                        bar.d.ts
Apakah halaman ini membantu?
0 / 5 - 0 peringkat